Skip to main content

melodium_share/
model_instanciation_design.rs

1use crate::{Attributes, Identifier, SharingError, SharingResult, Value};
2use melodium_common::descriptor::{Collection, Identified, Identifier as CommonIdentifier};
3use melodium_engine::{
4    descriptor::Treatment as DesignedTreatment,
5    design::{ModelInstanciation, Parameter as DesignedParameter},
6    LogicError,
7};
8use serde::{Deserialize, Serialize};
9use std::{
10    collections::{BTreeMap, HashMap},
11    sync::Arc,
12};
13
14#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
15#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
16#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
17pub struct ModelInstanciationDesign {
18    pub identifier: Identifier,
19    pub parameters: BTreeMap<String, Value>,
20    pub attributes: Attributes,
21}
22
23impl ModelInstanciationDesign {
24    pub(crate) fn make_design(
25        &self,
26        collection: &Collection,
27        scope: &Arc<DesignedTreatment>,
28        name: &str,
29    ) -> SharingResult<ModelInstanciation> {
30        let mut result = SharingResult::new_success(());
31
32        let identifier: CommonIdentifier = if let Ok(identifier) = (&self.identifier).try_into() {
33            identifier
34        } else {
35            return SharingResult::new_failure(SharingError::invalid_identifier(
36                16,
37                self.identifier.clone(),
38            ));
39        };
40
41        let model = if let Some(melodium_common::descriptor::Entry::Model(model)) =
42            collection.get(&(&identifier).into())
43        {
44            model
45        } else {
46            return SharingResult::new_failure(
47                LogicError::unexisting_model(
48                    240,
49                    scope.identifier().clone(),
50                    identifier.into(),
51                    None,
52                )
53                .into(),
54            );
55        };
56
57        let mut parameters = HashMap::with_capacity(self.parameters.len());
58
59        for (name, value) in &self.parameters {
60            if let Some(value) =
61                result.merge_degrade_failure(value.to_value(collection, scope.identifier()))
62            {
63                parameters.insert(
64                    name.clone(),
65                    DesignedParameter {
66                        name: name.clone(),
67                        value,
68                    },
69                );
70            }
71        }
72
73        result.and_then(|_| {
74            SharingResult::new_success(ModelInstanciation {
75                descriptor: Arc::downgrade(model),
76                name: name.to_string(),
77                attributes: (&self.attributes).into(),
78                parameters,
79            })
80        })
81    }
82}
83
84impl From<&ModelInstanciation> for ModelInstanciationDesign {
85    fn from(value: &ModelInstanciation) -> Self {
86        Self {
87            identifier: value.descriptor.upgrade().unwrap().identifier().into(),
88            parameters: value
89                .parameters
90                .iter()
91                .map(|(name, param)| (name.clone(), (&param.value).into()))
92                .collect(),
93            attributes: (&value.attributes).into(),
94        }
95    }
96}