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}