#![expect(dead_code, reason = "example data types are reflected rather than executed")]
use std::convert::Infallible;
use clap::{Args, Parser, Subcommand};
use clap_schema::{CliSchema, CommandSchema, schema_handler};
use schemars::JsonSchema;
use serde::Serialize;
#[derive(Debug, Parser, CliSchema)]
#[command(name = "resourcectl")]
#[schema(extend = CommandMetadata)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Debug, Subcommand, CommandSchema)]
enum Commands {
#[schema(extend = PaginationMetadata)]
List(ListArgs),
}
#[derive(Debug, Args)]
struct ListArgs {
#[arg(long)]
cursor: Option<String>,
}
#[derive(Debug, Serialize, JsonSchema)]
struct CommandMetadata {
effect: Effect,
idempotent: bool,
}
#[derive(Debug, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
struct PaginationMetadata {
cursor_argument: String,
cursor_output_field: String,
}
#[derive(Debug, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
enum Effect {
Read,
}
#[derive(Debug, Serialize)]
struct ListMetadataValue {
#[serde(flatten)]
command: CommandMetadata,
#[serde(flatten)]
pagination: PaginationMetadata,
}
#[derive(Debug, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
struct ResourcePage {
next_cursor: Option<String>,
}
#[schema_handler(ListArgs)]
fn list(_command: ListArgs) -> Result<ResourcePage, Infallible> {
Ok(ResourcePage { next_cursor: Some("next-123".to_owned()) })
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let contract = Cli::schema()?;
let extended_schema =
contract.extended_schema_for_command::<ListArgs>().expect("list extended schema");
let metadata = ListMetadataValue {
command: CommandMetadata { effect: Effect::Read, idempotent: true },
pagination: PaginationMetadata {
cursor_argument: "cursor".to_owned(),
cursor_output_field: "next_cursor".to_owned(),
},
};
println!("Application-owned metadata value:");
println!("{}", serde_json::to_string_pretty(&metadata)?);
println!("\nclap_schema effective extended schema:");
println!("{}", serde_json::to_string_pretty(extended_schema)?);
Ok(())
}