Skip to main content

melodium_share/
value.rs

1use crate::{DescribedType, Identifier, SharingError, SharingResult};
2use cbor4ii::core::utils::SliceReader;
3use melodium_common::{
4    descriptor::{Collection, Entry as CommonEntry, Identifier as CommonIdentifier},
5    executive::Value as CommonValue,
6};
7use melodium_engine::{design::Value as DesignedValue, LogicError};
8use serde::{Deserialize, Serialize};
9use std::{
10    collections::{BTreeMap, HashMap},
11    sync::Arc,
12};
13
14#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
15#[serde(rename_all = "snake_case")]
16#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
17#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
18pub enum Value {
19    Raw(RawValue),
20    Array(Vec<Value>),
21    Variable(String),
22    Context(Identifier, String),
23    Function(Identifier, BTreeMap<String, DescribedType>, Vec<Value>),
24}
25
26impl Value {
27    pub fn to_value(
28        &self,
29        collection: &Collection,
30        scope: &CommonIdentifier,
31    ) -> SharingResult<DesignedValue> {
32        match self {
33            Value::Raw(val) => {
34                if let Some(value) = val.to_value(collection) {
35                    SharingResult::new_success(DesignedValue::Raw(value))
36                } else {
37                    SharingResult::new_failure(SharingError::data_serialization_error(8))
38                }
39            }
40            Value::Array(arr) => {
41                let mut result = SharingResult::new_success(());
42                let mut vec = Vec::with_capacity(arr.len());
43                for val in arr {
44                    if let Some(val) = result.merge_degrade_failure(val.to_value(collection, scope))
45                    {
46                        vec.push(val);
47                    }
48                }
49                result.and_then(|_| SharingResult::new_success(DesignedValue::Array(vec)))
50            }
51            Value::Variable(var) => {
52                SharingResult::new_success(DesignedValue::Variable(var.clone()))
53            }
54            Value::Context(context, name) => {
55                let context: CommonIdentifier = if let Ok(identifier) = context.try_into() {
56                    identifier
57                } else {
58                    return SharingResult::new_failure(SharingError::invalid_identifier(
59                        9,
60                        context.clone(),
61                    ));
62                };
63                if let Some(CommonEntry::Context(context)) = collection.get(&(&context).into()) {
64                    SharingResult::new_success(DesignedValue::Context(
65                        Arc::clone(context),
66                        name.clone(),
67                    ))
68                } else {
69                    SharingResult::new_failure(
70                        LogicError::unexisting_context(232, scope.clone(), context.into(), None)
71                            .into(),
72                    )
73                }
74            }
75            Value::Function(function, generics, parameters) => {
76                let function: CommonIdentifier = if let Ok(identifier) = function.try_into() {
77                    identifier
78                } else {
79                    return SharingResult::new_failure(SharingError::invalid_identifier(
80                        10,
81                        function.clone(),
82                    ));
83                };
84                if let Some(CommonEntry::Function(function)) = collection.get(&(&function).into()) {
85                    let mut result = SharingResult::new_success(());
86
87                    let mut map_generics = HashMap::with_capacity(generics.len());
88                    for (name, gen) in generics {
89                        if let Some(gen) =
90                            result.merge_degrade_failure(gen.to_described_type(collection, scope))
91                        {
92                            map_generics.insert(name.clone(), gen);
93                        }
94                    }
95
96                    let mut vec_params = Vec::with_capacity(parameters.len());
97                    for param in parameters {
98                        if let Some(val) =
99                            result.merge_degrade_failure(param.to_value(collection, scope))
100                        {
101                            vec_params.push(val);
102                        }
103                    }
104
105                    result.and_then(|_| {
106                        SharingResult::new_success(DesignedValue::Function(
107                            Arc::clone(function),
108                            map_generics,
109                            vec_params,
110                        ))
111                    })
112                } else {
113                    SharingResult::new_failure(
114                        LogicError::unexisting_function(233, scope.clone(), function.into(), None)
115                            .into(),
116                    )
117                }
118            }
119        }
120    }
121}
122
123impl From<&DesignedValue> for Value {
124    fn from(value: &DesignedValue) -> Self {
125        match value {
126            DesignedValue::Raw(val) => Value::Raw(val.into()),
127            DesignedValue::Array(arr) => Value::Array(arr.iter().map(|v| v.into()).collect()),
128            DesignedValue::Variable(var) => Value::Variable(var.clone()),
129            DesignedValue::Context(context, name) => {
130                Value::Context(context.identifier().into(), name.clone())
131            }
132            DesignedValue::Function(function, generics, params) => Value::Function(
133                function.identifier().into(),
134                generics
135                    .iter()
136                    .map(|(name, dt)| (name.clone(), dt.into()))
137                    .collect(),
138                params.iter().map(|p| p.into()).collect(),
139            ),
140        }
141    }
142}
143
144#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
145#[serde(rename_all = "snake_case")]
146#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
147#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
148pub enum RawValue {
149    Void(()),
150
151    I8(i8),
152    I16(i16),
153    I32(i32),
154    I64(i64),
155    I128(i128),
156
157    U8(u8),
158    U16(u16),
159    U32(u32),
160    U64(u64),
161    U128(u128),
162
163    F32(f32),
164    F64(f64),
165
166    Bool(bool),
167    Byte(u8),
168    Char(char),
169    String(String),
170
171    Vec(Vec<RawValue>),
172    Option(Option<Box<RawValue>>),
173
174    Data(Identifier, Option<Vec<u8>>),
175}
176
177impl RawValue {
178    pub fn to_value(&self, collection: &Collection) -> Option<CommonValue> {
179        match self {
180            RawValue::Data(identifier, value) => {
181                if let Ok(identifier) =
182                    <&Identifier as TryInto<CommonIdentifier>>::try_into(identifier)
183                {
184                    match (collection.get(&(&identifier).into()), value) {
185                        (Some(CommonEntry::Data(data)), Some(value)) => {
186                            let slice_reader = SliceReader::new(value.as_slice());
187
188                            let mut deserializer_cbor =
189                                cbor4ii::serde::Deserializer::new(slice_reader);
190                            let mut erased_deserializer = Box::new(
191                                <dyn erased_serde::Deserializer>::erase(&mut deserializer_cbor),
192                            );
193
194                            data.deserialize(&mut erased_deserializer).ok()
195                        }
196                        _ => None,
197                    }
198                } else {
199                    None
200                }
201            }
202            RawValue::Vec(v) => Some({
203                let mut vec = Vec::with_capacity(v.len());
204                for val in v {
205                    vec.push(val.to_value(collection)?);
206                }
207                CommonValue::Vec(vec)
208            }),
209            RawValue::Option(option) => Some(match option {
210                None => CommonValue::Option(None),
211                Some(value) => CommonValue::Option(Some(Box::new(value.to_value(collection)?))),
212            }),
213            other => other.try_into().ok(),
214        }
215    }
216}
217
218impl From<CommonValue> for RawValue {
219    fn from(value: CommonValue) -> Self {
220        match value {
221            CommonValue::Void(_) => RawValue::Void(()),
222            CommonValue::I8(n) => RawValue::I8(n),
223            CommonValue::I16(n) => RawValue::I16(n),
224            CommonValue::I32(n) => RawValue::I32(n),
225            CommonValue::I64(n) => RawValue::I64(n),
226            CommonValue::I128(n) => RawValue::I128(n),
227            CommonValue::U8(n) => RawValue::U8(n),
228            CommonValue::U16(n) => RawValue::U16(n),
229            CommonValue::U32(n) => RawValue::U32(n),
230            CommonValue::U64(n) => RawValue::U64(n),
231            CommonValue::U128(n) => RawValue::U128(n),
232            CommonValue::F32(n) => RawValue::F32(n),
233            CommonValue::F64(n) => RawValue::F64(n),
234            CommonValue::Bool(b) => RawValue::Bool(b),
235            CommonValue::Byte(b) => RawValue::Byte(b),
236            CommonValue::Char(c) => RawValue::Char(c),
237            CommonValue::String(s) => RawValue::String(s),
238            CommonValue::Vec(v) => RawValue::Vec(v.into_iter().map(|v| v.into()).collect()),
239            CommonValue::Option(v) => RawValue::Option(v.map(|v| Box::new((*v).into()))),
240            CommonValue::Data(d) => {
241                let data = cbor4ii::serde::to_vec(Vec::new(), &d).ok();
242                RawValue::Data(d.descriptor().identifier().into(), data)
243            }
244        }
245    }
246}
247
248impl From<&CommonValue> for RawValue {
249    fn from(value: &CommonValue) -> Self {
250        match value {
251            CommonValue::Void(_) => RawValue::Void(()),
252            CommonValue::I8(n) => RawValue::I8(*n),
253            CommonValue::I16(n) => RawValue::I16(*n),
254            CommonValue::I32(n) => RawValue::I32(*n),
255            CommonValue::I64(n) => RawValue::I64(*n),
256            CommonValue::I128(n) => RawValue::I128(*n),
257            CommonValue::U8(n) => RawValue::U8(*n),
258            CommonValue::U16(n) => RawValue::U16(*n),
259            CommonValue::U32(n) => RawValue::U32(*n),
260            CommonValue::U64(n) => RawValue::U64(*n),
261            CommonValue::U128(n) => RawValue::U128(*n),
262            CommonValue::F32(n) => RawValue::F32(*n),
263            CommonValue::F64(n) => RawValue::F64(*n),
264            CommonValue::Bool(b) => RawValue::Bool(*b),
265            CommonValue::Byte(b) => RawValue::Byte(*b),
266            CommonValue::Char(c) => RawValue::Char(*c),
267            CommonValue::String(s) => RawValue::String(s.clone()),
268            CommonValue::Vec(v) => RawValue::Vec(v.into_iter().map(|v| v.into()).collect()),
269            CommonValue::Option(v) => {
270                RawValue::Option(v.as_ref().map(|v| Box::new(v.as_ref().into())))
271            }
272            CommonValue::Data(d) => {
273                let data = cbor4ii::serde::to_vec(Vec::new(), &d).ok();
274                RawValue::Data(d.descriptor().identifier().into(), data)
275            }
276        }
277    }
278}
279
280impl TryInto<CommonValue> for RawValue {
281    type Error = ();
282
283    fn try_into(self) -> Result<CommonValue, Self::Error> {
284        (&self).try_into()
285    }
286}
287
288impl TryInto<CommonValue> for &RawValue {
289    type Error = ();
290
291    fn try_into(self) -> Result<CommonValue, Self::Error> {
292        match self {
293            RawValue::Void(_) => Ok(CommonValue::Void(())),
294            RawValue::I8(n) => Ok(CommonValue::I8(*n)),
295            RawValue::I16(n) => Ok(CommonValue::I16(*n)),
296            RawValue::I32(n) => Ok(CommonValue::I32(*n)),
297            RawValue::I64(n) => Ok(CommonValue::I64(*n)),
298            RawValue::I128(n) => Ok(CommonValue::I128(*n)),
299            RawValue::U8(n) => Ok(CommonValue::U8(*n)),
300            RawValue::U16(n) => Ok(CommonValue::U16(*n)),
301            RawValue::U32(n) => Ok(CommonValue::U32(*n)),
302            RawValue::U64(n) => Ok(CommonValue::U64(*n)),
303            RawValue::U128(n) => Ok(CommonValue::U128(*n)),
304            RawValue::F32(n) => Ok(CommonValue::F32(*n)),
305            RawValue::F64(n) => Ok(CommonValue::F64(*n)),
306            RawValue::Bool(b) => Ok(CommonValue::Bool(*b)),
307            RawValue::Byte(b) => Ok(CommonValue::Byte(*b)),
308            RawValue::Char(c) => Ok(CommonValue::Char(*c)),
309            RawValue::String(s) => Ok(CommonValue::String(s.clone())),
310            RawValue::Vec(v) => Ok({
311                let mut vec = Vec::with_capacity(v.len());
312                for val in v {
313                    vec.push(val.try_into()?);
314                }
315                CommonValue::Vec(vec)
316            }),
317            RawValue::Option(v) => {
318                if let Some(val) = v {
319                    Ok(CommonValue::Option(Some(Box::new(
320                        val.as_ref().try_into()?,
321                    ))))
322                } else {
323                    Ok(CommonValue::Option(None))
324                }
325            }
326            RawValue::Data(_, _) => Err(()),
327        }
328    }
329}