lib3mf_core/parser/
bambu_config.rs

1use crate::error::Result;
2use crate::model::stats::PlateInfo;
3use crate::parser::xml_parser::{XmlParser, get_attribute};
4use quick_xml::events::Event;
5use std::io::Cursor;
6
7pub fn parse_model_settings(content: &[u8]) -> Result<Vec<PlateInfo>> {
8    let mut parser = XmlParser::new(Cursor::new(content));
9    let mut plates = Vec::new();
10
11    loop {
12        match parser.read_next_event()? {
13            Event::Start(e) => {
14                if e.name().as_ref() == b"plate" {
15                    let mut id = 0;
16                    let mut name = None;
17
18                    // The Bambu model_settings.config has <plate> as a container.
19                    // The ID and Name are inside <metadata> tags WITHIN the plate tag.
20                    // Example:
21                    // <plate>
22                    //   <metadata key="plater_id" value="1"/>
23                    //   <metadata key="plater_name" value="Main"/>
24                    // </plate>
25
26                    // We need to parse children of <plate>
27                    loop {
28                        match parser.read_next_event()? {
29                            Event::Empty(child) | Event::Start(child) => {
30                                if child.name().as_ref() == b"metadata" {
31                                    let key = get_attribute(&child, b"key");
32                                    let value = get_attribute(&child, b"value");
33
34                                    if let (Some(k), Some(v)) = (key, value) {
35                                        match k.as_ref() {
36                                            "plater_id" => {
37                                                if let Ok(pid) = v.parse::<u32>() {
38                                                    id = pid;
39                                                }
40                                            }
41                                            "plater_name" => name = Some(v.into_owned()),
42                                            _ => {}
43                                        }
44                                    }
45                                }
46                            }
47                            Event::End(end) if end.name().as_ref() == b"plate" => break,
48                            Event::Eof => break,
49                            _ => {}
50                        }
51                    }
52
53                    if id != 0 {
54                        plates.push(PlateInfo { id, name });
55                    }
56                }
57            }
58            Event::Eof => break,
59            _ => {}
60        }
61    }
62
63    Ok(plates)
64}