1use crate::error::{Lib3mfError, Result};
2use crate::model::{
3 BaseMaterialsGroup, ColorGroup, CompositeMaterials, Displacement2D, KeyStore, MultiProperties,
4 Object, SliceStack, Texture2D, Texture2DGroup, VolumetricStack,
5};
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
25pub struct ResourceId(pub u32);
26
27#[derive(Debug, Clone, Default, Serialize, Deserialize)]
60pub struct ResourceCollection {
61 objects: HashMap<ResourceId, Object>,
62 base_materials: HashMap<ResourceId, BaseMaterialsGroup>,
63 color_groups: HashMap<ResourceId, ColorGroup>,
64 slice_stacks: HashMap<ResourceId, SliceStack>,
65 volumetric_stacks: HashMap<ResourceId, VolumetricStack>,
66 texture_2d: HashMap<ResourceId, Texture2D>,
67 texture_2d_groups: HashMap<ResourceId, Texture2DGroup>,
68 composite_materials: HashMap<ResourceId, CompositeMaterials>,
69 multi_properties: HashMap<ResourceId, MultiProperties>,
70 displacement_2d: HashMap<ResourceId, Displacement2D>,
71 pub key_store: Option<KeyStore>, }
73
74impl ResourceCollection {
75 pub fn new() -> Self {
77 Self::default()
78 }
79
80 pub fn exists(&self, id: ResourceId) -> bool {
84 self.objects.contains_key(&id)
85 || self.base_materials.contains_key(&id)
86 || self.color_groups.contains_key(&id)
87 || self.slice_stacks.contains_key(&id)
88 || self.volumetric_stacks.contains_key(&id)
89 || self.texture_2d.contains_key(&id)
90 || self.texture_2d_groups.contains_key(&id)
91 || self.composite_materials.contains_key(&id)
92 || self.multi_properties.contains_key(&id)
93 || self.displacement_2d.contains_key(&id)
94 }
95
96 pub fn add_object(&mut self, object: Object) -> Result<()> {
102 if self.exists(object.id) {
103 return Err(Lib3mfError::Validation(format!(
104 "Duplicate resource ID: {}",
105 object.id.0
106 )));
107 }
108 self.objects.insert(object.id, object);
109 Ok(())
110 }
111
112 pub fn add_base_materials(&mut self, group: BaseMaterialsGroup) -> Result<()> {
118 if self.exists(group.id) {
119 return Err(Lib3mfError::Validation(format!(
120 "Duplicate resource ID: {}",
121 group.id.0
122 )));
123 }
124 self.base_materials.insert(group.id, group);
125 Ok(())
126 }
127
128 pub fn add_color_group(&mut self, group: ColorGroup) -> Result<()> {
134 if self.exists(group.id) {
135 return Err(Lib3mfError::Validation(format!(
136 "Duplicate resource ID: {}",
137 group.id.0
138 )));
139 }
140 self.color_groups.insert(group.id, group);
141 Ok(())
142 }
143
144 pub fn add_slice_stack(&mut self, stack: SliceStack) -> Result<()> {
145 if self.exists(stack.id) {
146 return Err(Lib3mfError::Validation(format!(
147 "Duplicate resource ID: {}",
148 stack.id.0
149 )));
150 }
151 self.slice_stacks.insert(stack.id, stack);
152 Ok(())
153 }
154
155 pub fn add_volumetric_stack(&mut self, stack: VolumetricStack) -> Result<()> {
156 if self.exists(stack.id) {
157 return Err(Lib3mfError::Validation(format!(
158 "Duplicate resource ID: {}",
159 stack.id.0
160 )));
161 }
162 self.volumetric_stacks.insert(stack.id, stack);
163 Ok(())
164 }
165
166 pub fn set_key_store(&mut self, store: KeyStore) {
167 self.key_store = Some(store);
168 }
169
170 pub fn get_object(&self, id: ResourceId) -> Option<&Object> {
174 self.objects.get(&id)
175 }
176
177 pub fn get_base_materials(&self, id: ResourceId) -> Option<&BaseMaterialsGroup> {
181 self.base_materials.get(&id)
182 }
183
184 pub fn get_color_group(&self, id: ResourceId) -> Option<&ColorGroup> {
188 self.color_groups.get(&id)
189 }
190
191 pub fn get_slice_stack(&self, id: ResourceId) -> Option<&SliceStack> {
192 self.slice_stacks.get(&id)
193 }
194
195 pub fn get_volumetric_stack(&self, id: ResourceId) -> Option<&VolumetricStack> {
196 self.volumetric_stacks.get(&id)
197 }
198
199 pub fn add_texture_2d(&mut self, texture: Texture2D) -> Result<()> {
200 if self.exists(texture.id) {
201 return Err(Lib3mfError::Validation(format!(
202 "Duplicate resource ID: {}",
203 texture.id.0
204 )));
205 }
206 self.texture_2d.insert(texture.id, texture);
207 Ok(())
208 }
209
210 pub fn add_texture_2d_group(&mut self, group: Texture2DGroup) -> Result<()> {
211 if self.exists(group.id) {
212 return Err(Lib3mfError::Validation(format!(
213 "Duplicate resource ID: {}",
214 group.id.0
215 )));
216 }
217 self.texture_2d_groups.insert(group.id, group);
218 Ok(())
219 }
220
221 pub fn get_texture_2d_group(&self, id: ResourceId) -> Option<&Texture2DGroup> {
222 self.texture_2d_groups.get(&id)
223 }
224
225 pub fn add_composite_materials(&mut self, group: CompositeMaterials) -> Result<()> {
226 if self.exists(group.id) {
227 return Err(Lib3mfError::Validation(format!(
228 "Duplicate resource ID: {}",
229 group.id.0
230 )));
231 }
232 self.composite_materials.insert(group.id, group);
233 Ok(())
234 }
235
236 pub fn get_composite_materials(&self, id: ResourceId) -> Option<&CompositeMaterials> {
237 self.composite_materials.get(&id)
238 }
239
240 pub fn add_multi_properties(&mut self, group: MultiProperties) -> Result<()> {
241 if self.exists(group.id) {
242 return Err(Lib3mfError::Validation(format!(
243 "Duplicate resource ID: {}",
244 group.id.0
245 )));
246 }
247 self.multi_properties.insert(group.id, group);
248 Ok(())
249 }
250
251 pub fn get_multi_properties(&self, id: ResourceId) -> Option<&MultiProperties> {
252 self.multi_properties.get(&id)
253 }
254
255 pub fn base_material_groups_count(&self) -> usize {
256 self.base_materials.len()
257 }
258
259 pub fn color_groups_count(&self) -> usize {
260 self.color_groups.len()
261 }
262
263 pub fn volumetric_stacks_count(&self) -> usize {
264 self.volumetric_stacks.len()
265 }
266
267 pub fn texture_2d_groups_count(&self) -> usize {
268 self.texture_2d_groups.len()
269 }
270
271 pub fn composite_materials_count(&self) -> usize {
272 self.composite_materials.len()
273 }
274
275 pub fn multi_properties_count(&self) -> usize {
276 self.multi_properties.len()
277 }
278
279 pub fn iter_objects(&self) -> impl Iterator<Item = &Object> {
281 self.objects.values()
282 }
283
284 pub fn iter_objects_mut(&mut self) -> impl Iterator<Item = &mut Object> {
286 self.objects.values_mut()
287 }
288
289 pub fn iter_base_materials(&self) -> impl Iterator<Item = &BaseMaterialsGroup> {
291 self.base_materials.values()
292 }
293
294 pub fn iter_color_groups(&self) -> impl Iterator<Item = &ColorGroup> {
296 self.color_groups.values()
297 }
298
299 pub fn iter_textures(&self) -> impl Iterator<Item = &Texture2DGroup> {
301 self.texture_2d_groups.values()
302 }
303
304 pub fn iter_composite_materials(&self) -> impl Iterator<Item = &CompositeMaterials> {
306 self.composite_materials.values()
307 }
308
309 pub fn iter_multi_properties(&self) -> impl Iterator<Item = &MultiProperties> {
311 self.multi_properties.values()
312 }
313
314 pub fn add_displacement_2d(&mut self, res: Displacement2D) -> Result<()> {
315 if self.exists(res.id) {
316 return Err(Lib3mfError::Validation(format!(
317 "Duplicate resource ID: {}",
318 res.id.0
319 )));
320 }
321 self.displacement_2d.insert(res.id, res);
322 Ok(())
323 }
324
325 pub fn get_displacement_2d(&self, id: ResourceId) -> Option<&Displacement2D> {
326 self.displacement_2d.get(&id)
327 }
328
329 pub fn displacement_2d_count(&self) -> usize {
330 self.displacement_2d.len()
331 }
332
333 pub fn iter_displacement_2d(&self) -> impl Iterator<Item = &Displacement2D> {
334 self.displacement_2d.values()
335 }
336}