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}