datex_core/decompiler/
ast_from_value_container.rs

1use crate::ast::{DatexExpression, TypeExpression};
2use crate::references::reference::ReferenceMutability;
3use crate::types::definition::TypeDefinition;
4use crate::types::structural_type_definition::StructuralTypeDefinition;
5use crate::values::core_value::CoreValue;
6use crate::values::value::Value;
7use crate::values::value_container::ValueContainer;
8
9impl From<&ValueContainer> for DatexExpression {
10    /// Converts a ValueContainer into a DatexExpression AST.
11    /// This AST can then be further processed or decompiled into human-readable DATEX code.
12    fn from(value: &ValueContainer) -> Self {
13        match value {
14            ValueContainer::Value(value) => value_to_datex_expression(value),
15            ValueContainer::Reference(reference) => {
16                match reference.mutability() {
17                    ReferenceMutability::Mutable => {
18                        DatexExpression::CreateRefMut(Box::new(
19                            DatexExpression::from(&reference.value_container()),
20                        ))
21                    }
22                    ReferenceMutability::Immutable => {
23                        DatexExpression::CreateRef(Box::new(
24                            DatexExpression::from(&reference.value_container()),
25                        ))
26                    }
27                    ReferenceMutability::Final => {
28                        DatexExpression::CreateRefFinal(Box::new(
29                            DatexExpression::from(&reference.value_container()),
30                        ))
31                    }
32                }
33            }
34        }
35    }
36}
37
38fn value_to_datex_expression(value: &Value) -> DatexExpression {
39    match &value.inner {
40        CoreValue::Integer(integer) => {
41            DatexExpression::Integer(integer.clone())
42        }
43        CoreValue::TypedInteger(typed_integer) => {
44            DatexExpression::TypedInteger(typed_integer.clone())
45        }
46        CoreValue::Decimal(decimal) => {
47            DatexExpression::Decimal(decimal.clone())
48        }
49        CoreValue::TypedDecimal(typed_decimal) => {
50            DatexExpression::TypedDecimal(typed_decimal.clone())
51        }
52        CoreValue::Boolean(boolean) => DatexExpression::Boolean(boolean.0),
53        CoreValue::Text(text) => DatexExpression::Text(text.0.clone()),
54        CoreValue::Endpoint(endpoint) => {
55            DatexExpression::Endpoint(endpoint.clone())
56        }
57        CoreValue::Null => DatexExpression::Null,
58        CoreValue::List(list) => DatexExpression::List(
59            list.into_iter().map(DatexExpression::from).collect(),
60        ),
61        CoreValue::Map(map) => DatexExpression::Map(
62            map.into_iter()
63                .map(|(key, value)| {
64                    (
65                        DatexExpression::from(&ValueContainer::from(key)),
66                        DatexExpression::from(value),
67                    )
68                })
69                .collect(),
70        ),
71        CoreValue::Type(type_value) => {
72            DatexExpression::TypeExpression(match &type_value.type_definition {
73                TypeDefinition::Structural(struct_type) => match struct_type {
74                    StructuralTypeDefinition::Integer(integer) => {
75                        TypeExpression::Integer(integer.clone())
76                    }
77                    _ => todo!("#416 Undescribed by author."),
78                },
79                _ => todo!("#417 Undescribed by author."),
80            })
81        }
82        _ => todo!("#418 Undescribed by author."),
83    }
84}
85
86#[cfg(test)]
87mod tests {
88    use crate::ast::DatexExpression;
89    use crate::values::core_values::decimal::Decimal;
90    use crate::values::core_values::decimal::typed_decimal::TypedDecimal;
91    use crate::values::core_values::integer::Integer;
92    use crate::values::core_values::integer::typed_integer::TypedInteger;
93    use crate::values::value::Value;
94    use crate::values::value_container::ValueContainer;
95
96    #[test]
97    fn test_integer_to_ast() {
98        let value = ValueContainer::from(Integer::from(42));
99        let ast = DatexExpression::from(&value);
100        assert_eq!(ast, DatexExpression::Integer(Integer::from(42)));
101    }
102
103    #[test]
104    fn test_typed_integer_to_ast() {
105        let value = ValueContainer::from(TypedInteger::from(42i8));
106        let ast = DatexExpression::from(&value);
107        assert_eq!(
108            ast,
109            DatexExpression::TypedInteger(TypedInteger::from(42i8))
110        );
111    }
112
113    #[test]
114    fn test_decimal_to_ast() {
115        let value = ValueContainer::from(Decimal::from(1.23));
116        let ast = DatexExpression::from(&value);
117        assert_eq!(ast, DatexExpression::Decimal(Decimal::from(1.23)));
118    }
119
120    #[test]
121    fn test_typed_decimal_to_ast() {
122        let value = ValueContainer::from(TypedDecimal::from(2.71f32));
123        let ast = DatexExpression::from(&value);
124        assert_eq!(
125            ast,
126            DatexExpression::TypedDecimal(TypedDecimal::from(2.71f32))
127        );
128    }
129
130    #[test]
131    fn test_boolean_to_ast() {
132        let value = ValueContainer::from(true);
133        let ast = DatexExpression::from(&value);
134        assert_eq!(ast, DatexExpression::Boolean(true));
135    }
136
137    #[test]
138    fn test_text_to_ast() {
139        let value = ValueContainer::from("Hello, World!".to_string());
140        let ast = DatexExpression::from(&value);
141        assert_eq!(ast, DatexExpression::Text("Hello, World!".to_string()));
142    }
143
144    #[test]
145    fn test_null_to_ast() {
146        let value = ValueContainer::Value(Value::null());
147        let ast = DatexExpression::from(&value);
148        assert_eq!(ast, DatexExpression::Null);
149    }
150
151    #[test]
152    fn test_list_to_ast() {
153        let value = ValueContainer::from(vec![
154            Integer::from(1),
155            Integer::from(2),
156            Integer::from(3),
157        ]);
158        let ast = DatexExpression::from(&value);
159        assert_eq!(
160            ast,
161            DatexExpression::List(vec![
162                DatexExpression::Integer(Integer::from(1)),
163                DatexExpression::Integer(Integer::from(2)),
164                DatexExpression::Integer(Integer::from(3)),
165            ])
166        );
167    }
168}