rosv/
serialization.rs

1use crate::{RoSVContainer, SerializeToU8, ROSV_FIELD_END, ROSV_FIELD_NULL, ROSV_ROW_END};
2use std::string::FromUtf8Error;
3
4/// Consume stream to output (probably) a RoSVContainer.
5/// Outputs Strings because everything is utf-8 for some reason.
6pub fn serialize_rosv<'a, Inner, IterValues, IterRows>(data: IterRows) -> Vec<u8>
7where
8    Inner: SerializeToU8 + 'a,
9    IterValues: IntoIterator<Item = &'a Option<Inner>>,
10    IterRows: IntoIterator<Item = IterValues>,
11{
12    let mut stream = Vec::default();
13
14    for datum in data {
15        stream.extend(serialize_to_rosv_row(datum));
16    }
17
18    stream
19}
20
21fn serialize_to_rosv_row<'a, Inner, Iterable>(data: Iterable) -> Vec<u8>
22where
23    Inner: SerializeToU8 + 'a,
24    Iterable: IntoIterator<Item = &'a Option<Inner>>,
25{
26    let mut stream = Vec::default();
27
28    for datum in data {
29        match datum {
30            Some(chunk) => {
31                stream.extend(chunk.to_u8());
32                stream.push(ROSV_FIELD_END);
33            }
34            None => {
35                stream.push(ROSV_FIELD_NULL);
36            }
37        }
38    }
39
40    stream.push(ROSV_ROW_END);
41
42    stream
43}
44
45/// Read iterable to u8 stream.
46pub fn deserialize_rosv<IterRows>(stream: IterRows) -> Result<RoSVContainer, FromUtf8Error>
47where
48    IterRows: IntoIterator<Item = u8>,
49{
50    let mut output: Vec<Vec<Option<String>>> = RoSVContainer::new();
51    let mut row = Vec::new();
52    let mut field = Vec::new();
53
54    for byte in stream {
55        match byte {
56            ROSV_FIELD_END => {
57                row.push(Some(String::from_utf8(field)?));
58                field = Vec::new();
59            }
60            ROSV_FIELD_NULL => {
61                row.push(None);
62            }
63            ROSV_ROW_END => {
64                output.push(row);
65                row = Vec::new();
66            }
67            b => field.push(b),
68        }
69    }
70
71    Ok(output)
72}