rof_rs/object_format/data_value/
hashmap.rs1use std::collections::HashMap;
4
5use crate::object_format::{
6 ignore_str_split::{
7 ignoring_compliant_split_once, ignoring_compliant_split_str, SplitIgnoreRule,
8 SplitIgnoreRuleType,
9 },
10 property::{data_value_from_string, property_type::PropertyType},
11 DataValue,
12};
13
14#[derive(Debug)]
15pub struct DataValueHashmap {
16 key_type: PropertyType,
17 value_type: PropertyType,
18 properties: HashMap<Box<dyn DataValue>, Box<dyn DataValue>>,
19}
20
21impl DataValueHashmap {
22 pub fn new(
23 key_type: PropertyType,
24 value_type: PropertyType,
25 properties: HashMap<Box<dyn DataValue>, Box<dyn DataValue>>,
26 ) -> Self {
27 Self {
28 key_type,
29 value_type,
30 properties,
31 }
32 }
33}
34
35impl DataValue for DataValueHashmap {
36 fn serialize(
37 &self,
38 pretty_print: bool,
39 tab_index: usize,
40 ) -> (
41 PropertyType, String, ) {
44 (
45 PropertyType::complex(
46 String::from("hashmap"),
47 vec![self.key_type.clone(), self.value_type.clone()],
48 ),
49 match pretty_print {
50 true => format!(
51 "{{\n{}\n{}}}",
52 self.properties
53 .iter()
54 .map(|(property_key, property_value)| format!(
55 "{}{}: {};",
56 "\t".repeat(tab_index + 1),
57 property_key.serialize(pretty_print, tab_index).1,
58 property_value.serialize(pretty_print, tab_index).1
59 ))
60 .collect::<Vec<String>>()
61 .join("\n"),
62 "\t".repeat(tab_index)
63 ),
64 false => format!(
65 "{{{}}}",
66 self.properties
67 .iter()
68 .map(|(property_key, property_value)| format!(
69 "{}:{};",
70 property_key.serialize(pretty_print, tab_index).1,
71 property_value.serialize(pretty_print, tab_index).1
72 ))
73 .collect::<Vec<String>>()
74 .join("")
75 ),
76 },
77 )
78 }
79
80 fn deserialize(
81 serialized_type: &PropertyType,
82 serialized_value: &str,
83 ) -> Option<Box<dyn DataValue>>
84 where
85 Self: Sized,
86 {
87 if !(serialized_type.get_base_type() == "hashmap"
88 && serialized_type.get_sub_types().len() == 2)
89 {
90 return None;
91 }
92
93 if !(serialized_value.starts_with("{")
94 && serialized_value.ends_with("}")
95 && serialized_value.chars().count() > 1)
96 {
97 return None;
98 }
99
100 let mut properties: HashMap<Box<dyn DataValue>, Box<dyn DataValue>> = HashMap::new();
101
102 for serialized_property in ignoring_compliant_split_str(
103 &serialized_value[1..serialized_value.len() - 1].trim(),
104 ';',
105 true,
106 vec![
107 SplitIgnoreRule::new(SplitIgnoreRuleType::PAIR('"')).set_ecapsulates_raw_text(true),
108 SplitIgnoreRule::new(SplitIgnoreRuleType::PAIR('\''))
109 .set_ecapsulates_raw_text(true),
110 SplitIgnoreRule::new(SplitIgnoreRuleType::NEST('{', '}')),
111 ],
112 ) {
113 if serialized_property.trim().len() < 1 {
114 continue;
115 }
116
117 if let Some((serialized_key, serialized_value)) = ignoring_compliant_split_once(
118 &serialized_property,
119 ':',
120 true,
121 vec![
122 SplitIgnoreRule::new(SplitIgnoreRuleType::PAIR('"'))
123 .set_ecapsulates_raw_text(true),
124 SplitIgnoreRule::new(SplitIgnoreRuleType::PAIR('\''))
125 .set_ecapsulates_raw_text(true),
126 SplitIgnoreRule::new(SplitIgnoreRuleType::NEST('{', '}')),
127 ],
128 ) {
129 properties.insert(
130 data_value_from_string(
131 serialized_type.get_sub_types().get(0).unwrap(),
132 &serialized_key.trim(),
133 ),
134 data_value_from_string(
135 serialized_type.get_sub_types().get(1).unwrap(),
136 &serialized_value.trim(),
137 ),
138 );
139 }
140 }
141
142 Some(Box::new(Self::new(
143 serialized_type.get_sub_types().get(0).unwrap().clone(),
144 serialized_type.get_sub_types().get(1).unwrap().clone(),
145 properties,
146 )))
147 }
148
149 fn clone_data_value(&self) -> Box<dyn DataValue> {
150 let mut cloned_properties: HashMap<Box<dyn DataValue>, Box<dyn DataValue>> = HashMap::new();
151
152 for (property_key, property_value) in self.properties.iter() {
153 cloned_properties.insert(
154 property_key.clone_data_value(),
155 property_value.clone_data_value(),
156 );
157 }
158
159 Box::new(Self::new(
160 self.key_type.clone(),
161 self.value_type.clone(),
162 cloned_properties,
163 ))
164 }
165
166 fn as_hashmap(&self) -> HashMap<Box<dyn DataValue>, Box<dyn DataValue>> {
167 let mut hashmap: HashMap<Box<dyn DataValue>, Box<dyn DataValue>> = HashMap::new();
168
169 for (property_key, property_value) in self.properties.iter() {
170 hashmap.insert(
171 property_key.clone_data_value(),
172 property_value.clone_data_value(),
173 );
174 }
175
176 hashmap
177 }
178}