1use crate::identifiers::GroupIDChanger;
6
7use super::{data::MaterialData, Material};
8
9#[derive(Debug, PartialEq, Clone)]
33pub struct MaterialDescriptor {
34 name: Option<String>,
35 data: MaterialData,
36}
37
38impl MaterialDescriptor {
39 pub fn new_color(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
51 MaterialDescriptor {
52 name: None,
53 data: MaterialData::Color(red, green, blue, alpha),
54 }
55 }
56
57 pub fn new_rgb(red: f32, green: f32, blue: f32) -> Self {
69 MaterialDescriptor {
70 name: None,
71 data: MaterialData::Color(red, green, blue, 1.),
72 }
73 }
74
75 pub fn new_texture(texture_path: impl Into<String>) -> Self {
87 MaterialDescriptor {
88 name: None,
89 data: MaterialData::Texture(texture_path.into()),
90 }
91 }
92
93 pub(crate) fn new_data(data: MaterialData) -> Self {
95 MaterialDescriptor { name: None, data }
96 }
97
98 pub fn named(mut self, name: impl Into<String>) -> Self {
112 self.name = Some(name.into());
113 self
114 }
115
116 pub(crate) fn build(self) -> Material {
118 match self.name {
119 Some(name) => Material::new_named_uninited(name, self.data),
120 None => Material::new_unnamed(self.data),
121 }
122 }
123}
124
125impl MaterialDescriptor {
127 pub fn name(&self) -> Option<&String> {
129 self.name.as_ref()
130 }
131
132 pub fn data(&self) -> &MaterialData {
134 &self.data
135 }
136}
137
138impl GroupIDChanger for MaterialDescriptor {
139 unsafe fn change_group_id_unchecked(&mut self, new_group_id: &str) {
140 if let Some(name) = self.name.as_mut() {
141 name.change_group_id_unchecked(new_group_id);
142 }
143 }
144
145 fn apply_group_id(&mut self) {
146 if let Some(name) = self.name.as_mut() {
147 name.apply_group_id();
148 }
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::MaterialDescriptor;
155 use test_log::test;
156
157 mod group_id_changer {
158 use super::{test, MaterialDescriptor};
159 use crate::identifiers::{GroupIDChanger, GroupIDError};
160
161 #[inline]
162 fn test_change_group_id_unchecked(
163 material_builder: MaterialDescriptor,
164 new_group_id: &str,
165 final_name: Option<&str>,
166 ) {
167 let mut material_builder = material_builder;
168 unsafe {
169 material_builder.change_group_id_unchecked(new_group_id);
170 }
171 assert_eq!(
172 material_builder.name,
173 final_name.and_then(|final_name| Some(final_name.to_owned()))
174 )
175 }
176
177 #[test]
178 fn change_group_id_unchecked_no_name() {
179 test_change_group_id_unchecked(
181 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.),
182 "R04",
183 None,
184 );
185 test_change_group_id_unchecked(MaterialDescriptor::new_rgb(1., 1., 0.), "C064w", None);
186 test_change_group_id_unchecked(
187 MaterialDescriptor::new_texture("package://some/texture/path/text.texture"),
188 "Yellow",
189 None,
190 );
191
192 test_change_group_id_unchecked(
194 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.),
195 "[[R04",
196 None,
197 );
198 test_change_group_id_unchecked(
199 MaterialDescriptor::new_rgb(1., 1., 0.),
200 "C064w]]",
201 None,
202 );
203 test_change_group_id_unchecked(
204 MaterialDescriptor::new_texture("package://some/texture/path/text.texture"),
205 "",
206 None,
207 );
208 }
209
210 #[test]
211 fn change_group_id_unchecked_with_name() {
212 test_change_group_id_unchecked(
214 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.).named("Leg_[[L01]]_mat"),
215 "R04",
216 Some("Leg_[[R04]]_mat"),
217 );
218 test_change_group_id_unchecked(
219 MaterialDescriptor::new_rgb(1., 1., 0.).named("rgb_[[dsd]]_dsdadavj,hnmn b v"),
220 "C064w",
221 Some("rgb_[[C064w]]_dsdadavj,hnmn b v"),
222 );
223 test_change_group_id_unchecked(
224 MaterialDescriptor::new_texture("package://some/texture/path/text.texture")
225 .named("SomeCoolTexture[[GroupID]]"),
226 "Yellow",
227 Some("SomeCoolTexture[[Yellow]]"),
228 );
229
230 test_change_group_id_unchecked(
232 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.).named("Leg_[[L01]]_mat"),
233 "[[R04",
234 Some("Leg_[[[[R04]]_mat"),
235 );
236 test_change_group_id_unchecked(
237 MaterialDescriptor::new_rgb(1., 1., 0.).named("[[CADcs]]SomeColor"),
238 "C064w]]",
239 Some("[[C064w]]]]SomeColor"),
240 );
241 test_change_group_id_unchecked(
242 MaterialDescriptor::new_texture("package://some/texture/path/text.texture")
243 .named("SomeCoolTexture[[GroupID]]"),
244 "",
245 Some("SomeCoolTexture[[]]"),
246 );
247 test_change_group_id_unchecked(
249 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.).named("Leg_L01_mat"),
250 "R04",
251 Some("Leg_L01_mat"),
252 );
253 test_change_group_id_unchecked(
254 MaterialDescriptor::new_rgb(1., 1., 0.).named("rgb_[\\[dsd]\\]_dsdadavj,hnmn b v"),
255 "C064w",
256 Some("rgb_[\\[dsd]\\]_dsdadavj,hnmn b v"),
257 );
258 test_change_group_id_unchecked(
259 MaterialDescriptor::new_texture("package://some/texture/path/text.texture")
260 .named("SomeCoolTexture[\\[GroupID]]"),
261 "Yellow",
262 Some("SomeCoolTexture[\\[GroupID]]"),
263 );
264
265 test_change_group_id_unchecked(
267 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.).named("Leg_L01_mat"),
268 "[[R04",
269 Some("Leg_L01_mat"),
270 );
271 test_change_group_id_unchecked(
272 MaterialDescriptor::new_rgb(1., 1., 0.).named("[[CADcs]\\]SomeColor"),
273 "C064w]]",
274 Some("[[CADcs]\\]SomeColor"),
275 );
276 test_change_group_id_unchecked(
277 MaterialDescriptor::new_texture("package://some/texture/path/text.texture")
278 .named("SomeCoolTexture_GroupID_"),
279 "",
280 Some("SomeCoolTexture_GroupID_"),
281 );
282 }
283
284 #[inline]
285 fn test_change_group_id(
286 material_builder: MaterialDescriptor,
287 new_group_id: &str,
288 change_result: Result<(), GroupIDError>,
289 final_name: Option<&str>,
290 ) {
291 let mut material_builder = material_builder;
292 assert_eq!(
293 material_builder.change_group_id(new_group_id),
294 change_result
295 );
296 assert_eq!(
297 material_builder.name,
298 final_name.and_then(|final_name| Some(final_name.to_owned()))
299 )
300 }
301
302 #[test]
303 fn change_group_id_no_name() {
304 test_change_group_id(
306 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.),
307 "R04",
308 Ok(()),
309 None,
310 );
311 test_change_group_id(
312 MaterialDescriptor::new_rgb(1., 1., 0.),
313 "C064w",
314 Ok(()),
315 None,
316 );
317 test_change_group_id(
318 MaterialDescriptor::new_texture("package://some/texture/path/text.texture"),
319 "Yellow",
320 Ok(()),
321 None,
322 );
323
324 test_change_group_id(
326 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.),
327 "[[R04",
328 Err(GroupIDError::new_open("[[R04")),
329 None,
330 );
331 test_change_group_id(
332 MaterialDescriptor::new_rgb(1., 1., 0.),
333 "C064w]]",
334 Err(GroupIDError::new_close("C064w]]")),
335 None,
336 );
337 test_change_group_id(
338 MaterialDescriptor::new_texture("package://some/texture/path/text.texture"),
339 "",
340 Err(GroupIDError::new_empty()),
341 None,
342 );
343 }
344
345 #[test]
346 fn change_group_id_with_name() {
347 test_change_group_id(
349 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.).named("Leg_[[L01]]_mat"),
350 "R04",
351 Ok(()),
352 Some("Leg_[[R04]]_mat"),
353 );
354 test_change_group_id(
355 MaterialDescriptor::new_rgb(1., 1., 0.).named("rgb_[[dsd]]_dsdadavj,hnmn b v"),
356 "C064w",
357 Ok(()),
358 Some("rgb_[[C064w]]_dsdadavj,hnmn b v"),
359 );
360 test_change_group_id(
361 MaterialDescriptor::new_texture("package://some/texture/path/text.texture")
362 .named("SomeCoolTexture[[GroupID]]"),
363 "Yellow",
364 Ok(()),
365 Some("SomeCoolTexture[[Yellow]]"),
366 );
367
368 test_change_group_id(
370 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.).named("Leg_[[L01]]_mat"),
371 "[[R04",
372 Err(GroupIDError::new_open("[[R04")),
373 Some("Leg_[[L01]]_mat"),
374 );
375 test_change_group_id(
376 MaterialDescriptor::new_rgb(1., 1., 0.).named("[[CADcs]]SomeColor"),
377 "C064w]]",
378 Err(GroupIDError::new_close("C064w]]")),
379 Some("[[CADcs]]SomeColor"),
380 );
381 test_change_group_id(
382 MaterialDescriptor::new_texture("package://some/texture/path/text.texture")
383 .named("SomeCoolTexture[[GroupID]]"),
384 "",
385 Err(GroupIDError::new_empty()),
386 Some("SomeCoolTexture[[GroupID]]"),
387 );
388 test_change_group_id(
390 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.).named("Leg_L01_mat"),
391 "R04",
392 Ok(()),
393 Some("Leg_L01_mat"),
394 );
395 test_change_group_id(
396 MaterialDescriptor::new_rgb(1., 1., 0.).named("rgb_[\\[dsd]\\]_dsdadavj,hnmn b v"),
397 "C064w",
398 Ok(()),
399 Some("rgb_[\\[dsd]\\]_dsdadavj,hnmn b v"),
400 );
401 test_change_group_id(
402 MaterialDescriptor::new_texture("package://some/texture/path/text.texture")
403 .named("SomeCoolTexture[\\[GroupID]]"),
404 "Yellow",
405 Ok(()),
406 Some("SomeCoolTexture[\\[GroupID]]"),
407 );
408
409 test_change_group_id(
411 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.).named("Leg_L01_mat"),
412 "[[R04",
413 Err(GroupIDError::new_open("[[R04")),
414 Some("Leg_L01_mat"),
415 );
416 test_change_group_id(
417 MaterialDescriptor::new_rgb(1., 1., 0.).named("[[CADcs]\\]SomeColor"),
418 "C064w]]",
419 Err(GroupIDError::new_close("C064w]]")),
420 Some("[[CADcs]\\]SomeColor"),
421 );
422 test_change_group_id(
423 MaterialDescriptor::new_texture("package://some/texture/path/text.texture")
424 .named("SomeCoolTexture_GroupID_"),
425 "",
426 Err(GroupIDError::new_empty()),
427 Some("SomeCoolTexture_GroupID_"),
428 );
429 }
430
431 #[inline]
432 fn test_apply_group_id(material_builder: MaterialDescriptor, final_name: Option<&str>) {
433 let mut material_builder = material_builder;
434 material_builder.apply_group_id();
435 assert_eq!(
436 material_builder.name,
437 final_name.and_then(|final_name| Some(final_name.to_owned()))
438 )
439 }
440
441 #[test]
442 fn apply_group_id_no_name() {
443 test_apply_group_id(MaterialDescriptor::new_color(1., 0.5, 0.25, 0.), None);
444 test_apply_group_id(MaterialDescriptor::new_rgb(1., 1., 0.), None);
445 test_apply_group_id(
446 MaterialDescriptor::new_texture("package://some/texture/path/text.texture"),
447 None,
448 );
449 }
450
451 #[test]
452 fn apply_group_id_with_name() {
453 test_apply_group_id(
455 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.).named("Leg_[[L01]]_mat"),
456 Some("Leg_L01_mat"),
457 );
458 test_apply_group_id(
459 MaterialDescriptor::new_rgb(1., 1., 0.).named("rgb_[[dsd]]_dsdadavj,hnmn b v"),
460 Some("rgb_dsd_dsdadavj,hnmn b v"),
461 );
462 test_apply_group_id(
463 MaterialDescriptor::new_texture("package://some/texture/path/text.texture")
464 .named("SomeCoolTexture[[GroupID]]"),
465 Some("SomeCoolTextureGroupID"),
466 );
467
468 test_apply_group_id(
470 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.).named("Leg_[\\[[[L01]]_mat]\\]"),
471 Some("Leg_[[L01_mat]]"),
472 );
473 test_apply_group_id(
474 MaterialDescriptor::new_rgb(1., 1., 0.)
475 .named("rgb_[[dsd]]_d[\\[sdadavj]\\],hnmn b v"),
476 Some("rgb_dsd_d[[sdadavj]],hnmn b v"),
477 );
478 test_apply_group_id(
479 MaterialDescriptor::new_texture("package://some/texture/path/text.texture")
480 .named("SomeCoolTexture[[Gro[\\[upID]]"),
481 Some("SomeCoolTextureGro[[upID"),
482 );
483
484 test_apply_group_id(
486 MaterialDescriptor::new_rgb(1., 1., 0.)
487 .named("rgb_[[dsd]]_d[[sdadavj]\\],hnmn b v"),
488 Some("rgb_[[dsd]]_d[[sdadavj]\\],hnmn b v"),
489 );
490
491 test_apply_group_id(
493 MaterialDescriptor::new_color(1., 0.5, 0.25, 0.).named("Leg_L01_mat"),
494 Some("Leg_L01_mat"),
495 );
496 test_apply_group_id(
497 MaterialDescriptor::new_rgb(1., 1., 0.).named("rgb_[\\[dsd]\\]_dsdadavj,hnmn b v"),
498 Some("rgb_[[dsd]]_dsdadavj,hnmn b v"),
499 );
500 test_apply_group_id(
501 MaterialDescriptor::new_texture("package://some/texture/path/text.texture")
502 .named("SomeCoolTexture[\\[GroupID"),
503 Some("SomeCoolTexture[[GroupID"),
504 );
505
506 test_apply_group_id(
508 MaterialDescriptor::new_texture("package://some/texture/path/text.texture")
509 .named("SomeCoolTexture[\\[GroupID]]"),
510 Some("SomeCoolTexture[\\[GroupID]]"),
511 );
512 }
513 }
514}