From a7882545b7a9aa0409dae95f8f4e51922b438615 Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Sat, 18 Jul 2026 21:17:57 +0400 Subject: feat(script): parse varset numeric defaults --- apps/fparkan-cli/src/main.rs | 62 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'apps/fparkan-cli/src/main.rs') diff --git a/apps/fparkan-cli/src/main.rs b/apps/fparkan-cli/src/main.rs index dbaf5dd..d3e1df5 100644 --- a/apps/fparkan-cli/src/main.rs +++ b/apps/fparkan-cli/src/main.rs @@ -245,6 +245,17 @@ struct ScriptHeaderWordCount { instructions: usize, } +#[derive(Serialize)] +struct VarSetInspectOutput<'a> { + schema_version: &'static str, + path: &'a str, + declarations: usize, + float_defaults: usize, + dword_defaults: usize, + first_name: Option<&'a str>, + last_name: Option<&'a str>, +} + fn main() { let args: Vec = std::env::args().skip(1).collect(); let result = run(&args); @@ -313,6 +324,10 @@ fn run(args: &[String]) -> Result<(), String> { let rest = strip_format_json(rest)?; inspect_script(&rest) } + [domain, command, rest @ ..] if domain == "varset" && command == "inspect" => { + let rest = strip_format_json(rest)?; + inspect_varset(&rest) + } _ => Err(usage()), } } @@ -364,6 +379,40 @@ fn script_inspect_json( }) } +fn inspect_varset(args: &[String]) -> Result<(), String> { + let path = parse_file_path(args, "varset inspect")?; + let bytes = std::fs::read(&path).map_err(|err| format!("{}: {err}", path.display()))?; + let varset = + fparkan_script::parse_varset(&bytes).map_err(|err| format!("{}: {err}", path.display()))?; + let display_path = path.display().to_string(); + println!("{}", varset_inspect_json(&display_path, &varset)?); + Ok(()) +} + +fn varset_inspect_json(path: &str, varset: &fparkan_script::VarSet) -> Result { + let float_defaults = varset + .declarations + .iter() + .filter(|declaration| declaration.type_name == fparkan_script::VarSetType::Float) + .count(); + let dword_defaults = varset.declarations.len() - float_defaults; + serialize_json(&VarSetInspectOutput { + schema_version: "fparkan-varset-inspect-v1", + path, + declarations: varset.declarations.len(), + float_defaults, + dword_defaults, + first_name: varset + .declarations + .first() + .map(|declaration| declaration.name.as_str()), + last_name: varset + .declarations + .last() + .map(|declaration| declaration.name.as_str()), + }) +} + fn exit_code(result: &Result<(), String>) -> i32 { if result.is_ok() { 0 @@ -839,7 +888,7 @@ fn prototype_graph_requiredness_label( } fn usage() -> String { - "usage: fparkan corpus discover|validate --root [--format json] | archive inspect [--format json] | terrain inspect [--format json] | wear inspect --root --archive --resource [--format json] | model inspect --root --archive --resource [--format json] | script inspect [--format json] | prototype inspect --root --key [--format json] | mission graph|inspect --root --mission [--format json]".to_string() + "usage: fparkan corpus discover|validate --root [--format json] | archive inspect [--format json] | terrain inspect [--format json] | wear inspect --root --archive --resource [--format json] | model inspect --root --archive --resource [--format json] | script inspect [--format json] | varset inspect [--format json] | prototype inspect --root --key [--format json] | mission graph|inspect --root --mission [--format json]".to_string() } #[cfg(test)] @@ -878,6 +927,17 @@ mod tests { ); } + #[test] + fn varset_inspect_json_has_canonical_field_order() { + let varset = + fparkan_script::parse_varset(b"VAR( float, f0, 0)\nVAR( DWORD, d0, 0xffffffff)\n") + .expect("minimal varset"); + assert_eq!( + varset_inspect_json("varset.var", &varset), + Ok("{\"schema_version\":\"fparkan-varset-inspect-v1\",\"path\":\"varset.var\",\"declarations\":2,\"float_defaults\":1,\"dword_defaults\":1,\"first_name\":\"f0\",\"last_name\":\"d0\"}".to_string()) + ); + } + #[test] fn archive_json_has_schema_version() { let json = archive_inspect_json("archive.lib", "NRes", 3, Some(true)) -- cgit v1.2.3