rsv_data/
lib.rs

1//!RSV is a minimal bianary alternative to CSV solving some of its problems, escape charecters and
2//!encoding. RSV aims to solve this by representing new data and new rows with special bytes that
3//!no utf8 string can contain. This allows for strings with no escape charecters.
4//!This code was adapted from the code at <https://github.com/Stenway/RSV-Challenge/blob/main/Rust/src/main.rs>
5//!
6//!Heres some examples on how to use this:
7//!
8//!Open RSV file and assign some data to it
9//!```
10//!let mut data: Rsv = Rsv::open("myRsv.rsv").unwrap();
11//!data.set_data(vec![
12//!    vec![Some("Hello user".to_string()), None],
13//!    vec![Some("\n\\\'\"".to_string()), Some("😁🔃📖".to_string())]
14//!]);
15//!
16//!data.save().unwrap();
17//!```
18//!
19//!Create RSV file and assign some data to it
20//!```
21//!let mut data: Rsv = Rsv::create("myRsv.rsv").unwrap();
22//!data.set_data(vec![
23//!    vec![Some("Hello user".to_string()), None],
24//!    vec![Some("\n\\\'\"".to_string()), Some("😁🔃📖".to_string())]
25//!]);
26//!
27//!data.save().unwrap();
28//!```
29
30use std::io::{Read, Write};
31
32pub mod core;
33
34///Convience/Abstraction struct for RSV, allows opening, creating, saving, and retrieving data;
35pub struct Rsv {
36    file: String,
37    data: Vec<Vec<Option<String>>>,
38}
39
40impl Rsv {
41    pub fn create(file_name: &str) -> core::Res<()> {
42        let mut file = std::fs::File::create(file_name)?;
43        //Adding valid end byte
44        let byte = [0xFD];
45        file.write_all(&byte)?;
46
47        Ok(())
48    }
49
50    pub fn open(file_name: &str) -> core::Res<Self> {
51        let mut file = std::fs::File::open(file_name)?;
52        let mut bytes = vec![];
53        file.read_to_end(&mut bytes)?;
54
55        let data = core::decode_rsv(&bytes)?;
56
57        Ok(Rsv {
58            file: String::from(file_name),
59            data,
60        })
61    }
62
63    pub fn save(&self) -> core::Res<()> {
64        let mut file = std::fs::File::open(&self.file)?;
65        file.write_all(&core::encode_rsv(&self.data))?;
66
67        Ok(())
68    }
69
70    pub fn data(&self) -> Vec<Vec<Option<String>>> {
71        self.data.clone()
72    }
73
74    pub fn set_data(&mut self, data: Vec<Vec<Option<String>>>) {
75        self.data = data;
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    #[test]
82    fn test_encode_decode() {
83        let data = vec![
84            vec![Some(String::from("Hello world")), None],
85            vec![Some(String::from("☀️"))],
86        ];
87
88        let encoded_data = crate::core::encode_rsv(&data);
89
90        assert_eq!(data, crate::core::decode_rsv(&encoded_data).unwrap());
91    }
92
93    #[test]
94    fn test_decode_error() {
95        let mut data = crate::core::encode_rsv(&vec![vec![None]]);
96        data.pop();
97
98        if crate::core::decode_rsv(&data).is_ok() {
99            panic!("Expected Err, but got Ok");
100        }
101    }
102}