1use crate::error::RoSVByteError;
2use crate::{ROSV_FIELD_END, ROSV_FIELD_NULL, ROSV_ROW_END, RoSVContainer, SerializeToU8};
3use error_stack::{Result, ResultExt};
4
5pub fn serialize_rosv<'a, Inner, IterValues, IterRows>(
7 data: IterRows,
8) -> Result<Vec<u8>, RoSVByteError>
9where
10 Inner: SerializeToU8 + 'a,
11 IterValues: IntoIterator<Item = &'a Option<Inner>>,
12 IterRows: IntoIterator<Item = IterValues>,
13{
14 let mut stream = Vec::default();
15
16 for datum in data {
17 stream.extend(serialize_to_rosv_row(datum)?);
18 }
19
20 Ok(stream)
21}
22
23fn serialize_to_rosv_row<'a, Inner, Iterable>(data: Iterable) -> Result<Vec<u8>, RoSVByteError>
25where
26 Inner: SerializeToU8 + 'a,
27 Iterable: IntoIterator<Item = &'a Option<Inner>>,
28{
29 let mut stream = Vec::default();
30
31 for datum in data {
32 match datum {
33 Some(chunk) => {
34 stream.extend(chunk.to_u8()?);
35 stream.push(ROSV_FIELD_END);
36 }
37 None => {
38 stream.push(ROSV_FIELD_NULL);
39 }
40 }
41 }
42
43 stream.push(ROSV_ROW_END);
44
45 Ok(stream)
46}
47
48pub fn deserialize_rosv<IterRows>(stream: IterRows) -> Result<RoSVContainer, RoSVByteError>
50where
51 IterRows: IntoIterator<Item = u8>,
52{
53 let mut output: Vec<Vec<Option<String>>> = RoSVContainer::new();
54 let mut row = Vec::new();
55 let mut field = Vec::new();
56
57 for byte in stream {
58 match byte {
59 ROSV_FIELD_END => {
60 let s = String::from_utf8(field)
61 .change_context_lazy(|| RoSVByteError::DecodingError)?;
64 row.push(Some(s));
65 field = Vec::new();
66 }
67 ROSV_FIELD_NULL => {
68 row.push(None);
69 }
70 ROSV_ROW_END => {
71 output.push(row);
72 row = Vec::new();
73 }
74 b => field.push(b),
75 }
76 }
77
78 Ok(output)
79}