Skip to main content

pimalaya_cli/clap/commands/
json_schema.rs

1use std::{collections::BTreeMap, fs, path::PathBuf};
2
3use anyhow::Result;
4use clap::Parser;
5use log::info;
6use serde_json::Value;
7
8use crate::{clap::parsers::path_parser, printer::Printer};
9
10/// Generate JSON Schemas of every command's JSON output to the given
11/// directory.
12///
13/// This command allows you to generate one JSON Schema per command
14/// describing the structure of its `--json` output, to the given
15/// directory. If the directory does not exist, it will be created. Any
16/// existing schema will be overriden.
17#[derive(Debug, Parser)]
18pub struct JsonSchemaCommand {
19    /// Directory where JSON Schema files should be generated in.
20    #[arg(value_parser = path_parser)]
21    pub dir: PathBuf,
22}
23
24impl JsonSchemaCommand {
25    /// Generates one `<command>.json` schema file per entry and reports
26    /// how many landed where.
27    ///
28    /// The map is keyed by command name (e.g. `himalaya-envelope-list`)
29    /// and valued by the already-built JSON Schema of that command's
30    /// output, mirroring how [`ManualCommand`] renders one man page per
31    /// subcommand. Callers own the command-to-schema mapping since the
32    /// output shapes live in the binary, not in this toolkit.
33    ///
34    /// [`ManualCommand`]: crate::clap::commands::ManualCommand
35    pub fn execute(
36        self,
37        printer: &mut impl Printer,
38        schemas: BTreeMap<String, Value>,
39    ) -> Result<()> {
40        let dir = &self.dir;
41        let count = schemas.len();
42
43        fs::create_dir_all(dir)?;
44
45        for (name, schema) in schemas {
46            let json = serde_json::to_vec_pretty(&schema)?;
47            info!("generate JSON Schema for command {name}");
48            fs::write(dir.join(format!("{name}.json")), json)?;
49        }
50
51        printer.out(format!(
52            "{count} JSON Schema(s) successfully generated in {}",
53            dir.display()
54        ))
55    }
56}