1use crate::internal::key_tree::Node as KeyNode;
5use anyhow::Result;
6use serde::{Deserialize, Serialize};
7use serde_cbor::Value as CborValue;
8use std::collections::BTreeMap;
9
10#[derive(thiserror::Error, Debug)]
11enum Error {
12 #[error("float types are currently unhandled")]
13 FloatUnhandled,
14}
15
16#[derive(Debug, PartialEq, Serialize, Deserialize)]
17pub(crate) enum Value {
19 Null,
20 Bool(bool),
21 Integer(i128),
22 Bytes(Vec<u8>),
23 Text(String),
24}
25
26impl Value {
27 pub(crate) fn to_cbor(&self) -> CborValue {
28 match self {
29 Value::Null => CborValue::Null,
30 Value::Bool(v) => CborValue::Bool(*v),
31 Value::Integer(v) => CborValue::Integer(*v),
32 Value::Bytes(v) => CborValue::Bytes(v.clone()),
33 Value::Text(v) => CborValue::Text(v.clone()),
34 }
35 }
36}
37
38#[derive(Debug, PartialEq, Serialize, Deserialize)]
39pub struct Node {
41 pub(crate) value: Option<Value>,
42 pub(crate) children: Vec<Node>,
43}
44
45impl Node {
46 pub fn new(src_value: CborValue) -> Result<Self> {
48 fn new_leaf(v: Value) -> Result<Node> {
49 Ok(Node {
50 value: Some(v),
51 children: vec![],
52 })
53 }
54 fn new_non_leaf(children: Vec<Node>) -> Result<Node> {
55 Ok(Node {
56 value: None,
57 children,
58 })
59 }
60
61 match src_value {
62 CborValue::Null => new_leaf(Value::Null),
63 CborValue::Bool(v) => new_leaf(Value::Bool(v)),
64 CborValue::Integer(v) => new_leaf(Value::Integer(v)),
65 CborValue::Float(_) => Err(Error::FloatUnhandled.into()),
66 CborValue::Bytes(v) => new_leaf(Value::Bytes(v)),
67 CborValue::Text(v) => new_leaf(Value::Text(v)),
68 CborValue::Tag(_, boxed_value) => Self::new(*boxed_value),
69 CborValue::Array(values) => new_non_leaf(
70 values
71 .into_iter()
72 .map(|v| Self::new(v))
73 .collect::<Result<Vec<Node>>>()?,
74 ),
75 CborValue::Map(tree_map) => new_non_leaf(
76 tree_map
77 .into_values()
78 .map(|v| Self::new(v))
79 .collect::<Result<Vec<Node>>>()?,
80 ),
81 CborValue::__Hidden => unreachable!(),
82 }
83 }
84
85 pub fn assign_keys(&self, key_node: &KeyNode) -> CborValue {
87 match &self.value {
88 Some(value) => value.to_cbor(),
89 None => {
90 if &key_node.children.len() > &(0usize) {
91 let mut map: BTreeMap<CborValue, CborValue> = BTreeMap::new();
92
93 for (i, child) in self.children.iter().enumerate() {
94 let key = &key_node.children.get(i).unwrap();
96 map.insert(
97 CborValue::Text(String::from(key.value.unwrap())),
98 child.assign_keys(key),
99 );
100 }
101
102 CborValue::Map(map)
103 } else {
104 let mut cbor_values: Vec<CborValue> = Vec::new();
105 for node in self.children.iter() {
106 cbor_values.push(node.assign_keys(&KeyNode::default()));
107 }
108 CborValue::Array(cbor_values)
109 }
110 }
111 }
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use serde::Serialize;
118 use serde_cbor::value::to_value;
119 use std::collections::BTreeMap;
120
121 use crate::internal::key_tree::GenerateNode;
122
123 use super::*;
124
125 #[test]
126 fn can_represent_null_value() {
127 assert_eq!(
128 Node::new(CborValue::Null).unwrap(),
129 Node {
130 value: Some(Value::Null),
131 children: vec![]
132 }
133 )
134 }
135
136 #[test]
137 fn can_represent_boolean_value() {
138 assert_eq!(
139 Node::new(CborValue::from(true)).unwrap(),
140 Node {
141 value: Some(Value::Bool(true)),
142 children: vec![]
143 }
144 );
145 assert_eq!(
146 Node::new(CborValue::from(false)).unwrap(),
147 Node {
148 value: Some(Value::Bool(false)),
149 children: vec![]
150 }
151 )
152 }
153
154 #[test]
155 fn can_represent_array() {
156 assert_eq!(
157 Node::new(CborValue::from(vec![
158 CborValue::from(vec![CborValue::Null]),
159 CborValue::Null,
160 ]))
161 .unwrap(),
162 Node {
163 value: None,
164 children: vec![
165 Node {
166 value: None,
167 children: vec![Node {
168 value: Some(Value::Null),
169 children: vec![]
170 }],
171 },
172 Node {
173 value: Some(Value::Null),
174 children: vec![]
175 },
176 ],
177 }
178 )
179 }
180
181 #[test]
182 fn can_represent_map() {
183 let mut tree_map = BTreeMap::new();
184 tree_map.insert(CborValue::Null, CborValue::Integer(0));
185 assert_eq!(
186 Node::new(CborValue::from(tree_map)).unwrap(),
187 Node {
188 value: None,
189 children: vec![Node {
190 value: Some(Value::Integer(0)),
191 children: vec![]
192 },],
193 }
194 )
195 }
196
197 #[test]
198 fn can_import_tagged_value() {
199 assert_eq!(
200 Node::new(CborValue::Tag(0, Box::from(CborValue::Null),)).unwrap(),
201 Node {
202 value: Some(Value::Null),
203 children: vec![]
204 }
205 )
206 }
207
208 #[test]
209 fn can_assign_map() {
210 #[derive(Eq, PartialEq, Serialize)]
211 struct Structure {
212 key: NestedStructure,
213 }
214 impl GenerateNode for Structure {
216 fn generate_node() -> KeyNode {
217 KeyNode {
218 value: None,
219 children: vec![KeyNode {
220 value: Some("key"),
221 children: NestedStructure::generate_node().children,
222 }],
223 }
224 }
225 }
226
227 #[derive(Eq, PartialEq, Serialize)]
228 struct NestedStructure {
229 key: u8,
230 }
231
232 impl GenerateNode for NestedStructure {
234 fn generate_node() -> KeyNode {
235 KeyNode {
236 value: None,
237 children: vec![KeyNode {
238 value: Some("key"),
239 children: u8::generate_node().children,
240 }],
241 }
242 }
243 }
244
245 let structure = Structure {
246 key: NestedStructure { key: 0 },
247 };
248
249 let structure_cbor = to_value(structure).unwrap();
250
251 let structure_data = Node::new(structure_cbor.clone()).unwrap();
252
253 let structure_assigned = structure_data.assign_keys(&Structure::generate_node());
254
255 assert_eq!(structure_cbor, structure_assigned);
256 }
257
258 #[test]
259 fn can_assign_array() {
260 #[derive(Eq, PartialEq, Serialize)]
261 struct Structure {
262 key: Vec<u8>,
263 }
264
265 impl GenerateNode for Structure {
267 fn generate_node() -> KeyNode {
268 KeyNode {
269 value: None,
270 children: vec![KeyNode {
271 value: Some("key"),
272 children: Vec::<u8>::generate_node().children,
273 }],
274 }
275 }
276 }
277
278 let structure = Structure {
279 key: vec![0, 1, 2, 3],
280 };
281
282 let structure_cbor = to_value(structure).unwrap();
283
284 let structure_data = Node::new(structure_cbor.clone()).unwrap();
285
286 let structure_assigned = structure_data.assign_keys(&Structure::generate_node());
287
288 assert_eq!(structure_cbor, structure_assigned);
289 }
290}