1use crate::{
2 runtime::execution::{ExecutionInput, ExecutionOptions, execute_dxb_sync},
3 serde::error::DeserializationError,
4 values::{
5 core_value::CoreValue,
6 core_values::{
7 integer::typed_integer::TypedInteger, map::BorrowedMapKey,
8 },
9 value,
10 value::Value,
11 value_container::ValueContainer,
12 },
13};
14use core::{result::Result, unreachable};
15use serde::{
16 Deserialize, Deserializer,
17 de::{
18 DeserializeOwned, EnumAccess, IntoDeserializer, VariantAccess, Visitor,
19 value::StrDeserializer,
20 },
21 forward_to_deserialize_any,
22};
23
24use crate::{prelude::*, runtime::RuntimeInternal};
25
26pub fn from_bytes<T>(input: &[u8]) -> Result<T, DeserializationError>
28where
29 T: DeserializeOwned,
30{
31 let runtime = RuntimeInternal::stub();
32 let context = ExecutionInput::new(
33 input,
34 ExecutionOptions { verbose: true },
35 Rc::new(runtime),
36 );
37 let value = execute_dxb_sync(context)
38 .map_err(DeserializationError::ExecutionError)?
39 .expect("DXB execution returned no value");
40
41 let deserializer = DatexDeserializer::new_from_value_container(&value);
42 T::deserialize(deserializer)
43}
44
45#[cfg(feature = "compiler")]
46pub fn from_script<T>(script: &str) -> Result<T, DeserializationError>
47where
48 T: DeserializeOwned,
49{
50 let (dxb, _) = crate::compiler::compile_script(
51 script,
52 crate::compiler::CompileOptions::default(),
53 )
54 .map_err(|err| DeserializationError::CanNotReadFile(err.to_string()))?;
55 from_bytes(&dxb)
56}
57
58#[cfg(all(feature = "std", feature = "compiler"))]
59pub fn from_dx_file<T>(
60 path: std::path::PathBuf,
61) -> Result<T, DeserializationError>
62where
63 T: DeserializeOwned,
64{
65 let input = std::fs::read_to_string(path)
66 .map_err(|err| DeserializationError::CanNotReadFile(err.to_string()))?;
67 from_script(&input)
68}
69
70#[cfg(feature = "compiler")]
81pub fn from_static_script<T>(script: &str) -> Result<T, DeserializationError>
82where
83 T: DeserializeOwned,
84{
85 let value = crate::compiler::extract_static_value_from_script(script)
86 .map_err(DeserializationError::CompilerError)?
87 .ok_or(DeserializationError::NoStaticValueFound)?;
88 let deserializer = DatexDeserializer::new_from_value_container(&value);
89 T::deserialize(deserializer)
90}
91
92pub fn from_value_container<T>(
94 value: &ValueContainer,
95) -> Result<T, DeserializationError>
96where
97 T: serde::de::DeserializeOwned,
98{
99 let deserializer = DatexDeserializer::new_from_value_container(value);
100 T::deserialize(deserializer)
101}
102
103#[derive(Clone)]
104pub enum DatexDeserializer<'de> {
105 ValueContainer(&'de ValueContainer),
106 Text(&'de str),
107}
108
109impl<'de> DatexDeserializer<'de> {
110 fn new_from_value_container(value: &'de ValueContainer) -> Self {
111 Self::ValueContainer(value)
112 }
113 fn new_from_str(text: &'de str) -> Self {
114 Self::Text(text)
115 }
116 fn new_from_borrowed_map_key(key: BorrowedMapKey<'de>) -> Self {
117 match key {
118 BorrowedMapKey::Text(s) => Self::Text(s),
119 BorrowedMapKey::Value(v) => Self::ValueContainer(v),
120 }
121 }
122
123 pub(crate) fn to_value_container(&self) -> Cow<'de, ValueContainer> {
124 match self {
125 DatexDeserializer::ValueContainer(v) => Cow::Borrowed(v),
126 DatexDeserializer::Text(s) => Cow::Owned(ValueContainer::from(*s)),
127 }
128 }
129}
130
131impl<'de> IntoDeserializer<'de, DeserializationError>
132 for DatexDeserializer<'de>
133{
134 type Deserializer = Self;
135
136 fn into_deserializer(self) -> Self::Deserializer {
137 self
138 }
139}
140impl<'de> Deserializer<'de> for DatexDeserializer<'de> {
141 type Error = DeserializationError;
142
143 forward_to_deserialize_any! {
144 bool char str string bytes byte_buf
145 tuple seq unit struct ignored_any
146 }
147
148 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
151 where
152 V: serde::de::Visitor<'de>,
153 {
154 match self {
155 DatexDeserializer::Text(s) => visitor.visit_string(s.to_string()),
156 DatexDeserializer::ValueContainer(value) => match value {
157 ValueContainer::Local(value::Value { inner, .. }) => {
159 match inner {
160 CoreValue::Null => visitor.visit_none(),
161 CoreValue::Boolean(b) => visitor.visit_bool(b.0),
162 CoreValue::TypedInteger(i) => match i {
163 TypedInteger::I128(i) => visitor.visit_i128(*i),
164 TypedInteger::U128(u) => visitor.visit_u128(*u),
165 TypedInteger::I64(i) => visitor.visit_i64(*i),
166 TypedInteger::U64(u) => visitor.visit_u64(*u),
167 TypedInteger::I32(i) => visitor.visit_i32(*i),
168 TypedInteger::U32(u) => visitor.visit_u32(*u),
169 TypedInteger::I16(i) => visitor.visit_i16(*i),
170 TypedInteger::U16(u) => visitor.visit_u16(*u),
171 TypedInteger::I8(i) => visitor.visit_i8(*i),
172 TypedInteger::U8(u) => visitor.visit_u8(*u),
173 TypedInteger::IBig(i) => {
174 visitor.visit_i128(i.as_i128().unwrap())
175 }
176 },
177 CoreValue::Text(s) => visitor.visit_string(s.0.clone()),
178 CoreValue::Endpoint(endpoint) => {
179 let endpoint_str = endpoint.to_string();
180 visitor.visit_string(endpoint_str)
181 }
182 CoreValue::Map(obj) => {
183 let map = obj
184 .iter()
185 .map(|(k, v)| {
186 (
187 DatexDeserializer::new_from_borrowed_map_key(k),
188 DatexDeserializer::new_from_value_container(v),
189 )
190 })
191 .collect::<Vec<_>>();
192 visitor.visit_map(
193 serde::de::value::MapDeserializer::new(
194 map.into_iter(),
195 ),
196 )
197 }
198 CoreValue::List(list) => {
199 let vec: Vec<DatexDeserializer<'de>> = list
200 .iter()
201 .map(
202 DatexDeserializer::new_from_value_container,
203 )
204 .collect::<Vec<_>>();
205 visitor.visit_seq(
206 serde::de::value::SeqDeserializer::new(
207 vec.into_iter(),
208 ),
209 )
210 }
211 e => unreachable!("Unsupported core value: {:?}", e),
212 }
213 }
214 _ => unreachable!("Refs are not supported in deserialization"),
215 },
216 }
217 }
218
219 fn deserialize_unit_struct<V>(
225 self,
226 _name: &'static str,
227 visitor: V,
228 ) -> Result<V::Value, Self::Error>
229 where
230 V: Visitor<'de>,
231 {
232 visitor.visit_unit()
233 }
234
235 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
240 where
241 V: serde::de::Visitor<'de>,
242 {
243 match self {
244 DatexDeserializer::ValueContainer(value)
245 if value.to_value().borrow().is_null() =>
246 {
247 visitor.visit_none()
248 }
249 _ => visitor.visit_some(self),
250 }
251 }
252
253 fn deserialize_newtype_struct<V>(
261 self,
262 _name: &'static str,
263 visitor: V,
264 ) -> Result<V::Value, Self::Error>
265 where
266 V: Visitor<'de>,
267 {
268 visitor.visit_seq(serde::de::value::SeqDeserializer::new(
302 vec![self].into_iter(),
303 ))
304 }
305
306 fn deserialize_tuple_struct<V>(
312 self,
313 _name: &'static str,
314 _len: usize,
315 visitor: V,
316 ) -> Result<V::Value, Self::Error>
317 where
318 V: Visitor<'de>,
319 {
320 if let DatexDeserializer::ValueContainer(ValueContainer::Local(
321 Value {
322 inner: CoreValue::List(list),
323 ..
324 },
325 )) = self
326 {
327 visitor.visit_seq(serde::de::value::SeqDeserializer::new(
328 list.iter().map(DatexDeserializer::new_from_value_container),
329 ))
330 } else {
331 Err(DeserializationError::Custom(
332 "expected map for tuple struct".to_string(),
333 ))
334 }
335 }
336
337 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
341 where
342 V: Visitor<'de>,
343 {
344 if let DatexDeserializer::ValueContainer(ValueContainer::Local(
345 Value {
346 inner: CoreValue::Map(map),
347 ..
348 },
349 )) = self
350 {
351 let entries = map.iter().map(|(k, v)| {
352 (
353 DatexDeserializer::new_from_borrowed_map_key(k),
354 DatexDeserializer::new_from_value_container(v),
355 )
356 });
357 visitor.visit_map(serde::de::value::MapDeserializer::new(entries))
358 } else {
359 Err(DeserializationError::Custom("expected map".to_string()))
360 }
361 }
362
363 fn deserialize_identifier<V>(
368 self,
369 visitor: V,
370 ) -> Result<V::Value, Self::Error>
371 where
372 V: Visitor<'de>,
373 {
374 match self {
375 DatexDeserializer::Text(s) => visitor.visit_string(s.to_string()),
376 DatexDeserializer::ValueContainer(value) => match value {
377 ValueContainer::Local(Value {
379 inner: CoreValue::Text(s),
380 ..
381 }) => visitor.visit_string(s.0.clone()),
382
383 ValueContainer::Local(Value {
385 inner: CoreValue::Map(o),
386 ..
387 }) => {
388 if o.size() == 1 {
389 let (key, _) = o.iter().next().unwrap();
390 if let BorrowedMapKey::Text(string) = key {
391 visitor.visit_string(string.to_string())
392 } else {
393 Err(DeserializationError::Custom(
394 "Expected text key for identifier".to_string(),
395 ))
396 }
397 } else {
398 Err(DeserializationError::Custom(
399 "Expected single-key map for identifier"
400 .to_string(),
401 ))
402 }
403 }
404
405 _ => Err(DeserializationError::Custom(
406 "Expected identifier".to_string(),
407 )),
408 },
409 }
410 }
411
412 fn deserialize_enum<V>(
416 self,
417 _name: &str,
418 _variants: &'static [&'static str],
419 visitor: V,
420 ) -> Result<V::Value, Self::Error>
421 where
422 V: Visitor<'de>,
423 {
424 match self {
425 DatexDeserializer::Text(s) => {
426 visitor.visit_enum(EnumDeserializer {
427 variant: s,
428 value: None,
429 })
430 }
431 DatexDeserializer::ValueContainer(value) => match value {
432 value @ ValueContainer::Local(Value {
434 inner: CoreValue::List(t),
435 ..
436 }) => {
437 if t.is_empty() {
438 return Err(DeserializationError::Custom(
439 "Expected non-empty tuple for enum".to_string(),
440 ));
441 }
442 let deserializer =
443 DatexDeserializer::new_from_value_container(value);
444 visitor.visit_enum(EnumDeserializer {
445 variant: "_tuple",
446 value: Some(deserializer),
447 })
448 }
449
450 ValueContainer::Local(Value {
452 inner: CoreValue::Map(o),
453 ..
454 }) => {
455 if o.size() != 1 {
456 return Err(DeserializationError::Custom(
457 "Expected single-key map for enum".to_string(),
458 ));
459 }
460
461 let (variant_name, value) = o.iter().next().unwrap();
462 if let BorrowedMapKey::Text(variant) = variant_name {
463 let deserializer =
464 DatexDeserializer::new_from_value_container(value);
465 visitor.visit_enum(EnumDeserializer {
466 variant,
467 value: Some(deserializer),
468 })
469 } else {
470 Err(DeserializationError::Custom(
471 "Expected text variant name".to_string(),
472 ))
473 }
474 }
475 ValueContainer::Local(Value {
497 inner: CoreValue::Text(s),
498 ..
499 }) => visitor.visit_enum(EnumDeserializer {
500 variant: &s.0,
501 value: None,
502 }),
503
504 e => Err(DeserializationError::Custom(format!(
505 "Expected enum representation, found: {}",
506 e
507 ))),
508 },
509 }
510 }
511
512 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
513 where
514 V: Visitor<'de>,
515 {
516 match self {
517 DatexDeserializer::Text(_s) => {
518 Err(DeserializationError::CanNotDeserialize("f32".to_string()))
519 }
520 DatexDeserializer::ValueContainer(value) => {
521 match &value.to_value().borrow().inner {
522 CoreValue::Decimal(decimal) => {
523 visitor.visit_f32(decimal.into_f32())
524 }
525 CoreValue::TypedDecimal(typed_decimal) => {
526 visitor.visit_f32(typed_decimal.as_f32())
527 }
528 CoreValue::Integer(integer) => {
529 visitor.visit_f32(integer.as_f32())
530 }
531 CoreValue::TypedInteger(typed_integer) => {
532 visitor.visit_f32(typed_integer.as_f32())
533 }
534 _ => Err(DeserializationError::CanNotDeserialize(
535 "f32".to_string(),
536 )),
537 }
538 }
539 }
540 }
541
542 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
543 where
544 V: Visitor<'de>,
545 {
546 match self {
547 DatexDeserializer::Text(_s) => {
548 Err(DeserializationError::CanNotDeserialize("f64".to_string()))
549 }
550 DatexDeserializer::ValueContainer(value) => {
551 match &value.to_value().borrow().inner {
552 CoreValue::Decimal(decimal) => {
553 visitor.visit_f64(decimal.into_f64())
554 }
555 CoreValue::TypedDecimal(typed_decimal) => {
556 visitor.visit_f64(typed_decimal.as_f64())
557 }
558 CoreValue::Integer(integer) => {
559 visitor.visit_f64(integer.as_f64())
560 }
561 CoreValue::TypedInteger(typed_integer) => {
562 visitor.visit_f64(typed_integer.as_f64())
563 }
564 _ => Err(DeserializationError::CanNotDeserialize(
565 "f64".to_string(),
566 )),
567 }
568 }
569 }
570 }
571
572 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
573 where
574 V: Visitor<'de>,
575 {
576 match self {
577 DatexDeserializer::Text(_s) => {
578 Err(DeserializationError::CanNotDeserialize("i8".to_string()))
579 }
580 DatexDeserializer::ValueContainer(value) => {
581 match &value.to_value().borrow().inner {
582 CoreValue::Integer(i) => {
583 visitor.visit_i8(i.as_wrapped_i8())
584 }
585 CoreValue::TypedInteger(i) => {
586 visitor.visit_i8(i.as_integer().as_wrapped_i8())
587 }
588 CoreValue::Decimal(d) => {
589 visitor.visit_i8(d.as_integer().unwrap() as i8)
590 }
591 CoreValue::TypedDecimal(d) => {
592 visitor.visit_i8(d.as_integer().unwrap() as i8)
593 }
594 _ => Err(DeserializationError::CanNotDeserialize(
595 "i8".to_string(),
596 )),
597 }
598 }
599 }
600 }
601
602 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
603 where
604 V: Visitor<'de>,
605 {
606 match self {
607 DatexDeserializer::Text(_s) => {
608 Err(DeserializationError::CanNotDeserialize("i16".to_string()))
609 }
610 DatexDeserializer::ValueContainer(value) => {
611 match &value.to_value().borrow().inner {
612 CoreValue::Integer(i) => {
613 visitor.visit_i16(i.as_wrapped_i16())
614 }
615 CoreValue::TypedInteger(i) => {
616 visitor.visit_i16(i.as_integer().as_wrapped_i16())
617 }
618 CoreValue::Decimal(d) => {
619 visitor.visit_i16(d.as_integer().unwrap() as i16)
620 }
621 CoreValue::TypedDecimal(d) => {
622 visitor.visit_i16(d.as_integer().unwrap() as i16)
623 }
624 _ => Err(DeserializationError::CanNotDeserialize(
625 "i16".to_string(),
626 )),
627 }
628 }
629 }
630 }
631
632 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
633 where
634 V: Visitor<'de>,
635 {
636 match self {
637 DatexDeserializer::Text(_s) => {
638 Err(DeserializationError::CanNotDeserialize("i32".to_string()))
639 }
640 DatexDeserializer::ValueContainer(value) => {
641 match &value.to_value().borrow().inner {
642 CoreValue::Integer(i) => {
643 visitor.visit_i32(i.as_wrapped_i32())
644 }
645 CoreValue::TypedInteger(i) => {
646 visitor.visit_i32(i.as_integer().as_wrapped_i32())
647 }
648 CoreValue::Decimal(d) => {
649 visitor.visit_i32(d.as_integer().unwrap() as i32)
650 }
651 CoreValue::TypedDecimal(d) => {
652 visitor.visit_i32(d.as_integer().unwrap() as i32)
653 }
654 _ => Err(DeserializationError::CanNotDeserialize(
655 "i32".to_string(),
656 )),
657 }
658 }
659 }
660 }
661
662 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
663 where
664 V: Visitor<'de>,
665 {
666 match self {
667 DatexDeserializer::Text(_s) => {
668 Err(DeserializationError::CanNotDeserialize("i64".to_string()))
669 }
670 DatexDeserializer::ValueContainer(value) => {
671 match &value.to_value().borrow().inner {
672 CoreValue::Integer(i) => {
673 visitor.visit_i64(i.as_wrapped_i64())
674 }
675 CoreValue::TypedInteger(i) => {
676 visitor.visit_i64(i.as_integer().as_wrapped_i64())
677 }
678 CoreValue::Decimal(d) => {
679 visitor.visit_i64(d.as_integer().unwrap())
680 }
681 CoreValue::TypedDecimal(d) => {
682 visitor.visit_i64(d.as_integer().unwrap())
683 }
684 _ => Err(DeserializationError::CanNotDeserialize(
685 "i64".to_string(),
686 )),
687 }
688 }
689 }
690 }
691
692 fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
693 where
694 V: Visitor<'de>,
695 {
696 match self {
697 DatexDeserializer::Text(_s) => {
698 Err(DeserializationError::CanNotDeserialize("i128".to_string()))
699 }
700 DatexDeserializer::ValueContainer(value) => {
701 match &value.to_value().borrow().inner {
702 CoreValue::Integer(i) => {
703 visitor.visit_i128(i.as_wrapped_i128())
704 }
705 CoreValue::TypedInteger(i) => {
706 visitor.visit_i128(i.as_integer().as_wrapped_i128())
707 }
708 CoreValue::Decimal(d) => {
709 visitor.visit_i128(d.as_integer().unwrap() as i128)
710 }
711 CoreValue::TypedDecimal(d) => {
712 visitor.visit_i128(d.as_integer().unwrap() as i128)
713 }
714 _ => Err(DeserializationError::CanNotDeserialize(
715 "i128".to_string(),
716 )),
717 }
718 }
719 }
720 }
721
722 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
723 where
724 V: Visitor<'de>,
725 {
726 match self {
727 DatexDeserializer::Text(_s) => {
728 Err(DeserializationError::CanNotDeserialize("u8".to_string()))
729 }
730 DatexDeserializer::ValueContainer(value) => {
731 match &value.to_value().borrow().inner {
732 CoreValue::Integer(i) => {
733 visitor.visit_u8(i.as_wrapped_u8())
734 }
735 CoreValue::TypedInteger(i) => {
736 visitor.visit_u8(i.as_integer().as_wrapped_u8())
737 }
738 CoreValue::Decimal(d) => {
739 visitor.visit_u8(d.as_integer().unwrap() as u8)
740 }
741 CoreValue::TypedDecimal(d) => {
742 visitor.visit_u8(d.as_integer().unwrap() as u8)
743 }
744 _ => Err(DeserializationError::CanNotDeserialize(
745 "u8".to_string(),
746 )),
747 }
748 }
749 }
750 }
751
752 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
753 where
754 V: Visitor<'de>,
755 {
756 match self {
757 DatexDeserializer::Text(_s) => {
758 Err(DeserializationError::CanNotDeserialize("u16".to_string()))
759 }
760 DatexDeserializer::ValueContainer(value) => {
761 match &value.to_value().borrow().inner {
762 CoreValue::Integer(i) => {
763 visitor.visit_u16(i.as_wrapped_u16())
764 }
765 CoreValue::TypedInteger(i) => {
766 visitor.visit_u16(i.as_integer().as_wrapped_u16())
767 }
768 CoreValue::Decimal(d) => {
769 visitor.visit_u16(d.as_integer().unwrap() as u16)
770 }
771 CoreValue::TypedDecimal(d) => {
772 visitor.visit_u16(d.as_integer().unwrap() as u16)
773 }
774 _ => Err(DeserializationError::CanNotDeserialize(
775 "u16".to_string(),
776 )),
777 }
778 }
779 }
780 }
781
782 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
783 where
784 V: Visitor<'de>,
785 {
786 match self {
787 DatexDeserializer::Text(_s) => {
788 Err(DeserializationError::CanNotDeserialize("u32".to_string()))
789 }
790 DatexDeserializer::ValueContainer(value) => {
791 match &value.to_value().borrow().inner {
792 CoreValue::Integer(i) => {
793 visitor.visit_u32(i.as_wrapped_u32())
794 }
795 CoreValue::TypedInteger(i) => {
796 visitor.visit_u32(i.as_integer().as_wrapped_u32())
797 }
798 CoreValue::Decimal(d) => {
799 visitor.visit_u32(d.as_integer().unwrap() as u32)
800 }
801 CoreValue::TypedDecimal(d) => {
802 visitor.visit_u32(d.as_integer().unwrap() as u32)
803 }
804 _ => Err(DeserializationError::CanNotDeserialize(
805 "u32".to_string(),
806 )),
807 }
808 }
809 }
810 }
811
812 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
813 where
814 V: Visitor<'de>,
815 {
816 match self {
817 DatexDeserializer::Text(_s) => {
818 Err(DeserializationError::CanNotDeserialize("u64".to_string()))
819 }
820 DatexDeserializer::ValueContainer(value) => {
821 match &value.to_value().borrow().inner {
822 CoreValue::Integer(i) => {
823 visitor.visit_u64(i.as_wrapped_u64())
824 }
825 CoreValue::TypedInteger(i) => {
826 visitor.visit_u64(i.as_integer().as_wrapped_u64())
827 }
828 CoreValue::Decimal(d) => {
829 visitor.visit_u64(d.as_integer().unwrap() as u64)
830 }
831 CoreValue::TypedDecimal(d) => {
832 visitor.visit_u64(d.as_integer().unwrap() as u64)
833 }
834 _ => Err(DeserializationError::CanNotDeserialize(
835 "u64".to_string(),
836 )),
837 }
838 }
839 }
840 }
841
842 fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
843 where
844 V: Visitor<'de>,
845 {
846 match self {
847 DatexDeserializer::Text(_s) => {
848 Err(DeserializationError::CanNotDeserialize("u128".to_string()))
849 }
850 DatexDeserializer::ValueContainer(value) => {
851 match &value.to_value().borrow().inner {
852 CoreValue::Integer(i) => {
853 visitor.visit_u128(i.as_wrapped_u128())
854 }
855 CoreValue::TypedInteger(i) => {
856 visitor.visit_u128(i.as_integer().as_wrapped_u128())
857 }
858 CoreValue::Decimal(d) => {
859 visitor.visit_u128(d.as_integer().unwrap() as u128)
860 }
861 CoreValue::TypedDecimal(d) => {
862 visitor.visit_u128(d.as_integer().unwrap() as u128)
863 }
864 _ => Err(DeserializationError::CanNotDeserialize(
865 "u128".to_string(),
866 )),
867 }
868 }
869 }
870 }
871
872 fn is_human_readable(&self) -> bool {
873 false
874 }
875}
876
877struct EnumDeserializer<'de> {
887 variant: &'de str,
888 value: Option<DatexDeserializer<'de>>,
889}
890impl<'de> EnumAccess<'de> for EnumDeserializer<'de> {
891 type Error = DeserializationError;
892 type Variant = VariantDeserializer<'de>;
893
894 fn variant_seed<V>(
895 self,
896 seed: V,
897 ) -> Result<(V::Value, Self::Variant), Self::Error>
898 where
899 V: serde::de::DeserializeSeed<'de>,
900 {
901 let variant = seed.deserialize::<StrDeserializer<Self::Error>>(
902 self.variant.into_deserializer(),
903 )?;
904 Ok((variant, VariantDeserializer { value: self.value }))
905 }
906}
907
908struct VariantDeserializer<'de> {
918 value: Option<DatexDeserializer<'de>>,
919}
920
921impl<'de> VariantAccess<'de> for VariantDeserializer<'de> {
922 type Error = DeserializationError;
923
924 fn unit_variant(self) -> Result<(), Self::Error> {
925 Ok(())
926 }
927
928 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
929 where
930 T: serde::de::DeserializeSeed<'de>,
931 {
932 match self.value {
933 Some(value) => seed.deserialize(value),
934 None => Err(DeserializationError::Custom(
935 "Expected value for newtype variant".to_string(),
936 )),
937 }
938 }
939
940 fn tuple_variant<V>(
941 self,
942 len: usize,
943 visitor: V,
944 ) -> Result<V::Value, Self::Error>
945 where
946 V: serde::de::Visitor<'de>,
947 {
948 match self.value {
949 Some(value) => value.deserialize_tuple(len, visitor),
950 None => visitor.visit_unit(),
951 }
952 }
953
954 fn struct_variant<V>(
955 self,
956 fields: &'static [&'static str],
957 visitor: V,
958 ) -> Result<V::Value, Self::Error>
959 where
960 V: serde::de::Visitor<'de>,
961 {
962 match self.value {
963 Some(value) => value.deserialize_struct("", fields, visitor),
964 None => visitor.visit_unit(),
965 }
966 }
967}
968
969#[cfg(test)]
970#[cfg(feature = "compiler")]
971mod tests {
972 use super::*;
973 use crate::{
974 compiler::{CompileOptions, compile_script},
975 serde::serializer::to_bytes,
976 values::core_values::endpoint::Endpoint,
977 };
978 use serde::{Deserialize, Serialize};
979
980 use crate::prelude::*;
981 #[derive(Deserialize, Serialize, Debug, PartialEq)]
982 struct TestStruct {
983 field1: String,
984 field2: i32,
985 }
986
987 #[derive(Deserialize, Serialize, Debug)]
988 enum TestEnum {
989 Variant1,
990 Variant2,
991 }
992
993 #[derive(Deserialize, Serialize, Debug)]
994 struct TestStruct2 {
995 test_enum: TestEnum,
996 }
997
998 #[derive(Deserialize, Serialize, Debug)]
999 struct TestWithOptionalField {
1000 optional_field: Option<String>,
1001 }
1002
1003 #[derive(Deserialize)]
1004 struct TestStructWithEndpoint {
1005 endpoint: Endpoint,
1006 }
1007
1008 #[derive(Deserialize)]
1009 struct TestStructWithOptionalEndpoint {
1010 endpoint: Option<Endpoint>,
1011 }
1012
1013 #[derive(Deserialize, Serialize, Debug, PartialEq)]
1014 struct TestNestedStruct {
1015 nested: TestStruct,
1016 }
1017
1018 #[test]
1019 fn nested_struct_serde() {
1020 let script = r#"
1021 {
1022 nested: {
1023 field1: "Hello",
1024 field2: 47
1025 }
1026 }
1027 "#;
1028 let result: TestNestedStruct = super::from_script(script).unwrap();
1029 assert_eq!(
1030 result,
1031 TestNestedStruct {
1032 nested: TestStruct {
1033 field1: "Hello".to_string(),
1034 field2: 47
1035 }
1036 }
1037 );
1038 }
1039
1040 #[test]
1041 fn struct_from_bytes() {
1042 let data = to_bytes(&TestStruct {
1043 field1: "Hello".to_string(),
1044 field2: 42,
1045 })
1046 .unwrap();
1047 let result: TestStruct = from_bytes(&data).unwrap();
1048 assert!(!result.field1.is_empty());
1049 }
1050
1051 #[test]
1052 fn from_script() {
1053 let script = r#"
1054 {
1055 field1: "Hello",
1056 field2: 42 + 5 // This will be evaluated to 47
1057 }
1058 "#;
1059 let result: TestStruct = super::from_script(script).unwrap();
1060 assert!(!result.field1.is_empty());
1061 }
1062
1063 #[test]
1064 fn test_from_static_script() {
1065 let script = r#"
1066 {
1067 field1: "Hello",
1068 field2: 42
1069 }
1070 "#;
1071 let result: TestStruct = from_static_script(script).unwrap();
1072 assert!(!result.field1.is_empty());
1073 }
1074
1075 #[test]
1076 fn enum_1() {
1077 let script = r#""Variant1""#;
1078 let dxb = compile_script(script, CompileOptions::default())
1079 .expect("Failed to compile script")
1080 .0;
1081 let result: TestEnum =
1082 from_bytes(&dxb).expect("Failed to deserialize TestEnum");
1083 assert!(core::matches!(result, TestEnum::Variant1));
1084 }
1085
1086 #[test]
1087 fn enum_2() {
1088 let script = r#""Variant2""#;
1089 let dxb = compile_script(script, CompileOptions::default())
1090 .expect("Failed to compile script")
1091 .0;
1092 let result: TestEnum =
1093 from_bytes(&dxb).expect("Failed to deserialize TestEnum");
1094 assert!(core::matches!(result, TestEnum::Variant2));
1095 }
1096
1097 #[test]
1098 fn struct_with_enum() {
1099 let script = r#"
1100 {
1101 test_enum: "Variant1"
1102 }
1103 "#;
1104 let dxb = compile_script(script, CompileOptions::default())
1105 .expect("Failed to compile script")
1106 .0;
1107 let result: TestStruct2 =
1108 from_bytes(&dxb).expect("Failed to deserialize TestStruct2");
1109 assert!(core::matches!(result.test_enum, TestEnum::Variant1));
1110 }
1111
1112 #[test]
1113 fn endpoint() {
1114 let script = r#"
1115 {
1116 endpoint: @jonas
1117 }
1118 "#;
1119 let dxb = compile_script(script, CompileOptions::default())
1120 .expect("Failed to compile script")
1121 .0;
1122 let result: TestStructWithEndpoint = from_bytes(&dxb)
1123 .expect("Failed to deserialize TestStructWithEndpoint");
1124 assert_eq!(result.endpoint.to_string(), "@jonas");
1125 }
1126
1127 #[test]
1128 fn optional_field() {
1129 let script = r#"
1130 {
1131 optional_field: "Optional Value"
1132 }
1133 "#;
1134 let dxb = compile_script(script, CompileOptions::default())
1135 .expect("Failed to compile script")
1136 .0;
1137 let result: TestWithOptionalField = from_bytes(&dxb)
1138 .expect("Failed to deserialize TestWithOptionalField");
1139 assert!(result.optional_field.is_some());
1140 assert_eq!(result.optional_field.unwrap(), "Optional Value");
1141 }
1142
1143 #[test]
1144 fn optional_field_empty() {
1145 let script = r#"
1146 {
1147 optional_field: null
1148 }
1149 "#;
1150 let dxb = compile_script(script, CompileOptions::default())
1151 .expect("Failed to compile script")
1152 .0;
1153 let result: TestWithOptionalField = from_bytes(&dxb)
1154 .expect("Failed to deserialize TestWithOptionalField");
1155 assert!(result.optional_field.is_none());
1156 }
1157
1158 #[test]
1159 fn optional_endpoint() {
1160 let script = r#"
1161 {
1162 endpoint: @jonas
1163 }
1164 "#;
1165 let dxb = compile_script(script, CompileOptions::default())
1166 .expect("Failed to compile script")
1167 .0;
1168 let result: TestStructWithOptionalEndpoint = from_bytes(&dxb)
1169 .expect("Failed to deserialize TestStructWithOptionalEndpoint");
1170 assert!(result.endpoint.is_some());
1171 assert_eq!(result.endpoint.unwrap().to_string(), "@jonas");
1172 }
1173
1174 #[derive(Deserialize, Serialize, Debug)]
1175 enum ExampleEnum {
1176 Variant1(String),
1177 Variant2(i32),
1178 }
1179
1180 #[test]
1181 fn map() {
1182 let script = "{Variant1: \"Hello\"}";
1183 let dxb = compile_script(script, CompileOptions::default())
1184 .expect("Failed to compile script")
1185 .0;
1186 let result: ExampleEnum =
1187 from_bytes(&dxb).expect("Failed to deserialize ExampleEnum");
1188 assert!(core::matches!(result, ExampleEnum::Variant1(_)));
1189
1190 let script = r#"{"Variant2": 42}"#;
1191 let dxb = compile_script(script, CompileOptions::default())
1192 .expect("Failed to compile script")
1193 .0;
1194 let result: ExampleEnum =
1195 from_bytes(&dxb).expect("Failed to deserialize ExampleEnum");
1196 assert!(core::matches!(result, ExampleEnum::Variant2(_)));
1197 }
1198}