//! RON content validator CLI (#611). //! //! Deserializes a RON file into the actual Rust structs and prints errors. //! This is the copy team's lint tool — run it to check RON files without //! needing to compile the full server. //! //! # Usage //! //! ```sh //! # Via wrapper script (recommended): //! tooling/validate-ron content/global/zone-identity-spec.example.ron zone //! tooling/validate-ron content/global/culture-krenn.example.ron culture //! //! # Direct: //! cargo run --bin validate_ron -- //! ``` use std::process; use clap::Parser; use settled_reach_server::npc::blueprint::{CultureProfile, ZoneSpec}; #[derive(Parser)] #[command( name = "validate_ron", about = "Validate RON content files against Rust struct schemas" )] struct Args { /// Path to the RON file to validate. file: String, /// Schema type: "zone" (ZoneSpec) or "culture" (CultureProfile). schema: String, } fn main() { let args = Args::parse(); let content = match std::fs::read_to_string(&args.file) { Ok(c) => c, Err(e) => { eprintln!("Error reading {}: {}", args.file, e); process::exit(1); } }; match args.schema.as_str() { "zone" => match ron::from_str::(&content) { Ok(spec) => { println!("Valid ZoneSpec: {} ({})", spec.label, spec.zone_type); println!(" {} roles, {} social sites", spec.roles.len(), spec.social_sites.len()); } Err(e) => { eprintln!("Invalid ZoneSpec in {}:", args.file); eprintln!(" {}", e); process::exit(1); } }, "culture" => match ron::from_str::(&content) { Ok(profile) => { println!("Valid CultureProfile: {} ({})", profile.name, profile.id); println!( " {} given names, {} family names", profile.naming.given_names.len(), profile.naming.family_names.len() ); println!( " {} filler words, {} favored traits", profile.speech.filler_words.len(), profile.values.favored_traits.len() ); } Err(e) => { eprintln!("Invalid CultureProfile in {}:", args.file); eprintln!(" {}", e); process::exit(1); } }, other => { eprintln!("Unknown schema type: '{}'. Use 'zone' or 'culture'.", other); process::exit(1); } } }