Skip to main content

stormchaser_cli/commands/
schema.rs

1use anyhow::{Context, Result};
2use clap::{Subcommand, ValueEnum};
3use stormchaser_dsl::hcl_schema::json_schema_to_hcl;
4use stormchaser_model::schema_gen::{generate_dsl_schema, generate_event_schemas};
5
6/// Output format for schema generation.
7#[derive(ValueEnum, Clone, Debug)]
8pub enum SchemaFormat {
9    /// JSON Schema (Draft 7)
10    Json,
11    /// HCL format
12    Hcl,
13}
14
15/// CLI subcommands for managing schemas.
16#[derive(Subcommand)]
17pub enum SchemaCommands {
18    /// Generate schema for the DSL
19    Generate {
20        /// Output format
21        #[arg(short, long, value_enum, default_value_t = SchemaFormat::Json)]
22        format: SchemaFormat,
23    },
24    /// Generate schemas for NATS events and output them to a directory
25    GenerateEvents {
26        /// Output directory
27        #[arg(short, long, default_value = "schemas")]
28        output_dir: String,
29    },
30}
31
32/// Handles the `schema` command logic.
33pub fn handle(command: SchemaCommands) -> Result<()> {
34    match command {
35        SchemaCommands::Generate { format } => {
36            let schema = generate_dsl_schema();
37
38            match format {
39                SchemaFormat::Hcl => {
40                    let json_val = serde_json::to_value(&schema)?;
41                    let hcl_body = json_schema_to_hcl(&json_val)
42                        .context("Failed to serialize schema to HCL")?;
43                    println!("{}", hcl::to_string(&hcl_body)?);
44                }
45                SchemaFormat::Json => {
46                    println!("{}", serde_json::to_string_pretty(&schema)?);
47                }
48            }
49        }
50        SchemaCommands::GenerateEvents { output_dir } => {
51            std::fs::create_dir_all(&output_dir)?;
52            let schemas = generate_event_schemas();
53            for (name, schema) in schemas {
54                let filename = format!("{}/{}.json", output_dir, name);
55                let json_str = serde_json::to_string_pretty(&schema)?;
56                std::fs::write(&filename, json_str)?;
57                println!("✓ Wrote schema to {}", filename);
58            }
59        }
60    }
61    Ok(())
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn test_handle_schema_generate_json() {
70        let cmd = SchemaCommands::Generate {
71            format: SchemaFormat::Json,
72        };
73        let result = handle(cmd);
74        assert!(result.is_ok());
75    }
76
77    #[test]
78    fn test_handle_schema_generate_hcl() {
79        let cmd = SchemaCommands::Generate {
80            format: SchemaFormat::Hcl,
81        };
82        let result = handle(cmd);
83        assert!(result.is_ok());
84    }
85}