use argx::{Parser as _, argx};
#[derive(argx::Args)]
struct Get {
id: String,
}
#[argx(schema)]
struct GetOutput {
id: String,
}
#[argx(schema)]
enum GetError {
NotFound,
}
#[argx(handler = Get)]
fn get(command: Get) -> Result<GetOutput, GetError> {
if command.id == "missing" { Err(GetError::NotFound) } else { Ok(GetOutput { id: command.id }) }
}
#[derive(argx::Args)]
struct List;
#[argx(schema)]
struct ListOutput {
ids: Vec<String>,
}
#[argx(schema)]
enum ListError {
Unavailable,
}
#[argx(handler = List)]
fn list(_: List) -> Result<ListOutput, ListError> {
let ids = vec!["object-7".to_owned()];
if ids.is_empty() { Err(ListError::Unavailable) } else { Ok(ListOutput { ids }) }
}
#[derive(argx::Subcommand)]
#[argx(schema)]
enum ObjectCommand {
#[argx(metadata({
"readOnly": true,
"requiredScopes": ["objects:read"],
}))]
Get(Get),
#[argx(metadata({ "readOnly": true }))]
List(List),
}
#[derive(argx::Args)]
#[argx(schema)]
struct Objects {
#[argx(subcommand)]
command: ObjectCommand,
}
#[derive(argx::Subcommand)]
#[argx(schema)]
enum Command {
Objects(Objects),
}
#[derive(argx::Parser)]
#[argx(name = "schema", schema)]
struct Cli {
#[argx(subcommand)]
command: Command,
}
fn main() {
match Cli::parse().command {
Command::Objects(objects) => match objects.command {
ObjectCommand::Get(command) => match get(command) {
Ok(output) => println!("id: {}", output.id),
Err(GetError::NotFound) => {
eprintln!("object not found");
std::process::exit(1);
}
},
ObjectCommand::List(command) => match list(command) {
Ok(output) => println!("{}", output.ids.join("\n")),
Err(ListError::Unavailable) => {
eprintln!("objects unavailable");
std::process::exit(1);
}
},
},
}
}