ursus_materials/
requirements.rs1use crate::error::MaterialError;
2use crate::material::Material;
3use crate::value::{MaterialValue, PropertyId};
4
5#[derive(Debug, Default, Clone)]
9pub struct Requirements {
10 pub required: Vec<PropertyId>,
11 pub optional_with_defaults: Vec<(PropertyId, MaterialValue)>,
12}
13
14impl Requirements {
15 pub fn new() -> Self {
16 Self::default()
17 }
18
19 pub fn require(mut self, id: PropertyId) -> Self {
20 self.required.push(id);
21 self
22 }
23
24 pub fn optional(mut self, id: PropertyId, default: MaterialValue) -> Self {
25 self.optional_with_defaults.push((id, default));
26 self
27 }
28
29 pub fn validate(&self, material: &Material, strategy_name: &'static str) -> Result<(), MaterialError> {
33 for &id in &self.required {
34 if !material.contains(id) {
35 return Err(MaterialError::MissingProperty {
36 material: material.name.clone(),
37 strategy: strategy_name,
38 property: id,
39 });
40 }
41 }
42 Ok(())
43 }
44
45 pub fn get_or_default<'a>(&'a self, material: &'a Material, id: PropertyId) -> Option<&'a MaterialValue> {
49 material
50 .get(id)
51 .or_else(|| self.optional_with_defaults.iter().find(|(pid, _)| *pid == id).map(|(_, default)| default))
52 }
53}