Skip to main content

config_disassembler/
xml_cmd.rs

1//! `xml` subcommand: thin wrapper around the in-tree XML disassembler CLI.
2//!
3//! All arguments after `config-disassembler xml` are forwarded directly to
4//! [`crate::xml::cli::run`], so every option from the original
5//! `xml-disassembler` crate works unchanged here. This subcommand
6//! intentionally does not duplicate any of the XML logic — it simply
7//! delegates to the in-tree port.
8
9use crate::error::{Error, Result};
10
11/// Run the in-tree XML disassembler CLI with the provided arguments.
12///
13/// `args` should be the trailing arguments after `config-disassembler xml`,
14/// e.g. `["disassemble", "path/to/file.xml", "--format", "json"]`.
15pub async fn run(args: Vec<String>) -> Result<()> {
16    let mut forwarded = Vec::with_capacity(args.len() + 1);
17    forwarded.push("xml-disassembler".to_string());
18    forwarded.extend(args);
19
20    crate::xml::cli::run(forwarded)
21        .await
22        .map_err(|e| Error::Xml(e.to_string()))
23}
24
25#[cfg(test)]
26mod tests {
27    use super::*;
28
29    #[tokio::test]
30    async fn run_forwards_args_and_succeeds_for_valid_disassemble() {
31        // Round-trip through the public entry point so a regression that
32        // short-circuits this function to `Ok(())` without actually invoking
33        // the in-tree XML CLI would be caught: the assertion below depends on
34        // files written by the underlying disassembler.
35        let tmp = tempfile::tempdir().unwrap();
36        let xml_path = tmp.path().join("sample.xml");
37        std::fs::write(
38            &xml_path,
39            r#"<?xml version="1.0" encoding="UTF-8"?>
40<Root xmlns="http://example.com">
41  <child><name>one</name></child>
42  <child><name>two</name></child>
43</Root>"#,
44        )
45        .unwrap();
46        run(vec![
47            "disassemble".to_string(),
48            xml_path.to_string_lossy().to_string(),
49        ])
50        .await
51        .unwrap();
52        assert!(tmp.path().join("sample").exists());
53    }
54
55    #[tokio::test]
56    async fn run_propagates_unknown_subcommand_as_ok() {
57        // The underlying CLI treats unknown subcommands as a non-error
58        // (prints a message and returns Ok). Asserting it explicitly here
59        // pins down the no-op shim behavior.
60        run(vec!["definitely-not-a-real-subcommand".to_string()])
61            .await
62            .unwrap();
63    }
64}