1use clap::{Subcommand, ValueEnum};
13
14use crate::api::Dictionary;
15use crate::api::models::DictEntry;
16use crate::cli::{Session, emit, report};
17use crate::exit::ExitCode;
18use crate::render::{Format, dict as render, machine};
19
20#[derive(Debug, Subcommand)]
21pub enum DictCommand {
22 #[command(long_about = crate::cli::help::md(crate::cli::help::DICT_LIST))]
24 List {
25 #[arg(long, value_enum)]
27 kind: Option<Kind>,
28 },
29}
30
31#[derive(Debug, Clone, Copy, ValueEnum)]
32pub enum Kind {
33 Types,
34 Priorities,
35 Statuses,
36 Resolutions,
37}
38
39impl From<Kind> for Dictionary {
40 fn from(kind: Kind) -> Self {
41 match kind {
42 Kind::Types => Self::Types,
43 Kind::Priorities => Self::Priorities,
44 Kind::Statuses => Self::Statuses,
45 Kind::Resolutions => Self::Resolutions,
46 }
47 }
48}
49
50pub async fn run(command: &DictCommand, session: &Session) -> ExitCode {
51 let client = match session.client() {
52 Ok(client) => client,
53 Err(code) => return code,
54 };
55
56 let DictCommand::List { kind } = command;
57
58 let wanted: Vec<Dictionary> = match kind {
62 Some(kind) => vec![(*kind).into()],
63 None => Dictionary::ALL.to_vec(),
64 };
65
66 let mut sections: Vec<(Dictionary, Vec<DictEntry>)> = Vec::with_capacity(wanted.len());
67 for kind in wanted {
68 match client.dictionary(kind).await {
69 Ok(entries) => sections.push((kind, entries)),
70 Err(error) => {
71 let code = error.exit_code();
72 return report(&error, code);
73 }
74 }
75 }
76
77 let rendered = match session.render.format {
78 Format::Text => Ok(render::many(§ions, &session.render)),
79 other => {
80 let keyed: serde_json::Map<String, serde_json::Value> = sections
84 .iter()
85 .map(|(kind, entries)| {
86 (
87 kind.label().to_owned(),
88 serde_json::to_value(entries).unwrap_or(serde_json::Value::Null),
89 )
90 })
91 .collect();
92 machine(
93 &keyed,
94 if other == Format::JsonRaw {
95 Format::Json
96 } else {
97 other
98 },
99 )
100 }
101 };
102
103 match rendered {
104 Ok(text) => {
105 emit(&text);
106 ExitCode::Success
107 }
108 Err(error) => report(&error, ExitCode::Failure),
109 }
110}