use clap::Subcommand;
use crate::cli::{Session, emit, report};
use crate::exit::ExitCode;
use crate::render::{Format, machine, queue};
#[derive(Debug, Subcommand)]
pub enum QueueCommand {
#[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_LIST))]
List,
#[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_GET))]
Get {
key: String,
},
#[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_CREATE))]
Create {
#[arg(long, short = 'k')]
key: String,
#[arg(long, short = 'n')]
name: String,
#[arg(long, short = 'l', value_name = "QUEUE")]
like: String,
#[arg(long)]
lead: Option<String>,
},
#[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_VERSIONS))]
Versions {
key: String,
},
#[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_TAGS))]
Tags {
key: String,
},
#[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_AUTOMATION))]
Automation {
key: String,
},
#[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_ACCESS))]
Access {
key: String,
},
#[command(name = "local-fields", long_about = crate::cli::help::md(crate::cli::help::QUEUE_LOCAL_FIELDS))]
LocalFields {
key: String,
},
#[command(long_about = crate::cli::help::md(crate::cli::help::QUEUE_FIELDS))]
Fields {
key: String,
},
}
pub async fn run(command: &QueueCommand, session: &Session) -> ExitCode {
let client = match session.client() {
Ok(client) => client,
Err(code) => return code,
};
match command {
QueueCommand::List => match client.queues().await {
Ok(queues) => render(&queues, session, |queues| {
queue::queues(queues, &session.render)
}),
Err(error) => {
let code = error.exit_code();
report(&error, code)
}
},
QueueCommand::Get { key } => match client.queue(key).await {
Ok(settings) => render_one(&settings, session, |settings| {
queue::settings(settings, &session.render)
}),
Err(error) => {
let code = error.exit_code();
report(&error, code)
}
},
QueueCommand::Create {
key,
name,
like,
lead,
} => create(&client, key, name, like, lead.as_deref(), session).await,
QueueCommand::Versions { key } => match client.queue_versions(key).await {
Ok(versions) => render(&versions, session, |versions| {
queue::versions(key, versions, &session.render)
}),
Err(error) => {
let code = error.exit_code();
report(&error, code)
}
},
QueueCommand::Tags { key } => match client.queue_tags(key).await {
Ok(tags) => render(&tags, session, |tags| {
queue::tags(key, tags, &session.render)
}),
Err(error) => {
let code = error.exit_code();
report(&error, code)
}
},
QueueCommand::Access { key } => match client.queue_access(key).await {
Ok(access) => render_one(&access, session, |access| {
queue::access(key, access, &session.render)
}),
Err(error) => {
let code = error.exit_code();
report(&error, code)
}
},
QueueCommand::Automation { key } => match client.queue_automation(key).await {
Ok(automation) => render_one(&automation, session, |automation| {
queue::automation(key, automation, &session.render)
}),
Err(error) => {
let code = error.exit_code();
report(&error, code)
}
},
QueueCommand::LocalFields { key } => match client.queue_local_fields(key).await {
Ok(fields) => render(&fields, session, |fields| {
queue::local_fields(key, fields, &session.render)
}),
Err(error) => {
let code = error.exit_code();
report(&error, code)
}
},
QueueCommand::Fields { key } => match client.queue_fields(key).await {
Ok(fields) => render(&fields, session, |fields| {
queue::fields(fields, &session.render)
}),
Err(error) => {
let code = error.exit_code();
report(&error, code)
}
},
}
}
fn render<T: serde::Serialize>(
value: &[T],
session: &Session,
as_text: impl Fn(&[T]) -> String,
) -> ExitCode {
let rendered = match session.render.format {
Format::Text => Ok(as_text(value)),
Format::JsonRaw => machine(&value, Format::Json),
other => machine(&value, other),
};
match rendered {
Ok(text) => {
emit(&text);
ExitCode::Success
}
Err(error) => report(&error, ExitCode::Failure),
}
}
fn render_one<T: serde::Serialize>(
value: &T,
session: &Session,
as_text: impl Fn(&T) -> String,
) -> ExitCode {
let rendered = match session.render.format {
Format::Text => Ok(as_text(value)),
Format::JsonRaw => machine(value, Format::Json),
other => machine(value, other),
};
match rendered {
Ok(text) => {
emit(&text);
ExitCode::Success
}
Err(error) => report(&error, ExitCode::Failure),
}
}
async fn create(
client: &crate::api::Client,
key: &str,
name: &str,
like: &str,
lead: Option<&str>,
session: &Session,
) -> ExitCode {
let blueprint = match client.queue_blueprint(like).await {
Ok(blueprint) => blueprint,
Err(error) => {
let code = error.exit_code();
return report(&error, code);
}
};
let lead = match lead {
Some(lead) => lead.to_owned(),
None => match client.myself().await {
Ok(user) => user.login.unwrap_or(user.id),
Err(error) => {
let code = error.exit_code();
return report(&error, code);
}
},
};
let body = serde_json::json!({
"key": key,
"name": name,
"lead": lead,
"defaultType": blueprint.default_type,
"defaultPriority": blueprint.default_priority,
"issueTypesConfig": blueprint.issue_types,
});
let action = format!("create queue {key} modelled on {like}");
let targets = [key.to_owned()];
let intent = crate::cli::write::Intent {
action: &action,
targets: &targets,
body: &body,
always_confirm: true,
};
if let crate::cli::write::Gate::Stop(code) = crate::cli::write::check(&intent, session) {
return code;
}
match client.create_queue(&body).await {
Ok(created) => {
let rendered = match session.render.format {
Format::Text => Ok(queue::settings(&created, &session.render)),
Format::JsonRaw => machine(&created, Format::Json),
other => machine(&created, other),
};
match rendered {
Ok(text) => {
emit(&text);
ExitCode::Success
}
Err(error) => report(&error, ExitCode::Failure),
}
}
Err(error) => {
let code = error.exit_code();
report(&error, code)
}
}
}