1use crate::{
2 compiler::{
3 CompileOptions, compile_script, extract_static_value_from_script,
4 },
5 runtime::execution::{ExecutionInput, ExecutionOptions, execute_dxb_sync},
6 values::{
7 core_value::CoreValue,
8 core_values::integer::{integer::Integer, typed_integer::TypedInteger},
9 serde::error::SerializationError,
10 value,
11 value_container::ValueContainer,
12 },
13};
14use serde::de::{DeserializeSeed, EnumAccess, VariantAccess, Visitor};
15use serde::{
16 Deserialize, Deserializer, de::IntoDeserializer, forward_to_deserialize_any,
17};
18use std::path::PathBuf;
19
20#[derive(Clone)]
21pub struct DatexDeserializer {
22 pub value: ValueContainer,
23}
24
25impl<'de> DatexDeserializer {
26 pub fn from_bytes(input: &'de [u8]) -> Result<Self, SerializationError> {
27 let context = ExecutionInput::new_with_dxb_and_options(
28 input,
29 ExecutionOptions { verbose: true },
30 );
31 let value = execute_dxb_sync(context)
32 .unwrap_or_else(|err| {
33 panic!("Execution failed: {err}");
34 })
35 .unwrap();
36 Ok(Self { value })
37 }
38
39 pub fn from_dx_file(path: PathBuf) -> Result<Self, SerializationError> {
40 let input = std::fs::read_to_string(path)
41 .map_err(|err| SerializationError(err.to_string()))?;
42 DatexDeserializer::from_script(&input)
43 }
44 pub fn from_dxb_file(path: PathBuf) -> Result<Self, SerializationError> {
45 let input = std::fs::read(path)
46 .map_err(|err| SerializationError(err.to_string()))?;
47 DatexDeserializer::from_bytes(&input)
48 }
49
50 pub fn from_script(script: &'de str) -> Result<Self, SerializationError> {
51 let (dxb, _) = compile_script(script, CompileOptions::default())
52 .map_err(|err| SerializationError(err.to_string()))?;
53 DatexDeserializer::from_bytes(&dxb)
54 }
55 pub fn from_static_script(
56 script: &'de str,
57 ) -> Result<Self, SerializationError> {
58 let value = extract_static_value_from_script(script)
59 .map_err(|err| SerializationError(err.to_string()))?;
60 if value.is_none() {
61 return Err(SerializationError(
62 "No static value found in script".to_string(),
63 ));
64 }
65 Ok(DatexDeserializer::from_value(value.unwrap()))
66 }
67
68 fn from_value(value: ValueContainer) -> Self {
69 Self { value }
70 }
71}
72impl<'de> IntoDeserializer<'de, SerializationError> for DatexDeserializer {
73 type Deserializer = Self;
74
75 fn into_deserializer(self) -> Self::Deserializer {
76 self
77 }
78}
79impl<'de> Deserializer<'de> for DatexDeserializer {
80 type Error = SerializationError;
81
82 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
83 where
84 V: serde::de::Visitor<'de>,
85 {
86 match self.value {
87 ValueContainer::Value(value::Value { inner, .. }) => match inner {
89 CoreValue::Null => visitor.visit_none(),
90 CoreValue::Bool(b) => visitor.visit_bool(b.0),
91 CoreValue::TypedInteger(i) => match i {
92 TypedInteger::I128(i) => visitor.visit_i128(i),
93 TypedInteger::U128(u) => visitor.visit_u128(u),
94 TypedInteger::I64(i) => visitor.visit_i64(i),
95 TypedInteger::U64(u) => visitor.visit_u64(u),
96 TypedInteger::I32(i) => visitor.visit_i32(i),
97 TypedInteger::U32(u) => visitor.visit_u32(u),
98 TypedInteger::I16(i) => visitor.visit_i16(i),
99 TypedInteger::U16(u) => visitor.visit_u16(u),
100 TypedInteger::I8(i) => visitor.visit_i8(i),
101 TypedInteger::U8(u) => visitor.visit_u8(u),
102 _ => unreachable!(),
103 },
104 CoreValue::Integer(Integer {
105 0: TypedInteger::I128(i),
106 }) => visitor.visit_i128(i),
107 CoreValue::Integer(Integer {
108 0: TypedInteger::U128(u),
109 }) => visitor.visit_u128(u),
110 CoreValue::Integer(Integer {
111 0: TypedInteger::I64(i),
112 }) => visitor.visit_i64(i),
113 CoreValue::Integer(Integer {
114 0: TypedInteger::U64(u),
115 }) => visitor.visit_u64(u),
116 CoreValue::Integer(Integer {
117 0: TypedInteger::I32(i),
118 }) => visitor.visit_i32(i),
119 CoreValue::Integer(Integer {
120 0: TypedInteger::U32(u),
121 }) => visitor.visit_u32(u),
122 CoreValue::Integer(Integer {
123 0: TypedInteger::I16(i),
124 }) => visitor.visit_i16(i),
125 CoreValue::Integer(Integer {
126 0: TypedInteger::U16(u),
127 }) => visitor.visit_u16(u),
128 CoreValue::Integer(Integer {
129 0: TypedInteger::I8(i),
130 }) => visitor.visit_i8(i),
131 CoreValue::Integer(Integer {
132 0: TypedInteger::U8(u),
133 }) => visitor.visit_u8(u),
134 CoreValue::Text(s) => visitor.visit_string(s.0),
135 CoreValue::Endpoint(endpoint) => {
136 let endpoint_str = endpoint.to_string();
137 visitor.visit_string(endpoint_str)
138 }
139 CoreValue::Object(obj) => {
140 let map = obj
141 .into_iter()
142 .map(|(k, v)| (k, DatexDeserializer::from_value(v)));
143 visitor
144 .visit_map(serde::de::value::MapDeserializer::new(map))
145 }
146 CoreValue::Array(arr) => {
147 let vec =
148 arr.into_iter().map(DatexDeserializer::from_value);
149 visitor
150 .visit_seq(serde::de::value::SeqDeserializer::new(vec))
151 }
152 CoreValue::Tuple(tuple) => {
153 let vec = tuple
154 .into_iter()
155 .map(|(_, v)| DatexDeserializer::from_value(v));
156 visitor
157 .visit_seq(serde::de::value::SeqDeserializer::new(vec))
158 }
159 e => unreachable!("Unsupported core value: {:?}", e),
160 },
161 _ => unreachable!("Refs are not supported in deserialization"),
162 }
163 }
164
165 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
166 where
167 V: serde::de::Visitor<'de>,
168 {
169 if self.value.to_value().borrow().is_null() {
170 visitor.visit_none()
171 } else {
172 visitor.visit_some(self)
173 }
174 }
175
176 forward_to_deserialize_any! {
177 bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf
178 tuple seq unit unit_struct struct ignored_any
179 }
180
181 fn deserialize_newtype_struct<V>(
182 self,
183 name: &'static str,
184 visitor: V,
185 ) -> Result<V::Value, Self::Error>
186 where
187 V: Visitor<'de>,
188 {
189 if let ValueContainer::Value(value::Value {
190 inner: CoreValue::Tuple(t),
191 ..
192 }) = self.value
193 {
194 let values =
195 t.into_iter().map(|(_, v)| DatexDeserializer::from_value(v));
196 visitor.visit_seq(serde::de::value::SeqDeserializer::new(values))
197 } else {
198 visitor.visit_seq(serde::de::value::SeqDeserializer::new(
199 vec![self.value.clone()]
200 .into_iter()
201 .map(DatexDeserializer::from_value),
202 ))
203 }
204 }
205 fn deserialize_tuple_struct<V>(
206 self,
207 name: &'static str,
208 len: usize,
209 visitor: V,
210 ) -> Result<V::Value, Self::Error>
211 where
212 V: Visitor<'de>,
213 {
214 if let ValueContainer::Value(value::Value {
215 inner: CoreValue::Tuple(t),
216 ..
217 }) = self.value
218 {
219 let values =
220 t.into_iter().map(|(_, v)| DatexDeserializer::from_value(v));
221 visitor.visit_seq(serde::de::value::SeqDeserializer::new(values))
222 } else {
223 visitor.visit_seq(serde::de::value::SeqDeserializer::new(
224 vec![self.value.clone()]
225 .into_iter()
226 .map(DatexDeserializer::from_value),
227 ))
228 }
229 }
230
231 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
232 where
233 V: Visitor<'de>,
234 {
235 todo!("#235 map")
236 }
237 fn deserialize_identifier<V>(
238 self,
239 visitor: V,
240 ) -> Result<V::Value, Self::Error>
241 where
242 V: Visitor<'de>,
243 {
244 println!("Deserializing identifier: {:?}", self.value);
245 if let ValueContainer::Value(value::Value {
247 inner: CoreValue::Tuple(t),
248 ..
249 }) = self.value
250 {
251 let identifier = t
252 .at(0)
253 .ok_or(SerializationError("Invalid tuple".to_string()))?
254 .1;
255 visitor
256 .visit_string(identifier.to_value().borrow().cast_to_text().0)
257 }
258 else if let ValueContainer::Value(value::Value {
260 inner: CoreValue::Text(s),
261 ..
262 }) = self.value
263 {
264 visitor.visit_string(s.0)
265 } else {
266 Err(SerializationError("Expected identifier tuple".to_string()))
267 }
268 }
269
270 fn deserialize_enum<V>(
271 self,
272 _name: &str,
273 _variants: &'static [&'static str],
274 visitor: V,
275 ) -> Result<V::Value, Self::Error>
276 where
277 V: serde::de::Visitor<'de>,
278 {
279 println!("Deserializing enum: {:?}", self.value);
280 visitor.visit_enum(DatexEnumAccess { de: self })
281 }
282
283 fn is_human_readable(&self) -> bool {
284 false
285 }
286}
287
288struct DatexEnumAccess {
289 de: DatexDeserializer,
290}
291
292impl<'de> EnumAccess<'de> for DatexEnumAccess {
293 type Error = SerializationError;
294 type Variant = DatexVariantAccess;
295
296 fn variant_seed<V>(
297 self,
298 seed: V,
299 ) -> Result<(V::Value, Self::Variant), Self::Error>
300 where
301 V: DeserializeSeed<'de>,
302 {
303 let variant = seed.deserialize(self.de.clone())?;
304 Ok((variant, DatexVariantAccess { de: self.de }))
305 }
306}
307
308struct DatexVariantAccess {
309 de: DatexDeserializer,
310}
311impl<'de> VariantAccess<'de> for DatexVariantAccess {
312 type Error = SerializationError;
313
314 fn unit_variant(self) -> Result<(), Self::Error> {
315 Ok(())
316 }
317
318 fn newtype_variant_seed<T>(
319 mut self,
320 seed: T,
321 ) -> Result<T::Value, Self::Error>
322 where
323 T: DeserializeSeed<'de>,
324 {
325 if let ValueContainer::Value(value::Value {
326 inner: CoreValue::Tuple(t),
327 ..
328 }) = self.de.value
329 {
330 let value = t
331 .at(1)
332 .ok_or(SerializationError("Invalid tuple".to_string()))?
333 .1;
334 self.de.value = value.clone();
335 Ok(seed.deserialize(self.de)?)
336 } else {
337 Err(SerializationError("Expected identifier tuple".to_string()))
338 }
339 }
340
341 fn tuple_variant<V>(
342 self,
343 len: usize,
344 visitor: V,
345 ) -> Result<V::Value, Self::Error>
346 where
347 V: Visitor<'de>,
348 {
349 todo!("#236 Undescribed by author.")
350 }
351
352 fn struct_variant<V>(
353 self,
354 fields: &'static [&'static str],
355 visitor: V,
356 ) -> Result<V::Value, Self::Error>
357 where
358 V: Visitor<'de>,
359 {
360 todo!("#237 Undescribed by author.")
361 }
362}
363
364pub fn from_bytes<'de, T>(input: &'de [u8]) -> Result<T, SerializationError>
365where
366 T: serde::Deserialize<'de>,
367{
368 let deserializer = DatexDeserializer::from_bytes(input)?;
369 T::deserialize(deserializer)
370}
371
372pub fn from_value_container<'de, T>(
373 value: ValueContainer,
374) -> Result<T, SerializationError>
375where
376 T: serde::Deserialize<'de>,
377{
378 let deserializer = DatexDeserializer::from_value(value);
379 T::deserialize(deserializer)
380}
381
382#[cfg(test)]
383mod tests {
384 use super::*;
385 use crate::values::serde::serializer::to_bytes;
386 use serde::{Deserialize, Serialize};
387 use crate::values::core_values::endpoint::Endpoint;
388
389 #[derive(Deserialize, Serialize, Debug, PartialEq)]
390 struct TestStruct {
391 field1: String,
392 field2: i32,
393 }
394
395 #[derive(Deserialize, Serialize, Debug)]
396 enum TestEnum {
397 Variant1,
398 Variant2,
399 }
400
401 #[derive(Deserialize, Serialize, Debug)]
402 struct TestStruct2 {
403 test_enum: TestEnum,
404 }
405
406 #[derive(Deserialize, Serialize, Debug)]
407 struct TestWithOptionalField {
408 optional_field: Option<String>,
409 }
410
411 #[derive(Deserialize)]
412 struct TestStructWithEndpoint {
413 endpoint: Endpoint,
414 }
415
416 #[derive(Deserialize)]
417 struct TestStructWithOptionalEndpoint {
418 endpoint: Option<Endpoint>,
419 }
420
421 #[derive(Deserialize, Serialize, Debug, PartialEq)]
422 struct TestNestedStruct {
423 nested: TestStruct,
424 }
425
426 #[test]
427 fn test_nested_struct_serde() {
428 let script = r#"
429 {
430 nested: {
431 field1: "Hello",
432 field2: 47
433 }
434 }
435 "#;
436 let deserializer = DatexDeserializer::from_script(script).unwrap();
437 let result: TestNestedStruct =
438 Deserialize::deserialize(deserializer).unwrap();
439 assert_eq!(
440 result,
441 TestNestedStruct {
442 nested: TestStruct {
443 field1: "Hello".to_string(),
444 field2: 47
445 }
446 }
447 );
448 }
449
450 #[test]
451 fn test_from_bytes() {
452 let data = to_bytes(&TestStruct {
453 field1: "Hello".to_string(),
454 field2: 42,
455 })
456 .unwrap();
457 let result: TestStruct = from_bytes(&data).unwrap();
458 assert!(!result.field1.is_empty());
459 }
460
461 #[test]
462 fn test_from_script() {
463 let script = r#"
464 {
465 field1: "Hello",
466 field2: 42 + 5 // This will be evaluated to 47
467 }
468 "#;
469 let deserializer = DatexDeserializer::from_script(script).unwrap();
470 let result: TestStruct =
471 Deserialize::deserialize(deserializer).unwrap();
472 assert!(!result.field1.is_empty());
473 }
474
475 #[test]
478 #[ignore = "This test is currently failing due to type mismatch (i128 instead of i32)"]
479 fn test_from_static_script() {
480 let script = r#"
481 {
482 field1: "Hello",
483 field2: 42
484 }
485 "#;
486 let deserializer =
487 DatexDeserializer::from_static_script(script).unwrap();
488 let result: TestStruct =
489 Deserialize::deserialize(deserializer).unwrap();
490 assert!(!result.field1.is_empty());
491 }
492
493 #[test]
494 fn test_enum_1() {
495 let script = r#""Variant1""#;
496 let dxb = compile_script(script, CompileOptions::default())
497 .expect("Failed to compile script")
498 .0;
499 let deserializer = DatexDeserializer::from_bytes(&dxb)
500 .expect("Failed to create deserializer from DXB");
501 let result: TestEnum = Deserialize::deserialize(deserializer)
502 .expect("Failed to deserialize TestEnum");
503 assert!(matches!(result, TestEnum::Variant1));
504 }
505
506 #[test]
507 fn test_enum_2() {
508 let script = r#""Variant2""#;
509 let dxb = compile_script(script, CompileOptions::default())
510 .expect("Failed to compile script")
511 .0;
512 let deserializer = DatexDeserializer::from_bytes(&dxb)
513 .expect("Failed to create deserializer from DXB");
514 let result: TestEnum = Deserialize::deserialize(deserializer)
515 .expect("Failed to deserialize TestEnum");
516 assert!(matches!(result, TestEnum::Variant2));
517 }
518
519 #[test]
520 fn test_struct_with_enum() {
521 let script = r#"
522 {
523 test_enum: "Variant1"
524 }
525 "#;
526 let dxb = compile_script(script, CompileOptions::default())
527 .expect("Failed to compile script")
528 .0;
529 let deserializer = DatexDeserializer::from_bytes(&dxb)
530 .expect("Failed to create deserializer from DXB");
531 let result: TestStruct2 = Deserialize::deserialize(deserializer)
532 .expect("Failed to deserialize TestStruct2");
533 assert!(matches!(result.test_enum, TestEnum::Variant1));
534 }
535
536 #[test]
537 fn test_endpoint() {
538 let script = r#"
539 {
540 endpoint: @jonas
541 }
542 "#;
543 let dxb = compile_script(script, CompileOptions::default())
544 .expect("Failed to compile script")
545 .0;
546 let deserializer = DatexDeserializer::from_bytes(&dxb)
547 .expect("Failed to create deserializer from DXB");
548 let result: TestStructWithEndpoint =
549 Deserialize::deserialize(deserializer)
550 .expect("Failed to deserialize TestStructWithEndpoint");
551 assert_eq!(result.endpoint.to_string(), "@jonas");
552 }
553
554 #[test]
555 fn test_optional_field() {
556 let script = r#"
557 {
558 optional_field: "Optional Value"
559 }
560 "#;
561 let dxb = compile_script(script, CompileOptions::default())
562 .expect("Failed to compile script")
563 .0;
564 let deserializer = DatexDeserializer::from_bytes(&dxb)
565 .expect("Failed to create deserializer from DXB");
566 let result: TestWithOptionalField =
567 Deserialize::deserialize(deserializer)
568 .expect("Failed to deserialize TestWithOptionalField");
569 assert!(result.optional_field.is_some());
570 assert_eq!(result.optional_field.unwrap(), "Optional Value");
571 }
572
573 #[test]
574 fn test_optional_field_empty() {
575 let script = r#"
576 {
577 optional_field: null
578 }
579 "#;
580 let dxb = compile_script(script, CompileOptions::default())
581 .expect("Failed to compile script")
582 .0;
583 let deserializer = DatexDeserializer::from_bytes(&dxb)
584 .expect("Failed to create deserializer from DXB");
585 let result: TestWithOptionalField =
586 Deserialize::deserialize(deserializer)
587 .expect("Failed to deserialize TestWithOptionalField");
588 assert!(result.optional_field.is_none());
589 }
590
591 #[test]
592 fn test_optional_endpoint() {
593 let script = r#"
594 {
595 endpoint: @jonas
596 }
597 "#;
598 let dxb = compile_script(script, CompileOptions::default())
599 .expect("Failed to compile script")
600 .0;
601 let deserializer = DatexDeserializer::from_bytes(&dxb)
602 .expect("Failed to create deserializer from DXB");
603 let result: TestStructWithOptionalEndpoint =
604 Deserialize::deserialize(deserializer)
605 .expect("Failed to deserialize TestStructWithOptionalEndpoint");
606 assert!(result.endpoint.is_some());
607 assert_eq!(result.endpoint.unwrap().to_string(), "@jonas");
608 }
609
610 #[derive(Deserialize, Serialize, Debug)]
611 enum ExampleEnum {
612 Variant1(String),
613 Variant2(i32),
614 }
615
616 #[test]
617 fn test_map() {
618 let script = r#"("Variant1", "xy")"#;
619 let dxb = compile_script(script, CompileOptions::default())
620 .expect("Failed to compile script")
621 .0;
622 let deserializer = DatexDeserializer::from_bytes(&dxb)
623 .expect("Failed to create deserializer from DXB");
624 let result: ExampleEnum = Deserialize::deserialize(deserializer)
625 .expect("Failed to deserialize ExampleEnum");
626 match result {
627 ExampleEnum::Variant1(s) => assert_eq!(s, "xy"),
628 _ => panic!("Expected Variant1 with value 'xy'"),
629 }
630
631 let script = r#"("Variant2", 42)"#;
632 let dxb = compile_script(script, CompileOptions::default())
633 .expect("Failed to compile script")
634 .0;
635 let deserializer = DatexDeserializer::from_bytes(&dxb)
636 .expect("Failed to create deserializer from DXB");
637 let result: ExampleEnum = Deserialize::deserialize(deserializer)
638 .expect("Failed to deserialize ExampleEnum");
639 match result {
640 ExampleEnum::Variant2(i) => assert_eq!(i, 42),
641 _ => panic!("Expected Variant2 with value 42"),
642 }
643 }
644}