rsv_data/
core.rs

1//!Core module used for encoding and decoding RSV data
2//!
3//!Here's an example for input to the encoder:
4//!
5//!```
6//!let input: Vec<Vec<Option<String>>> = vec![
7//!    vec![Some("Hello user!".to_string()), None],
8//!    vec![Some("\n\\\'\"".to_string()), Some("😁🔃📖".to_string())]
9//!];
10//!```
11
12pub type Res<T> = Result<T, Box<dyn std::error::Error>>;
13
14pub fn encode_rsv(rows: &Vec<Vec<Option<String>>>) -> Vec<u8> {
15    let mut parts: Vec<&[u8]> = vec![];
16
17    for row in rows {
18        for value in row {
19            match value {
20                //Pushes byte for null data
21                None => parts.push(b"\xFE"),
22                //Pushes bytes for non null data
23                Some(str_value) => {
24                    if !str_value.is_empty() {
25                        parts.push(str_value.as_bytes());
26                    }
27                }
28            }
29
30            parts.push(b"\xFF");
31        }
32
33        parts.push(b"\xFD");
34    }
35
36    //Returns bianary data for RSV file
37    parts.concat()
38}
39
40pub fn decode_rsv(bytes: &Vec<u8>) -> Res<Vec<Vec<Option<String>>>> {
41    //Check for valid end charecter in RSV input
42    if !bytes.is_empty() && bytes[bytes.len() - 1] != 0xFD {
43        return Err("Incomplete RSV document".into());
44    }
45
46    let mut result: Vec<Vec<Option<String>>> = Vec::new();
47    let mut current_row: Vec<Option<String>> = Vec::new();
48    let mut value_start_index = 0;
49
50    for i in 0..bytes.len() {
51        if bytes[i] == 0xFF {
52            let length = i - value_start_index;
53
54            if length == 0 {
55                current_row.push(Some(String::new()));
56            } else if length == 1 && bytes[value_start_index] == 0xFE {
57                current_row.push(None);
58            } else {
59                let value_bytes = bytes[value_start_index..i].to_vec();
60
61                if let Ok(str_value) = String::from_utf8(value_bytes) {
62                    current_row.push(Some(str_value));
63                } else {
64                    return Err("Invalid string value".into());
65                }
66            }
67
68            value_start_index = i + 1;
69        } else if bytes[i] == 0xFD {
70            if i > 0 && value_start_index != i {
71                return Err("Incomplete RSV row".into());
72            }
73
74            result.push(current_row);
75            current_row = Vec::new();
76            value_start_index = i + 1;
77        }
78    }
79
80    //Return table
81    Ok(result)
82}
83