use clap::{Subcommand, ValueEnum};
use crate::api::Dictionary;
use crate::api::models::DictEntry;
use crate::cli::{Session, emit, report};
use crate::exit::ExitCode;
use crate::render::{Format, dict as render, machine};
#[derive(Debug, Subcommand)]
pub enum DictCommand {
#[command(long_about = crate::cli::help::md(crate::cli::help::DICT_LIST))]
List {
#[arg(long, value_enum)]
kind: Option<Kind>,
},
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum Kind {
Types,
Priorities,
Statuses,
Resolutions,
}
impl From<Kind> for Dictionary {
fn from(kind: Kind) -> Self {
match kind {
Kind::Types => Self::Types,
Kind::Priorities => Self::Priorities,
Kind::Statuses => Self::Statuses,
Kind::Resolutions => Self::Resolutions,
}
}
}
pub async fn run(command: &DictCommand, session: &Session) -> ExitCode {
let client = match session.client() {
Ok(client) => client,
Err(code) => return code,
};
let DictCommand::List { kind } = command;
let wanted: Vec<Dictionary> = match kind {
Some(kind) => vec![(*kind).into()],
None => Dictionary::ALL.to_vec(),
};
let mut sections: Vec<(Dictionary, Vec<DictEntry>)> = Vec::with_capacity(wanted.len());
for kind in wanted {
match client.dictionary(kind).await {
Ok(entries) => sections.push((kind, entries)),
Err(error) => {
let code = error.exit_code();
return report(&error, code);
}
}
}
let rendered = match session.render.format {
Format::Text => Ok(render::many(§ions, &session.render)),
other => {
let keyed: serde_json::Map<String, serde_json::Value> = sections
.iter()
.map(|(kind, entries)| {
(
kind.label().to_owned(),
serde_json::to_value(entries).unwrap_or(serde_json::Value::Null),
)
})
.collect();
machine(
&keyed,
if other == Format::JsonRaw {
Format::Json
} else {
other
},
)
}
};
match rendered {
Ok(text) => {
emit(&text);
ExitCode::Success
}
Err(error) => report(&error, ExitCode::Failure),
}
}