use clap::{Arg, Command};
use crate::infra::driving::cli::errors::{die1, CliError};
use crate::infra::driving::cli::output::OutputFormat;
use crate::infra::driving::cli::render_structured;
use crate::infra::driving::cli::theme;
pub(crate) fn subcommand(noun: &'static str, id_help: &'static str) -> Command {
let article = super::indefinite(noun);
Command::new("body")
.about(format!("Read or edit the body of {article}"))
.subcommand_required(true)
.arg_required_else_help(true)
.subcommand(
Command::new("show")
.about(format!("Print the current body of {article}"))
.arg(id_arg(id_help)),
)
.subcommand(
Command::new("edit")
.about(format!(
"Rewrite the body of {article} from stdin or $EDITOR",
))
.arg(id_arg(id_help)),
)
}
fn id_arg(help: &'static str) -> Arg {
Arg::new("id").required(true).value_name("ID").help(help)
}
pub(crate) enum View {
NotFound,
Shown { body: String },
Edited,
EditNoOp,
}
pub(crate) fn render(
view: View,
display_id: &str,
canonical_id: &str,
noun: &str,
output_fmt: OutputFormat,
) {
match view {
View::NotFound => die1(
CliError::not_found(format!("{noun} '{display_id}'"), &format!("{noun} list")),
output_fmt,
),
view if output_fmt.is_structured() => {
render_structured_view(view, canonical_id, output_fmt)
}
View::Shown { body } => print!("{body}"),
View::Edited => println!(
"{}",
theme::success(&format!("Updated body of {noun} {display_id}")),
),
View::EditNoOp => println!(
"{}",
theme::noop(&format!(
"No change: body of {noun} {display_id} is unchanged",
)),
),
}
}
fn render_structured_view(view: View, canonical_id: &str, output_fmt: OutputFormat) {
#[derive(serde::Serialize)]
#[serde(untagged)]
enum BodyResult<'a> {
Show { id: &'a str, body: &'a str },
Outcome { id: &'a str, outcome: &'a str },
}
let r = match &view {
View::Shown { body } => BodyResult::Show {
id: canonical_id,
body,
},
View::Edited => BodyResult::Outcome {
id: canonical_id,
outcome: "updated",
},
View::EditNoOp => BodyResult::Outcome {
id: canonical_id,
outcome: "noop",
},
View::NotFound => unreachable!(),
};
render_structured(&r, output_fmt);
}