1use crate::merge::Settings;
2
3pub fn serialize(settings: &Settings) -> String {
28 settings
29 .iter()
30 .map(|(key, value)| format!("{}={}\n", key, if let Some(x) = value { x } else { "" }))
31 .collect()
32}
33
34pub fn deserialize(input: &str) -> Settings {
59 let mut result = Settings::new();
60
61 input
62 .split('\n')
63 .filter(|line| !line.is_empty())
64 .for_each(|line| {
65 let mut splits = line.split('=').collect::<Vec<&str>>();
66 let key: String = splits.remove(0).into();
67 let value: Option<String> = if splits.is_empty() || splits.join("=") == "" {
68 None
69 } else {
70 Some(splits.join("="))
71 };
72 result.insert(key, value);
73 });
74
75 result
76}
77
78#[cfg(test)]
79mod test {
80
81 use crate::{merge, serde};
82
83 #[test]
84 fn test_seralization_one_value() {
85 let settings =
86 merge::Settings::from([("domain".into(), Some("https://benjaminsattler.net".into()))]);
87
88 let expected = String::from("domain=https://benjaminsattler.net\n");
89
90 assert_eq!(serde::serialize(&settings), expected);
91 }
92
93 #[test]
94 fn test_deseralization_one_value() {
95 let input = String::from("domain=https://benjaminsattler.net\n");
96
97 let actual = serde::deserialize(&input);
98
99 assert!(actual.contains_key("domain"));
100 assert_eq!(
101 actual.get("domain").unwrap(),
102 &Some("https://benjaminsattler.net".into())
103 );
104 }
105
106 #[test]
107 fn test_seralization_multiple_values() {
108 let settings = merge::Settings::from([
109 ("domain".into(), Some("https://benjaminsattler.net".into())),
110 ("port".into(), Some("443".into())),
111 ]);
112
113 let expected = String::from("domain=https://benjaminsattler.net\nport=443\n");
114
115 assert_eq!(serde::serialize(&settings), expected);
116 }
117
118 #[test]
119 fn test_deseralization_multiple_values() {
120 let input = String::from("port=443\ndomain=https://benjaminsattler.net\n");
121
122 let actual = serde::deserialize(&input);
123
124 assert!(actual.contains_key("domain"));
125 assert_eq!(
126 actual.get("domain").unwrap(),
127 &Some("https://benjaminsattler.net".into())
128 );
129 assert!(actual.contains_key("port"));
130 assert_eq!(actual.get("port").unwrap(), &Some("443".into()));
131 }
132
133 #[test]
134 fn test_seralization_sorting() {
135 let settings = merge::Settings::from([
136 ("port".into(), Some("443".into())),
137 ("domain".into(), Some("https://benjaminsattler.net".into())),
138 ]);
139
140 let expected = String::from("domain=https://benjaminsattler.net\nport=443\n");
141
142 assert_eq!(serde::serialize(&settings), expected);
143 }
144
145 #[test]
146 fn test_deseralization_sorting() {
147 let input = String::from("port=443\ndomain=https://benjaminsattler.net\n");
148
149 let actual = serde::deserialize(&input);
150
151 let mut actual_iter = actual.keys().into_iter();
152 assert_eq!(actual_iter.next(), Some(&"domain".into()));
153 assert_eq!(actual_iter.next(), Some(&"port".into()));
154 }
155
156 #[test]
157 fn test_seralization_equals_in_value() {
158 let settings =
159 merge::Settings::from([("domain".into(), Some("this=value_is_special".into()))]);
160
161 let expected = String::from("domain=this=value_is_special\n");
162
163 assert_eq!(serde::serialize(&settings), expected);
164 }
165
166 #[test]
167 fn test_deseralization_equals_in_value() {
168 let input = String::from("domain=this=value_is_special\n");
169
170 let actual = serde::deserialize(&input);
171
172 assert!(actual.contains_key("domain"));
173 assert_eq!(
174 actual.get("domain").unwrap(),
175 &Some("this=value_is_special".into())
176 );
177 }
178
179 #[test]
180 fn test_seralization_spaces_in_value() {
181 let settings =
182 merge::Settings::from([("domain".into(), Some("this value has spaces".into()))]);
183
184 let expected = String::from("domain=this value has spaces\n");
185
186 assert_eq!(serde::serialize(&settings), expected);
187 }
188
189 #[test]
190 fn test_deseralization_spaces_in_value() {
191 let input = String::from("domain=this value has spaces\n");
192
193 let actual = serde::deserialize(&input);
194
195 assert!(actual.contains_key("domain"));
196 assert_eq!(
197 actual.get("domain").unwrap(),
198 &Some("this value has spaces".into())
199 );
200 }
201
202 #[test]
203 fn test_seralization_empty_value() {
204 let settings = merge::Settings::from([("domain".into(), None)]);
205
206 let expected = String::from("domain=\n");
207
208 assert_eq!(serde::serialize(&settings), expected);
209 }
210
211 #[test]
212 fn test_deseralization_empty_value() {
213 let input = String::from("domain=\n");
214
215 let actual = serde::deserialize(&input);
216
217 assert!(actual.contains_key("domain"));
218 assert_eq!(actual.get("domain").unwrap(), &None);
219 }
220}