• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kaidokert / xacro / 20655392290

02 Jan 2026 09:56AM UTC coverage: 86.036%. First build
20655392290

Pull #10

github

web-flow
Merge bb96cd1da into f43e4ad58
Pull Request #10: Fix namespace output handling

41 of 50 new or added lines in 2 files covered. (82.0%)

992 of 1153 relevant lines covered (86.04%)

64.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.44
/src/processor.rs
1
use crate::{
2
    error::XacroError,
3
    features::{
4
        conditions::ConditionProcessor, includes::IncludeProcessor, loops::LoopProcessor,
5
        macros::MacroProcessor, properties::PropertyProcessor,
6
    },
7
};
8

9
pub struct XacroProcessor {
10
    macros: MacroProcessor,
11
    properties: PropertyProcessor,
12
    conditions: ConditionProcessor,
13
    loops: LoopProcessor,
14
    includes: IncludeProcessor,
15
}
16

17
impl XacroProcessor {
18
    #[allow(clippy::new_without_default)]
19
    pub fn new() -> Self {
6✔
20
        Self {
6✔
21
            includes: IncludeProcessor::new(),
6✔
22
            macros: MacroProcessor::new(),
6✔
23
            properties: PropertyProcessor::new(),
6✔
24
            conditions: ConditionProcessor::new(),
6✔
25
            loops: LoopProcessor::new(),
6✔
26
        }
6✔
27
    }
6✔
28

29
    /// Process xacro content from a file path
30
    pub fn run<P: AsRef<std::path::Path>>(
×
31
        &self,
×
32
        path: P,
×
33
    ) -> Result<String, XacroError> {
×
34
        let xml = XacroProcessor::parse_file(&path)?;
×
NEW
35
        self.run_impl(xml, path.as_ref())
×
NEW
36
    }
×
37

38
    /// Process xacro content from a string
39
    pub fn run_from_string(
6✔
40
        &self,
6✔
41
        content: &str,
6✔
42
    ) -> Result<String, XacroError> {
6✔
43
        let xml = xmltree::Element::parse(content.as_bytes())?;
6✔
44
        // Use current directory as base path for any includes in test content
45
        self.run_impl(xml, std::path::Path::new("."))
6✔
46
    }
6✔
47

48
    /// Internal implementation
49
    fn run_impl(
6✔
50
        &self,
6✔
51
        xml: xmltree::Element,
6✔
52
        base_path: &std::path::Path,
6✔
53
    ) -> Result<String, XacroError> {
6✔
54
        // Process features in order
55
        let xml = self.includes.process(xml, base_path)?;
6✔
56

57
        // The HashMap contains all properties for use by subsequent processors
58
        let (xml, properties) = self.properties.process(xml)?;
6✔
59

60
        // Pass properties to MacroProcessor so macros can reference global properties
61
        let xml = self.macros.process(xml, &properties)?;
6✔
62

63
        // Pass properties to ConditionProcessor for expression evaluation
64
        let xml = self.conditions.process(xml, &properties)?;
3✔
65
        let mut xml = self.loops.process(xml)?;
3✔
66

67
        // Final cleanup: check for unprocessed xacro:* elements and remove xacro namespace
68
        // Does both in a single recursive pass for efficiency
69
        Self::finalize_tree(&mut xml)?;
3✔
70

71
        XacroProcessor::serialize(xml)
3✔
72
    }
6✔
73

74
    fn finalize_tree(element: &mut xmltree::Element) -> Result<(), XacroError> {
20✔
75
        // Check if this element has xacro: prefix (indicates unimplemented feature)
76
        if let Some(ref prefix) = element.prefix {
20✔
77
            if prefix == "xacro" {
1✔
NEW
78
                return Err(XacroError::UnimplementedFeature(format!(
×
NEW
79
                    "<xacro:{}>\n\
×
NEW
80
                         This element was not processed. Either:\n\
×
NEW
81
                         1. The feature is not implemented yet (e.g., xacro:arg, xacro:element)\n\
×
NEW
82
                         2. There's a bug in the processor\n",
×
NEW
83
                    element.name
×
NEW
84
                )));
×
85
            }
1✔
86
        }
19✔
87

88
        // Remove xacro namespace declaration
89
        // Keep all other namespaces (gazebo, ignition, etc.)
90
        if let Some(ref mut ns) = element.namespaces {
20✔
91
            ns.0.remove("xacro");
20✔
92
        }
20✔
93

94
        // Recursively process children
95
        for child in &mut element.children {
39✔
96
            if let Some(child_elem) = child.as_mut_element() {
19✔
97
                Self::finalize_tree(child_elem)?;
17✔
98
            }
2✔
99
        }
100

101
        Ok(())
20✔
102
    }
20✔
103
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc