lib3mf_core/archive/
opc.rs1use crate::error::{Lib3mfError, Result};
2use quick_xml::events::Event;
3use quick_xml::reader::Reader;
4use serde::{Deserialize, Serialize};
5
6pub mod bambu_rel_types {
19 pub const COVER_THUMBNAIL_MIDDLE: &str =
24 "http://schemas.bambulab.com/package/2021/cover-thumbnail-middle";
25
26 pub const COVER_THUMBNAIL_SMALL: &str =
30 "http://schemas.bambulab.com/package/2021/cover-thumbnail-small";
31
32 pub const GCODE: &str = "http://schemas.bambulab.com/package/2021/gcode";
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct Relationship {
42 pub id: String,
44 pub rel_type: String,
46 pub target: String,
48 pub target_mode: String,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
54pub enum ContentType {
55 Default {
57 extension: String,
59 content_type: String,
61 },
62 Override {
64 part_name: String,
66 content_type: String,
68 },
69}
70
71pub fn parse_relationships(xml_content: &[u8]) -> Result<Vec<Relationship>> {
73 let mut reader = Reader::from_reader(xml_content);
74 reader.config_mut().trim_text(true);
75
76 let mut rels = Vec::new();
77 let mut buf = Vec::new();
78
79 loop {
80 match reader.read_event_into(&mut buf) {
81 Ok(Event::Empty(e)) | Ok(Event::Start(e)) => {
82 if e.name().as_ref() == b"Relationship" {
83 let mut id = String::new();
84 let mut rel_type = String::new();
85 let mut target = String::new();
86 let mut target_mode = "Internal".to_string(); for attr in e.attributes() {
89 let attr = attr.map_err(|e| Lib3mfError::Validation(e.to_string()))?;
90 match attr.key.as_ref() {
91 b"Id" => id = String::from_utf8_lossy(&attr.value).to_string(),
92 b"Type" => rel_type = String::from_utf8_lossy(&attr.value).to_string(),
93 b"Target" => target = String::from_utf8_lossy(&attr.value).to_string(),
94 b"TargetMode" => {
95 target_mode = String::from_utf8_lossy(&attr.value).to_string()
96 }
97 _ => {}
98 }
99 }
100 rels.push(Relationship {
101 id,
102 rel_type,
103 target,
104 target_mode,
105 });
106 }
107 }
108 Ok(Event::Eof) => break,
109 Err(e) => return Err(Lib3mfError::Validation(e.to_string())),
110 _ => {}
111 }
112 buf.clear();
113 }
114
115 Ok(rels)
116}
117
118pub fn parse_content_types(xml_content: &[u8]) -> Result<Vec<ContentType>> {
120 let mut reader = Reader::from_reader(xml_content);
121 reader.config_mut().trim_text(true);
122
123 let mut types = Vec::new();
124 let mut buf = Vec::new();
125
126 loop {
127 match reader.read_event_into(&mut buf) {
128 Ok(Event::Empty(e)) | Ok(Event::Start(e)) => match e.name().as_ref() {
129 b"Default" => {
130 let mut extension = String::new();
131 let mut content_type = String::new();
132 for attr in e.attributes() {
133 let attr = attr.map_err(|e| Lib3mfError::Validation(e.to_string()))?;
134 match attr.key.as_ref() {
135 b"Extension" => {
136 extension = String::from_utf8_lossy(&attr.value).to_string()
137 }
138 b"ContentType" => {
139 content_type = String::from_utf8_lossy(&attr.value).to_string()
140 }
141 _ => {}
142 }
143 }
144 types.push(ContentType::Default {
145 extension,
146 content_type,
147 });
148 }
149 b"Override" => {
150 let mut part_name = String::new();
151 let mut content_type = String::new();
152 for attr in e.attributes() {
153 let attr = attr.map_err(|e| Lib3mfError::Validation(e.to_string()))?;
154 match attr.key.as_ref() {
155 b"PartName" => {
156 part_name = String::from_utf8_lossy(&attr.value).to_string()
157 }
158 b"ContentType" => {
159 content_type = String::from_utf8_lossy(&attr.value).to_string()
160 }
161 _ => {}
162 }
163 }
164 types.push(ContentType::Override {
165 part_name,
166 content_type,
167 });
168 }
169 _ => {}
170 },
171 Ok(Event::Eof) => break,
172 Err(e) => return Err(Lib3mfError::Validation(e.to_string())),
173 _ => {}
174 }
175 buf.clear();
176 }
177
178 Ok(types)
179}