Skip to main content

iced_layout_xml/
lib.rs

1mod attr;
2mod node;
3mod style;
4
5use iced_layout_core::Layout;
6use quick_xml::events::Event;
7use quick_xml::Reader;
8
9use node::parse_node;
10use style::{ParsedStyles, parse_styles};
11
12pub fn parse(xml: &str) -> Layout {
13    let mut reader = Reader::from_str(xml);
14    // Find <layout>
15    loop {
16        match reader.read_event().expect("failed to read XML") {
17            Event::Start(e) if e.name().as_ref() == b"layout" => break,
18            Event::Decl(_) | Event::Text(_) | Event::Comment(_) => continue,
19            other => panic!("expected <layout> root element, found {:?}", other),
20        }
21    }
22
23    let mut styles = ParsedStyles::default();
24    let mut root = None;
25
26    // Parse <styles> and <root> children (order-independent)
27    loop {
28        match reader.read_event().expect("failed to read XML") {
29            Event::Start(e) => match e.name().as_ref() {
30                b"styles" => {
31                    styles = parse_styles(&mut reader);
32                }
33                b"root" => {
34                    root = Some(parse_node(&mut reader));
35                    // consume </root>
36                    loop {
37                        match reader.read_event().expect("failed to read XML") {
38                            Event::End(end) if end.name().as_ref() == b"root" => break,
39                            Event::Text(_) | Event::Comment(_) => continue,
40                            other => panic!("expected </root>, found {:?}", other),
41                        }
42                    }
43                }
44                other => panic!(
45                    "expected <styles> or <root>, found <{}>",
46                    String::from_utf8_lossy(other)
47                ),
48            },
49            Event::Empty(_e) if _e.name().as_ref() == b"styles" => {
50                // empty <styles/> — no styles defined
51            }
52            Event::End(e) if e.name().as_ref() == b"layout" => break,
53            Event::Text(_) | Event::Comment(_) => continue,
54            other => panic!("unexpected event in <layout>: {:?}", other),
55        }
56    }
57
58    Layout {
59        container_styles: styles.container,
60        text_styles: styles.text,
61        button_styles: styles.button,
62        checkbox_styles: styles.checkbox,
63        text_input_styles: styles.text_input,
64        font_defs: styles.font,
65        root: root.expect("<layout> must contain a <root> element"),
66    }
67}