1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use serde::{Serialize, Deserialize};
use std::io;
use crate::file as inner;
use super::Serialization;
#[derive(Default)]
pub struct Toml;
impl<'de, T: Serialize + Deserialize<'de>> Serialization<'de, T> for Toml {
fn serialize(data: &T) -> Result<Vec<u8>, io::Error> {
toml::to_vec(data).map_err(|error| io::Error::new(io::ErrorKind::Other, error))
}
fn serialize_into(data: &T, writer: &mut inner::Storage) -> Result<(), io::Error> {
let data = toml::to_vec(data).map_err(|error| io::Error::new(io::ErrorKind::Other, error))?;
match data.len() {
0 => Err(super::empty_write_error()),
_ => writer.put_data(&data)
}
}
fn deserialize(bytes: &'de [u8]) -> Result<T, io::Error> {
toml::from_slice(bytes).map_err(|error| io::Error::new(io::ErrorKind::Other, error))
}
}
#[cfg(test)]
mod tests {
use super::Toml;
use super::super::{FileView};
use std::fs;
use std::collections::HashMap;
#[test]
fn should_handle_toml_file_view() {
const STORAGE_PATH: &'static str = "test_file_view.toml";
let _ = fs::remove_file(STORAGE_PATH);
{
let result = FileView::<HashMap<String, String>, Toml>::open_or_default(STORAGE_PATH);
assert!(result.is_err());
}
{
let mut default_map = HashMap::new();
default_map.insert(1.to_string(), "".to_string());
let storage = FileView::<HashMap<String, String>, Toml>::open_or(STORAGE_PATH, &default_map).expect("Open with provided default data");;
let data = storage.load().expect("To load data from empty file");
assert_eq!(data.len(), default_map.len());
assert_eq!(data.get(&1.to_string()).expect("To find key 1"), "");
}
let _ = fs::remove_file(STORAGE_PATH);
let new_len = {
let mut storage = FileView::<HashMap<String, String>, Toml>::open(STORAGE_PATH).expect("To create file");
let mut data = storage.load().expect("To load data from empty file");
assert_eq!(data.len(), 0);
data.insert(1.to_string(), "".to_string());
data.insert(2.to_string(), "two".to_string());
data.insert(3.to_string(), "".to_string());
data.insert(4.to_string(), "".to_string());
data.insert(5.to_string(), "".to_string());
data.insert(4.to_string(), "four".to_string());
storage.save_sync(&data).expect("To save modified data");
data.len()
};
{
let storage = FileView::<HashMap<usize, Option<String>>, Toml>::open(STORAGE_PATH).expect("To load");
assert!(storage.load().is_err());
}
let expected = [
(1, ""),
(2, "two"),
(3, ""),
(4, "four"),
(5, "")
];
{
let mut storage = FileView::<HashMap<String, String>, Toml>::open(STORAGE_PATH).expect("To open file");
let data = storage.load().expect("To load data");
assert_eq!(data.len(), new_len);
for (expected_key, expected_val) in expected.iter() {
let expected_val: &str = expected_val;
let value: &str = data.get(&expected_key.to_string()).expect("To find key");
assert_eq!(value, expected_val);
}
storage.save_sync(&data).expect("To save data");
let _data = storage.load_owned().expect("To load owned data");
}
{
let mut storage = FileView::<HashMap<&str, &str>, Toml>::open(STORAGE_PATH).expect("To open file");
storage.modify(|data| {
data
}).expect("To modify");
let data = storage.load().expect("To load data");
assert_eq!(data.len(), new_len);
for (expected_key, expected_val) in expected.iter() {
let expected_val: &str = expected_val;
let value: &str = data.get(&expected_key.to_string().as_ref()).expect("To find key");
assert_eq!(value, expected_val);
}
}
let _ = fs::remove_file(STORAGE_PATH);
}
}