1use clap::{Subcommand, ValueEnum};
8
9use crate::api::TemplateKind;
10use crate::cli::{Session, emit, report};
11use crate::exit::ExitCode;
12use crate::render::{Format, machine, queue as render};
13
14#[derive(Debug, Subcommand)]
15pub enum FieldCommand {
16 #[command(long_about = crate::cli::help::md(crate::cli::help::FIELD_LIST))]
18 List,
19 #[command(long_about = crate::cli::help::md(crate::cli::help::FIELD_GET))]
21 Get {
22 key: String,
24 #[arg(long)]
26 all: bool,
27 },
28}
29
30#[derive(Debug, Subcommand)]
31pub enum TemplateCommand {
32 #[command(long_about = crate::cli::help::md(crate::cli::help::TEMPLATE_LIST))]
34 List {
35 #[arg(long, value_enum, default_value_t = Kind::Issue)]
37 kind: Kind,
38 },
39}
40
41#[derive(Debug, Clone, Copy, ValueEnum)]
42pub enum Kind {
43 Issue,
44 Comment,
45}
46
47impl From<Kind> for TemplateKind {
48 fn from(kind: Kind) -> Self {
49 match kind {
50 Kind::Issue => Self::Issue,
51 Kind::Comment => Self::Comment,
52 }
53 }
54}
55
56pub async fn run(command: &FieldCommand, session: &Session) -> ExitCode {
57 let client = match session.client() {
58 Ok(client) => client,
59 Err(code) => return code,
60 };
61
62 match command {
63 FieldCommand::List => match client.fields().await {
64 Ok(fields) => finish(&fields, session, |fields| {
65 render::fields(fields, &session.render)
66 }),
67 Err(error) => {
68 let code = error.exit_code();
69 report(&error, code)
70 }
71 },
72 FieldCommand::Get { key, all } => match client.field(key).await {
73 Ok(field) => {
74 let rendered = match session.render.format {
75 Format::Text => Ok(render::field_spec(&field, *all, &session.render)),
76 Format::JsonRaw => machine(&field, Format::Json),
77 other => machine(&field, other),
78 };
79 match rendered {
80 Ok(text) => {
81 emit(&text);
82 ExitCode::Success
83 }
84 Err(error) => report(&error, ExitCode::Failure),
85 }
86 }
87 Err(error) => {
88 let code = error.exit_code();
89 report(&error, code)
90 }
91 },
92 }
93}
94
95pub async fn run_templates(command: &TemplateCommand, session: &Session) -> ExitCode {
96 let client = match session.client() {
97 Ok(client) => client,
98 Err(code) => return code,
99 };
100
101 let TemplateCommand::List { kind } = command;
102 match client.templates((*kind).into()).await {
103 Ok(templates) => finish(&templates, session, |templates| {
104 render::templates(templates, &session.render)
105 }),
106 Err(error) => {
107 let code = error.exit_code();
108 report(&error, code)
109 }
110 }
111}
112
113fn finish<T: serde::Serialize>(
114 value: &[T],
115 session: &Session,
116 as_text: impl Fn(&[T]) -> String,
117) -> ExitCode {
118 let rendered = match session.render.format {
119 Format::Text => Ok(as_text(value)),
120 Format::JsonRaw => machine(&value, Format::Json),
121 other => machine(&value, other),
122 };
123
124 match rendered {
125 Ok(text) => {
126 emit(&text);
127 ExitCode::Success
128 }
129 Err(error) => report(&error, ExitCode::Failure),
130 }
131}