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,
43 pub rel_type: String,
44 pub target: String,
45 pub target_mode: String,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
50pub enum ContentType {
51 Default {
52 extension: String,
53 content_type: String,
54 },
55 Override {
56 part_name: String,
57 content_type: String,
58 },
59}
60
61pub fn parse_relationships(xml_content: &[u8]) -> Result<Vec<Relationship>> {
63 let mut reader = Reader::from_reader(xml_content);
64 reader.config_mut().trim_text(true);
65
66 let mut rels = Vec::new();
67 let mut buf = Vec::new();
68
69 loop {
70 match reader.read_event_into(&mut buf) {
71 Ok(Event::Empty(e)) | Ok(Event::Start(e)) => {
72 if e.name().as_ref() == b"Relationship" {
73 let mut id = String::new();
74 let mut rel_type = String::new();
75 let mut target = String::new();
76 let mut target_mode = "Internal".to_string(); for attr in e.attributes() {
79 let attr = attr.map_err(|e| Lib3mfError::Validation(e.to_string()))?;
80 match attr.key.as_ref() {
81 b"Id" => id = String::from_utf8_lossy(&attr.value).to_string(),
82 b"Type" => rel_type = String::from_utf8_lossy(&attr.value).to_string(),
83 b"Target" => target = String::from_utf8_lossy(&attr.value).to_string(),
84 b"TargetMode" => {
85 target_mode = String::from_utf8_lossy(&attr.value).to_string()
86 }
87 _ => {}
88 }
89 }
90 rels.push(Relationship {
91 id,
92 rel_type,
93 target,
94 target_mode,
95 });
96 }
97 }
98 Ok(Event::Eof) => break,
99 Err(e) => return Err(Lib3mfError::Validation(e.to_string())),
100 _ => {}
101 }
102 buf.clear();
103 }
104
105 Ok(rels)
106}
107
108pub fn parse_content_types(xml_content: &[u8]) -> Result<Vec<ContentType>> {
110 let mut reader = Reader::from_reader(xml_content);
111 reader.config_mut().trim_text(true);
112
113 let mut types = Vec::new();
114 let mut buf = Vec::new();
115
116 loop {
117 match reader.read_event_into(&mut buf) {
118 Ok(Event::Empty(e)) | Ok(Event::Start(e)) => match e.name().as_ref() {
119 b"Default" => {
120 let mut extension = String::new();
121 let mut content_type = String::new();
122 for attr in e.attributes() {
123 let attr = attr.map_err(|e| Lib3mfError::Validation(e.to_string()))?;
124 match attr.key.as_ref() {
125 b"Extension" => {
126 extension = String::from_utf8_lossy(&attr.value).to_string()
127 }
128 b"ContentType" => {
129 content_type = String::from_utf8_lossy(&attr.value).to_string()
130 }
131 _ => {}
132 }
133 }
134 types.push(ContentType::Default {
135 extension,
136 content_type,
137 });
138 }
139 b"Override" => {
140 let mut part_name = String::new();
141 let mut content_type = String::new();
142 for attr in e.attributes() {
143 let attr = attr.map_err(|e| Lib3mfError::Validation(e.to_string()))?;
144 match attr.key.as_ref() {
145 b"PartName" => {
146 part_name = String::from_utf8_lossy(&attr.value).to_string()
147 }
148 b"ContentType" => {
149 content_type = String::from_utf8_lossy(&attr.value).to_string()
150 }
151 _ => {}
152 }
153 }
154 types.push(ContentType::Override {
155 part_name,
156 content_type,
157 });
158 }
159 _ => {}
160 },
161 Ok(Event::Eof) => break,
162 Err(e) => return Err(Lib3mfError::Validation(e.to_string())),
163 _ => {}
164 }
165 buf.clear();
166 }
167
168 Ok(types)
169}