rof_rs/object_format/data_value/
enum_value.rs

1// Enum
2
3use crate::object_format::{
4    ignore_str_split::{ignoring_compliant_split_str, SplitIgnoreRule, SplitIgnoreRuleType},
5    property::{data_value_from_string, property_type::PropertyType, Property},
6    DataValue,
7};
8
9#[derive(Debug)]
10pub struct DataValueEnum {
11    enum_name: String,
12    enum_values: Vec<Property>,
13}
14
15impl DataValueEnum {
16    pub fn new(enum_name: String, enum_values: Vec<Property>) -> Self {
17        Self {
18            enum_name,
19            enum_values,
20        }
21    }
22
23    pub fn simple(enum_name: String) -> Self {
24        Self::new(enum_name, Vec::new())
25    }
26
27    pub fn none() -> Self {
28        Self::new(String::from("None"), Vec::new())
29    }
30}
31
32impl DataValue for DataValueEnum {
33    fn serialize(
34        &self,
35        pretty_print: bool,
36        tab_index: usize,
37    ) -> (
38        PropertyType, /* serialized type */
39        String,       /* serialized value */
40    ) {
41        (
42            PropertyType::new(
43                String::from("enum"),
44                self.enum_values
45                    .iter()
46                    .map(|enum_value| enum_value.property_value.get_type())
47                    .collect(),
48            ),
49            match self.enum_values.is_empty() {
50                true => format!("{}", self.enum_name),
51                false => format!(
52                    "{}({})",
53                    self.enum_name,
54                    self.enum_values
55                        .iter()
56                        .map(|property| property
57                            .property_value
58                            .serialize(pretty_print, tab_index)
59                            .1)
60                        .collect::<Vec<String>>()
61                        .join(match pretty_print {
62                            true => ", ",
63                            false => ",",
64                        })
65                ),
66            },
67        )
68    }
69
70    fn deserialize(
71        serialized_type: &PropertyType,
72        serialized_value: &str,
73    ) -> Option<Box<dyn DataValue>>
74    where
75        Self: Sized,
76    {
77        if !(serialized_type.get_base_type() == "enum"
78            || serialized_type.get_base_type() == "option")
79        {
80            return None;
81        }
82
83        match serialized_value.split_once("(") {
84            Some((enum_name, enum_data)) => {
85                let mut properties: Vec<Property> = Vec::new();
86
87                let mut sub_type_iter = serialized_type.get_sub_types().iter();
88
89                for serialized_property in ignoring_compliant_split_str(
90                    &enum_data[..enum_data.len() - 1].trim(),
91                    ',',
92                    true,
93                    vec![
94                        SplitIgnoreRule::new(SplitIgnoreRuleType::PAIR('"'))
95                            .set_ecapsulates_raw_text(true),
96                        SplitIgnoreRule::new(SplitIgnoreRuleType::PAIR('\''))
97                            .set_ecapsulates_raw_text(true),
98                        SplitIgnoreRule::new(SplitIgnoreRuleType::NEST('(', ')')),
99                        SplitIgnoreRule::new(SplitIgnoreRuleType::NEST('<', '>')),
100                    ],
101                ) {
102                    if serialized_property.trim().len() < 1 {
103                        continue;
104                    }
105
106                    if let Some(sub_type) = sub_type_iter.next() {
107                        properties.push(Property::unnamed(data_value_from_string(
108                            sub_type,
109                            serialized_property.trim(),
110                        )));
111                    } else {
112                        break;
113                    }
114                }
115
116                Some(Box::new(Self::new(enum_name.to_string(), properties)))
117            }
118            None => Some(Box::new(Self::new(
119                serialized_value.to_string(),
120                Vec::new(),
121            ))),
122        }
123    }
124
125    fn clone_data_value(&self) -> Box<dyn DataValue> {
126        Box::new(Self::new(self.enum_name.clone(), self.enum_values.clone()))
127    }
128
129    fn as_enum_structure(
130        &self,
131    ) -> (
132        String,                  /* enum name */
133        Vec<Box<dyn DataValue>>, /* enum values */
134    ) {
135        (
136            self.enum_name.clone(),
137            self.enum_values
138                .iter()
139                .map(|enum_value| enum_value.property_value.clone_data_value())
140                .collect(),
141        )
142    }
143
144    fn as_bool(&self) -> bool {
145        self.enum_name == "Some"
146    }
147
148    fn as_string(&self) -> String {
149        self.enum_name.clone()
150    }
151}