mysqladm/client/commands/
show_user.rs

1use anyhow::Context;
2use clap::Parser;
3use futures_util::SinkExt;
4use tokio_stream::StreamExt;
5
6use crate::{
7    client::commands::erroneous_server_response,
8    core::{
9        protocol::{ClientToServerMessageStream, Request, Response},
10        types::MySQLUser,
11    },
12};
13
14#[derive(Parser, Debug, Clone)]
15pub struct ShowUserArgs {
16    #[arg(num_args = 0..)]
17    username: Vec<MySQLUser>,
18
19    /// Print the information as JSON
20    #[arg(short, long)]
21    json: bool,
22}
23
24pub async fn show_users(
25    args: ShowUserArgs,
26    mut server_connection: ClientToServerMessageStream,
27) -> anyhow::Result<()> {
28    let message = if args.username.is_empty() {
29        Request::ListUsers(None)
30    } else {
31        Request::ListUsers(Some(args.username.to_owned()))
32    };
33
34    if let Err(err) = server_connection.send(message).await {
35        server_connection.close().await.ok();
36        anyhow::bail!(err);
37    }
38
39    let users = match server_connection.next().await {
40        Some(Ok(Response::ListUsers(users))) => users
41            .into_iter()
42            .filter_map(|(username, result)| match result {
43                Ok(user) => Some(user),
44                Err(err) => {
45                    eprintln!("{}", err.to_error_message(&username));
46                    eprintln!("Skipping...");
47                    None
48                }
49            })
50            .collect::<Vec<_>>(),
51        Some(Ok(Response::ListAllUsers(users))) => match users {
52            Ok(users) => users,
53            Err(err) => {
54                server_connection.send(Request::Exit).await?;
55                return Err(
56                    anyhow::anyhow!(err.to_error_message()).context("Failed to list all users")
57                );
58            }
59        },
60        response => return erroneous_server_response(response),
61    };
62
63    server_connection.send(Request::Exit).await?;
64
65    if args.json {
66        println!(
67            "{}",
68            serde_json::to_string_pretty(&users).context("Failed to serialize users to JSON")?
69        );
70    } else if users.is_empty() {
71        println!("No users to show.");
72    } else {
73        let mut table = prettytable::Table::new();
74        table.add_row(row![
75            "User",
76            "Password is set",
77            "Locked",
78            "Databases where user has privileges"
79        ]);
80        for user in users {
81            table.add_row(row![
82                user.user,
83                user.has_password,
84                user.is_locked,
85                user.databases.join("\n")
86            ]);
87        }
88        table.printstd();
89    }
90
91    Ok(())
92}