hff_core/utilities/
ksv.rs1use super::StringVec;
2use crate::{
3 byteorder::{ByteOrder, ReadBytesExt, WriteBytesExt},
4 Ecc, Endian, Error, Result, BE, LE, NE,
5};
6use std::{
7 collections::BTreeMap,
8 io::{copy, Read, Write},
9 ops::{Deref, DerefMut},
10};
11
12#[derive(Debug, Clone, Eq, PartialEq)]
16pub struct Ksv {
17 value_map: BTreeMap<String, StringVec>,
19}
20
21impl Ksv {
22 const ID: Ecc = Ecc::new("STR_VEC");
24
25 pub fn new() -> Self {
27 Self {
28 value_map: BTreeMap::new(),
29 }
30 }
31
32 pub fn to_bytes<E: ByteOrder>(self) -> Result<Vec<u8>> {
34 let mut bytes = vec![];
35 let writer: &mut dyn Write = &mut bytes;
36
37 Self::ID.write::<E>(writer)?;
38 writer.write_u64::<E>(self.value_map.len() as u64)?;
39
40 for (k, v) in self.value_map {
41 let kbytes = k.as_bytes();
43 writer.write_u64::<E>(kbytes.len() as u64)?;
44 writer.write_all(kbytes)?;
45
46 let vbytes = v.to_bytes::<E>()?;
48 writer.write_u64::<E>(vbytes.len() as u64)?;
49 copy(&mut vbytes.as_slice(), writer)?;
50 }
51
52 Ok(bytes)
53 }
54
55 pub fn from_bytes(mut bytes: &[u8]) -> Result<Self> {
57 let reader: &mut dyn Read = &mut bytes;
59 let id = Ecc::from(reader.read_u64::<NE>()?);
65 match id.endian(Self::ID) {
66 Some(endian) => match endian {
67 Endian::Big => Self::from_bytes_endian::<BE>(reader),
68 Endian::Little => Self::from_bytes_endian::<LE>(reader),
69 },
70 None => Err(Error::Invalid("Not a string vector.".into())),
71 }
72 }
73
74 fn from_bytes_endian<E: ByteOrder>(reader: &mut dyn Read) -> Result<Self> {
76 let count = reader.read_u64::<E>()?;
77 let mut result = Self::new();
78 for _ in 0..count {
79 let len = reader.read_u64::<E>()?;
81 let mut s = vec![0; len as usize];
82 reader.read_exact(&mut s)?;
83
84 let len = reader.read_u64::<E>()?;
86 let mut v = vec![0; len as usize];
87 reader.read_exact(&mut v)?;
88 let v = StringVec::from_bytes(&v)?;
89
90 result.insert(std::str::from_utf8(&s)?.to_owned(), v);
92 }
93
94 Ok(result)
95 }
96}
97
98impl<I, S> From<I> for Ksv
99where
100 I: Iterator<Item = (S, StringVec)>,
101 S: AsRef<str>,
102{
103 fn from(value: I) -> Self {
104 let mut result = Self::new();
105 for (k, v) in value {
106 result.insert(k.as_ref().to_owned(), v);
107 }
108 result
109 }
110}
111
112impl Deref for Ksv {
113 type Target = BTreeMap<String, StringVec>;
114
115 fn deref(&self) -> &Self::Target {
116 &self.value_map
117 }
118}
119
120impl DerefMut for Ksv {
121 fn deref_mut(&mut self) -> &mut Self::Target {
122 &mut self.value_map
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[test]
131 fn simple() {
132 let test_data: &[(&'static str, StringVec)] = &[
133 ("1", ["this", "is"].iter().into()),
134 ("2", ["test", "data"].iter().into()),
135 ("3", ["for", "Ksv", "containers."].iter().into()),
136 ];
137 let test: Ksv = test_data.to_owned().into_iter().into();
138 let bytes = test.to_bytes::<LE>().unwrap();
139 let result = Ksv::from_bytes(&bytes).unwrap();
140
141 assert_eq!(Ksv::from(test_data.to_owned().into_iter()), result);
142 }
143}