hff_core/utilities/
hierarchical.rs1use crate::{Ecc, Endian, Error, Result, BE, LE, NE};
2use byteorder::{ByteOrder, ReadBytesExt, WriteBytesExt};
3use std::io::{Read, Write};
4
5#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
7pub struct Hierarchical {
8 key: String,
10 content: Vec<String>,
12 children: Vec<Hierarchical>,
14}
15
16impl Hierarchical {
17 const ID: Ecc = Ecc::new("STR_HIER");
19
20 pub fn new<T: Into<String>>(key: T, content: Vec<String>, children: Vec<Self>) -> Self {
22 Self {
23 key: key.into(),
24 content,
25 children,
26 }
27 }
28
29 pub fn key(&self) -> &str {
31 &self.key
32 }
33
34 pub fn key_mut(&mut self) -> &mut String {
36 &mut self.key
37 }
38
39 pub fn content(&self) -> &[String] {
41 &self.content
42 }
43
44 pub fn content_mut(&mut self) -> &mut Vec<String> {
46 &mut self.content
47 }
48
49 pub fn push<T: Into<String>>(&mut self, item: T) {
51 self.content.push(item.into());
52 }
53
54 pub fn children(&self) -> &[Self] {
56 &self.children
57 }
58
59 pub fn children_mut(&mut self) -> &mut Vec<Self> {
61 &mut self.children
62 }
63
64 pub fn push_child(&mut self, item: Self) {
66 self.children.push(item);
67 }
68
69 pub fn to_bytes<E: ByteOrder>(self) -> Result<Vec<u8>> {
71 let mut bytes = vec![];
73 let writer: &mut dyn Write = &mut bytes;
74
75 Self::ID.write::<E>(writer)?;
77
78 self.write_structure::<E>(writer)?;
80
81 Ok(bytes)
85 }
86
87 fn write_structure<E: ByteOrder>(self, writer: &mut dyn Write) -> Result<()> {
89 Self::write_string::<E>(&self.key, writer)?;
91
92 writer.write_u32::<E>(self.content.len() as u32)?;
94 for s in self.content {
96 Self::write_string::<E>(&s, writer)?;
97 }
98
99 writer.write_u32::<E>(self.children.len() as u32)?;
102 for c in self.children {
103 c.write_structure::<E>(writer)?;
104 }
105
106 Ok(())
107 }
108
109 fn write_string<E: ByteOrder>(value: &str, writer: &mut dyn Write) -> Result<()> {
111 if value.len() > core::u16::MAX as usize {
113 return Err(Error::Invalid("String length greater than max u16!".into()));
114 }
115 writer.write_u16::<E>(value.len() as u16)?;
116 writer.write_all(value.as_bytes())?;
117
118 Ok(())
119 }
120
121 pub fn from_bytes(mut bytes: &[u8]) -> Result<Self> {
125 let reader: &mut dyn Read = &mut bytes;
127
128 let id = Ecc::from(reader.read_u64::<NE>()?);
130 match id.endian(Self::ID) {
131 Some(Endian::Big) => Ok(Self::from_reader::<BE>(reader)?),
132 Some(Endian::Little) => Ok(Self::from_reader::<LE>(reader)?),
133 None => Err(Error::Invalid("Not a valid hierarchical.".into())),
134 }
135 }
136
137 fn from_reader<E: ByteOrder>(reader: &mut dyn Read) -> Result<Self> {
139 let key = Self::read_string::<E>(reader)?;
141
142 let content_count = reader.read_u32::<E>()?;
144 let mut content = vec![];
145 for _ in 0..content_count {
146 content.push(Self::read_string::<E>(reader)?);
147 }
148
149 let child_count = reader.read_u32::<E>()?;
151 let mut children = vec![];
152 for _ in 0..child_count {
153 children.push(Self::from_reader::<E>(reader)?);
154 }
155
156 Ok(Self {
157 key,
158 content,
159 children,
160 })
161 }
162
163 fn read_string<E: ByteOrder>(reader: &mut dyn Read) -> Result<String> {
165 let len = reader.read_u16::<E>()?;
166 let mut buffer = vec![0; len as usize];
167 reader.read_exact(buffer.as_mut_slice())?;
168
169 Ok(std::str::from_utf8(buffer.as_slice())?.into())
170 }
171}
172
173#[cfg(test)]
174mod test {
175 use super::*;
176
177 #[test]
178 fn test_serialization() {
179 let test = Hierarchical::new(
180 "Bah",
181 vec![String::from("1"), String::from("2")],
182 vec![Hierarchical::new(
183 "Humbug",
184 vec![String::from("3"), String::from("4")],
185 vec![],
186 )],
187 );
188
189 let bytes = test.clone().to_bytes::<NE>().unwrap();
190 let result = Hierarchical::from_bytes(bytes.as_slice()).unwrap();
191 assert_eq!(test, result);
192 }
193}