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(long_about = crate::cli::help::md(crate::cli::help::QUEUE_ACCESS))]
56 Access {
57 key: String,
59 },
60 #[command(name = "local-fields", long_about = crate::cli::help::md(crate::cli::help::QUEUE_LOCAL_FIELDS))]
62 LocalFields {
63 key: String,
65 },
66 #[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_FIELDS))]
68 Fields {
69 key: String,
71 },
72}
73
74pub async fn run(command: &QueueCommand, session: &Session) -> ExitCode {
75 let client = match session.client() {
76 Ok(client) => client,
77 Err(code) => return code,
78 };
79
80 match command {
81 QueueCommand::List => match client.queues().await {
82 Ok(queues) => render(&queues, session, |queues| {
83 queue::queues(queues, &session.render)
84 }),
85 Err(error) => {
86 let code = error.exit_code();
87 report(&error, code)
88 }
89 },
90 QueueCommand::Get { key } => match client.queue(key).await {
91 Ok(settings) => render_one(&settings, session, |settings| {
92 queue::settings(settings, &session.render)
93 }),
94 Err(error) => {
95 let code = error.exit_code();
96 report(&error, code)
97 }
98 },
99 QueueCommand::Create {
100 key,
101 name,
102 like,
103 lead,
104 } => create(&client, key, name, like, lead.as_deref(), session).await,
105 QueueCommand::Versions { key } => match client.queue_versions(key).await {
106 Ok(versions) => render(&versions, session, |versions| {
107 queue::versions(key, versions, &session.render)
108 }),
109 Err(error) => {
110 let code = error.exit_code();
111 report(&error, code)
112 }
113 },
114 QueueCommand::Tags { key } => match client.queue_tags(key).await {
115 Ok(tags) => render(&tags, session, |tags| {
116 queue::tags(key, tags, &session.render)
117 }),
118 Err(error) => {
119 let code = error.exit_code();
120 report(&error, code)
121 }
122 },
123 QueueCommand::Access { key } => match client.queue_access(key).await {
124 Ok(access) => render_one(&access, session, |access| {
125 queue::access(key, access, &session.render)
126 }),
127 Err(error) => {
128 let code = error.exit_code();
129 report(&error, code)
130 }
131 },
132 QueueCommand::Automation { key } => match client.queue_automation(key).await {
133 Ok(automation) => render_one(&automation, session, |automation| {
134 queue::automation(key, automation, &session.render)
135 }),
136 Err(error) => {
137 let code = error.exit_code();
138 report(&error, code)
139 }
140 },
141 QueueCommand::LocalFields { key } => match client.queue_local_fields(key).await {
142 Ok(fields) => render(&fields, session, |fields| {
143 queue::local_fields(key, fields, &session.render)
144 }),
145 Err(error) => {
146 let code = error.exit_code();
147 report(&error, code)
148 }
149 },
150 QueueCommand::Fields { key } => match client.queue_fields(key).await {
151 Ok(fields) => render(&fields, session, |fields| {
152 queue::fields(fields, &session.render)
153 }),
154 Err(error) => {
155 let code = error.exit_code();
156 report(&error, code)
157 }
158 },
159 }
160}
161
162fn render<T: serde::Serialize>(
165 value: &[T],
166 session: &Session,
167 as_text: impl Fn(&[T]) -> String,
168) -> ExitCode {
169 let rendered = match session.render.format {
170 Format::Text => Ok(as_text(value)),
171 Format::JsonRaw => machine(&value, Format::Json),
175 other => machine(&value, other),
176 };
177
178 match rendered {
179 Ok(text) => {
180 emit(&text);
181 ExitCode::Success
182 }
183 Err(error) => report(&error, ExitCode::Failure),
184 }
185}
186
187fn render_one<T: serde::Serialize>(
189 value: &T,
190 session: &Session,
191 as_text: impl Fn(&T) -> String,
192) -> ExitCode {
193 let rendered = match session.render.format {
194 Format::Text => Ok(as_text(value)),
195 Format::JsonRaw => machine(value, Format::Json),
196 other => machine(value, other),
197 };
198
199 match rendered {
200 Ok(text) => {
201 emit(&text);
202 ExitCode::Success
203 }
204 Err(error) => report(&error, ExitCode::Failure),
205 }
206}
207
208async fn create(
216 client: &crate::api::Client,
217 key: &str,
218 name: &str,
219 like: &str,
220 lead: Option<&str>,
221 session: &Session,
222) -> ExitCode {
223 let blueprint = match client.queue_blueprint(like).await {
224 Ok(blueprint) => blueprint,
225 Err(error) => {
226 let code = error.exit_code();
227 return report(&error, code);
228 }
229 };
230
231 let lead = match lead {
232 Some(lead) => lead.to_owned(),
233 None => match client.myself().await {
234 Ok(user) => user.login.unwrap_or(user.id),
235 Err(error) => {
236 let code = error.exit_code();
237 return report(&error, code);
238 }
239 },
240 };
241
242 let body = serde_json::json!({
243 "key": key,
244 "name": name,
245 "lead": lead,
246 "defaultType": blueprint.default_type,
247 "defaultPriority": blueprint.default_priority,
248 "issueTypesConfig": blueprint.issue_types,
249 });
250
251 let action = format!("create queue {key} modelled on {like}");
252 let targets = [key.to_owned()];
253 let intent = crate::cli::write::Intent {
254 action: &action,
255 targets: &targets,
256 body: &body,
257 always_confirm: true,
261 };
262 if let crate::cli::write::Gate::Stop(code) = crate::cli::write::check(&intent, session) {
263 return code;
264 }
265
266 match client.create_queue(&body).await {
267 Ok(created) => {
268 let rendered = match session.render.format {
269 Format::Text => Ok(queue::settings(&created, &session.render)),
270 Format::JsonRaw => machine(&created, Format::Json),
271 other => machine(&created, other),
272 };
273 match rendered {
274 Ok(text) => {
275 emit(&text);
276 ExitCode::Success
277 }
278 Err(error) => report(&error, ExitCode::Failure),
279 }
280 }
281 Err(error) => {
282 let code = error.exit_code();
283 report(&error, code)
284 }
285 }
286}