1use clap::Subcommand;
2
3use crate::api::HtbClient;
4use crate::output::{self, OutputFormat};
5
6#[derive(Subcommand)]
7pub enum UserCommand {
8 Me,
10 Info {
12 user: String,
14 },
15}
16
17pub async fn handle(
18 client: &HtbClient,
19 cmd: UserCommand,
20 format: OutputFormat,
21) -> anyhow::Result<()> {
22 match cmd {
23 UserCommand::Me => {
24 let current = client.user().current().await?;
25 let profile = client.user().profile(current.id).await?;
26 let fields = vec![
27 ("Username", profile.name.clone()),
28 ("ID", profile.id.to_string()),
29 ("Rank", profile.rank.clone().unwrap_or_default()),
30 ("Points", profile.points.to_string()),
31 (
32 "Ranking",
33 profile
34 .ranking
35 .map(|r| format!("#{r}"))
36 .unwrap_or_else(|| "-".into()),
37 ),
38 ("User Owns", profile.user_owns.to_string()),
39 ("System Owns", profile.system_owns.to_string()),
40 ("User Bloods", profile.user_bloods.to_string()),
41 ("System Bloods", profile.system_bloods.to_string()),
42 ("Country", profile.country_name.clone().unwrap_or_default()),
43 ("Server", profile.server.clone().unwrap_or_default()),
44 ];
45 output::print_detail(&profile, format, &fields);
46 }
47
48 UserCommand::Info { user } => {
49 let user_id: u64 = match user.parse() {
50 Ok(id) => id,
51 Err(_) => {
52 anyhow::bail!("Please provide a numeric user ID. Username lookup is not supported by the API.");
53 }
54 };
55 let profile = client.user().profile(user_id).await?;
56 let fields = vec![
57 ("Username", profile.name.clone()),
58 ("ID", profile.id.to_string()),
59 ("Rank", profile.rank.clone().unwrap_or_default()),
60 ("Points", profile.points.to_string()),
61 (
62 "Ranking",
63 profile
64 .ranking
65 .map(|r| format!("#{r}"))
66 .unwrap_or_else(|| "-".into()),
67 ),
68 ("User Owns", profile.user_owns.to_string()),
69 ("System Owns", profile.system_owns.to_string()),
70 ("Country", profile.country_name.clone().unwrap_or_default()),
71 ];
72 output::print_detail(&profile, format, &fields);
73 }
74 }
75 Ok(())
76}