1use clap::Subcommand;
4
5use crate::cli::{Session, emit, report};
6use crate::exit::ExitCode;
7use crate::render::{Format, machine, queue};
8
9#[derive(Debug, Subcommand)]
10pub enum QueueCommand {
11 #[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_LIST))]
13 List,
14 #[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_GET))]
16 Get {
17 key: String,
19 },
20 #[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_CREATE))]
22 Create {
23 #[arg(long, short = 'k')]
25 key: String,
26 #[arg(long, short = 'n')]
28 name: String,
29 #[arg(long, short = 'l', value_name = "QUEUE")]
31 like: String,
32 #[arg(long)]
34 lead: Option<String>,
35 },
36 #[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_VERSIONS))]
38 Versions {
39 key: String,
41 },
42 #[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_TAGS))]
44 Tags {
45 key: String,
47 },
48 #[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_AUTOMATION))]
50 Automation {
51 key: String,
53 },
54 #[command(name = "local-fields", long_about = crate::cli::help::md(crate::cli::help::QUEUE_LOCAL_FIELDS))]
56 LocalFields {
57 key: String,
59 },
60 #[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_FIELDS))]
62 Fields {
63 key: String,
65 },
66}
67
68pub async fn run(command: &QueueCommand, session: &Session) -> ExitCode {
69 let client = match session.client() {
70 Ok(client) => client,
71 Err(code) => return code,
72 };
73
74 match command {
75 QueueCommand::List => match client.queues().await {
76 Ok(queues) => render(&queues, session, |queues| {
77 queue::queues(queues, &session.render)
78 }),
79 Err(error) => {
80 let code = error.exit_code();
81 report(&error, code)
82 }
83 },
84 QueueCommand::Get { key } => match client.queue(key).await {
85 Ok(settings) => {
86 let rendered = match session.render.format {
87 Format::Text => Ok(queue::settings(&settings, &session.render)),
88 Format::JsonRaw => machine(&settings, Format::Json),
89 other => machine(&settings, other),
90 };
91 match rendered {
92 Ok(text) => {
93 emit(&text);
94 ExitCode::Success
95 }
96 Err(error) => report(&error, ExitCode::Failure),
97 }
98 }
99 Err(error) => {
100 let code = error.exit_code();
101 report(&error, code)
102 }
103 },
104 QueueCommand::Create {
105 key,
106 name,
107 like,
108 lead,
109 } => create(&client, key, name, like, lead.as_deref(), session).await,
110 QueueCommand::Versions { key } => match client.queue_versions(key).await {
111 Ok(versions) => render(&versions, session, |versions| {
112 queue::versions(key, versions, &session.render)
113 }),
114 Err(error) => {
115 let code = error.exit_code();
116 report(&error, code)
117 }
118 },
119 QueueCommand::Tags { key } => match client.queue_tags(key).await {
120 Ok(tags) => render(&tags, session, |tags| {
121 queue::tags(key, tags, &session.render)
122 }),
123 Err(error) => {
124 let code = error.exit_code();
125 report(&error, code)
126 }
127 },
128 QueueCommand::Automation { key } => match client.queue_automation(key).await {
129 Ok(automation) => {
130 let rendered = match session.render.format {
131 Format::Text => Ok(queue::automation(key, &automation, &session.render)),
132 Format::JsonRaw => machine(&automation, Format::Json),
133 other => machine(&automation, other),
134 };
135 match rendered {
136 Ok(text) => {
137 emit(&text);
138 ExitCode::Success
139 }
140 Err(error) => report(&error, ExitCode::Failure),
141 }
142 }
143 Err(error) => {
144 let code = error.exit_code();
145 report(&error, code)
146 }
147 },
148 QueueCommand::LocalFields { key } => match client.queue_local_fields(key).await {
149 Ok(fields) => render(&fields, session, |fields| {
150 queue::local_fields(key, fields, &session.render)
151 }),
152 Err(error) => {
153 let code = error.exit_code();
154 report(&error, code)
155 }
156 },
157 QueueCommand::Fields { key } => match client.queue_fields(key).await {
158 Ok(fields) => render(&fields, session, |fields| {
159 queue::fields(fields, &session.render)
160 }),
161 Err(error) => {
162 let code = error.exit_code();
163 report(&error, code)
164 }
165 },
166 }
167}
168
169fn render<T: serde::Serialize>(
172 value: &[T],
173 session: &Session,
174 as_text: impl Fn(&[T]) -> String,
175) -> ExitCode {
176 let rendered = match session.render.format {
177 Format::Text => Ok(as_text(value)),
178 Format::JsonRaw => machine(&value, Format::Json),
182 other => machine(&value, other),
183 };
184
185 match rendered {
186 Ok(text) => {
187 emit(&text);
188 ExitCode::Success
189 }
190 Err(error) => report(&error, ExitCode::Failure),
191 }
192}
193
194async fn create(
202 client: &crate::api::Client,
203 key: &str,
204 name: &str,
205 like: &str,
206 lead: Option<&str>,
207 session: &Session,
208) -> ExitCode {
209 let blueprint = match client.queue_blueprint(like).await {
210 Ok(blueprint) => blueprint,
211 Err(error) => {
212 let code = error.exit_code();
213 return report(&error, code);
214 }
215 };
216
217 let lead = match lead {
218 Some(lead) => lead.to_owned(),
219 None => match client.myself().await {
220 Ok(user) => user.login.unwrap_or(user.id),
221 Err(error) => {
222 let code = error.exit_code();
223 return report(&error, code);
224 }
225 },
226 };
227
228 let body = serde_json::json!({
229 "key": key,
230 "name": name,
231 "lead": lead,
232 "defaultType": blueprint.default_type,
233 "defaultPriority": blueprint.default_priority,
234 "issueTypesConfig": blueprint.issue_types,
235 });
236
237 let action = format!("create queue {key} modelled on {like}");
238 let targets = [key.to_owned()];
239 let intent = crate::cli::write::Intent {
240 action: &action,
241 targets: &targets,
242 body: &body,
243 always_confirm: true,
247 };
248 if let crate::cli::write::Gate::Stop(code) = crate::cli::write::check(&intent, session) {
249 return code;
250 }
251
252 match client.create_queue(&body).await {
253 Ok(created) => {
254 let rendered = match session.render.format {
255 Format::Text => Ok(queue::settings(&created, &session.render)),
256 Format::JsonRaw => machine(&created, Format::Json),
257 other => machine(&created, other),
258 };
259 match rendered {
260 Ok(text) => {
261 emit(&text);
262 ExitCode::Success
263 }
264 Err(error) => report(&error, ExitCode::Failure),
265 }
266 }
267 Err(error) => {
268 let code = error.exit_code();
269 report(&error, code)
270 }
271 }
272}