Skip to main content

callisto_cli/commands/
schema.rs

1use std::process::ExitCode;
2
3use callisto_format::{Changeset, PreState};
4use callisto_model::{
5    InitReport, MatrixReport, PublishPlan, SnapshotReport, StatusReport, TagReport, ValidateReport, VersionReport,
6};
7use schemars::schema_for;
8
9use crate::cli::{GlobalArgs, SchemaArgs};
10use crate::error::CliError;
11
12pub fn handle(args: SchemaArgs, _global: &GlobalArgs) -> Result<ExitCode, CliError> {
13    let schema = match args.target_type.as_deref().unwrap_or("status") {
14        "status" => schema_for!(StatusReport),
15        "version" => schema_for!(VersionReport),
16        "snapshot" => schema_for!(SnapshotReport),
17        "validate" => schema_for!(ValidateReport),
18        "tag" => schema_for!(TagReport),
19        "init" => schema_for!(InitReport),
20        "plan-publish" | "publish-plan" => schema_for!(PublishPlan),
21        "changeset" => schema_for!(Changeset),
22        "pre" => schema_for!(PreState),
23        "matrix" => schema_for!(MatrixReport),
24        other => {
25            return Err(CliError::Other(format!(
26                "Unknown schema target type `{other}`. Supported types: status, version, snapshot, validate, tag, init, plan-publish, changeset, pre, matrix"
27            )));
28        }
29    };
30
31    let json = serde_json::to_string_pretty(&schema)
32        .map_err(|e| CliError::Other(format!("Failed to serialize JSON schema: {e}")))?;
33    println!("{json}");
34    Ok(ExitCode::SUCCESS)
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40
41    fn global() -> GlobalArgs {
42        GlobalArgs {
43            format: crate::cli::OutputFormat::Text,
44            cwd: std::path::PathBuf::from("."),
45            dry_run: false,
46        }
47    }
48
49    #[test]
50    fn handle_rejects_unknown_target_type() {
51        let result = handle(
52            SchemaArgs {
53                target_type: Some("bogus".to_string()),
54            },
55            &global(),
56        );
57        match result {
58            Err(CliError::Other(msg)) => {
59                assert!(msg.contains("Unknown schema target type `bogus`"), "got: {msg}");
60                assert!(msg.contains("Supported types:"), "got: {msg}");
61            }
62            other => panic!("expected CliError::Other, got: {other:?}"),
63        }
64    }
65}