diff options
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/fparkan-cli/Cargo.toml | 1 | ||||
| -rw-r--r-- | apps/fparkan-cli/src/main.rs | 64 |
2 files changed, 64 insertions, 1 deletions
diff --git a/apps/fparkan-cli/Cargo.toml b/apps/fparkan-cli/Cargo.toml index 10689b4..dcf9c12 100644 --- a/apps/fparkan-cli/Cargo.toml +++ b/apps/fparkan-cli/Cargo.toml @@ -13,6 +13,7 @@ fparkan-inspection = { path = "../../crates/fparkan-inspection", version = "0.1. fparkan-path = { path = "../../crates/fparkan-path", version = "0.1.0" } fparkan-resource = { path = "../../crates/fparkan-resource", version = "0.1.0" } fparkan-runtime = { path = "../../crates/fparkan-runtime", version = "0.1.0" } +fparkan-script = { path = "../../crates/fparkan-script", version = "0.1.0" } fparkan-vfs = { path = "../../crates/fparkan-vfs", version = "0.1.0" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/apps/fparkan-cli/src/main.rs b/apps/fparkan-cli/src/main.rs index 2f933e6..a6fb25e 100644 --- a/apps/fparkan-cli/src/main.rs +++ b/apps/fparkan-cli/src/main.rs @@ -48,6 +48,7 @@ const MISSION_INSPECT_SCHEMA: &str = "fparkan-mission-inspect-v1"; const TERRAIN_INSPECT_SCHEMA: &str = "fparkan-terrain-inspect-v1"; const MODEL_INSPECT_SCHEMA: &str = "fparkan-model-inspect-v1"; const WEAR_INSPECT_SCHEMA: &str = "fparkan-wear-inspect-v1"; +const SCRIPT_INSPECT_SCHEMA: &str = "fparkan-script-inspect-v1"; #[derive(Serialize)] struct ArchiveInspectOutput<'a> { @@ -226,6 +227,17 @@ struct PrototypeGraphEdgeInspectOutput { resource_raw_hex: Option<String>, } +#[derive(Serialize)] +struct ScriptInspectOutput<'a> { + schema_version: &'static str, + path: &'a str, + opcode_handler_count: u32, + events: usize, + instructions: usize, + references: usize, + trailing_bytes: usize, +} + fn main() { let args: Vec<String> = std::env::args().skip(1).collect(); let result = run(&args); @@ -290,10 +302,50 @@ fn run(args: &[String]) -> Result<(), String> { let rest = strip_format_json(rest)?; inspect_model(&rest) } + [domain, command, rest @ ..] if domain == "script" && command == "inspect" => { + let rest = strip_format_json(rest)?; + inspect_script(&rest) + } _ => Err(usage()), } } +fn inspect_script(args: &[String]) -> Result<(), String> { + let path = parse_file_path(args, "script inspect")?; + let bytes = std::fs::read(&path).map_err(|err| format!("{}: {err}", path.display()))?; + let package = + fparkan_script::decode(&bytes).map_err(|err| format!("{}: {err}", path.display()))?; + let display_path = path.display().to_string(); + println!("{}", script_inspect_json(&display_path, &package)?); + Ok(()) +} + +fn script_inspect_json( + path: &str, + package: &fparkan_script::ScriptPackage, +) -> Result<String, String> { + let instructions = package + .events + .iter() + .map(|event| event.instructions.len()) + .sum(); + let references = package + .events + .iter() + .flat_map(|event| &event.instructions) + .map(|instruction| instruction.references.len()) + .sum(); + serialize_json(&ScriptInspectOutput { + schema_version: SCRIPT_INSPECT_SCHEMA, + path, + opcode_handler_count: package.opcode_handler_count, + events: package.events.len(), + instructions, + references, + trailing_bytes: package.trailing_bytes.len(), + }) +} + fn exit_code(result: &Result<(), String>) -> i32 { if result.is_ok() { 0 @@ -769,7 +821,7 @@ fn prototype_graph_requiredness_label( } fn usage() -> String { - "usage: fparkan corpus discover|validate --root <path> [--format json] | archive inspect <file> [--format json] | terrain inspect <Land.msh> [--format json] | wear inspect --root <path> --archive <archive> --resource <wear.wea> [--format json] | model inspect --root <path> --archive <archive> --resource <model.msh> [--format json] | prototype inspect --root <path> --key <key> [--format json] | mission graph|inspect --root <path> --mission <path> [--format json]".to_string() + "usage: fparkan corpus discover|validate --root <path> [--format json] | archive inspect <file> [--format json] | terrain inspect <Land.msh> [--format json] | wear inspect --root <path> --archive <archive> --resource <wear.wea> [--format json] | model inspect --root <path> --archive <archive> --resource <model.msh> [--format json] | script inspect <file> [--format json] | prototype inspect --root <path> --key <key> [--format json] | mission graph|inspect --root <path> --mission <path> [--format json]".to_string() } #[cfg(test)] @@ -799,6 +851,16 @@ mod tests { } #[test] + fn script_inspect_json_has_canonical_field_order() { + let package = + fparkan_script::decode(&[73, 0, 0, 0, 0, 0, 0, 0]).expect("minimal script package"); + assert_eq!( + script_inspect_json("script.scr", &package), + Ok("{\"schema_version\":\"fparkan-script-inspect-v1\",\"path\":\"script.scr\",\"opcode_handler_count\":73,\"events\":0,\"instructions\":0,\"references\":0,\"trailing_bytes\":0}".to_string()) + ); + } + + #[test] fn archive_json_has_schema_version() { let json = archive_inspect_json("archive.lib", "NRes", 3, Some(true)) .expect("serialize archive inspection"); |
