rosv/
serialization.rs

1use crate::error::RoSVByteError;
2use crate::{ROSV_FIELD_END, ROSV_FIELD_NULL, ROSV_ROW_END, RoSVContainer, SerializeToU8};
3use error_stack::{Result, ResultExt};
4
5/// Consume stream to output (probably) a RoSVContainer.
6pub 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
23/// Consume stream to output a single row of RoSV data.
24fn 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
48/// Read iterable to u8 stream.
49pub 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                    // Should not fail in normal use, and even most abnormal use.
62                    // One day I'll figure out how to make this happen.
63                    .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}