gitconfig/
value.rs

1use std::error::Error;
2use std::str;
3use std::iter::FromIterator;
4
5pub use map::Map;
6use map::Entry;
7
8#[derive(PartialEq, Clone, Debug)]
9pub enum Value {
10    String(String),
11    Object(Map<String, Value>),
12}
13
14impl Value {
15    /// Returns true if the `Value` is an Object. Returns false otherwise.
16    ///
17    /// For any Value on which `is_object` returns true, `as_object` and
18    /// `as_object_mut` are guaranteed to return the map representation of the
19    /// object.
20    pub fn is_object(&self) -> bool {
21        self.as_object().is_some()
22    }
23
24    /// If the `Value` is an Object, returns the associated Map. Returns None
25    /// otherwise.
26    pub fn as_object(&self) -> Option<&Map<String, Value>> {
27        match *self {
28            Value::Object(ref map) => Some(map),
29            _ => None,
30        }
31    }
32
33    /// If the `Value` is an Object, returns the associated mutable Map.
34    /// Returns None otherwise.
35    pub fn as_object_mut(&mut self) -> Option<&mut Map<String, Value>> {
36        match *self {
37            Value::Object(ref mut map) => Some(map),
38            _ => None,
39        }
40    }
41}
42
43impl str::FromStr for Value {
44    type Err = Box<Error>;
45    fn from_str(s: &str) -> Result<Value, Box<Error>> {
46        let git_configs = Vec::from_iter(s.split("\0").map(String::from));
47        let mut map = Map::new();
48
49        for git_config in &git_configs {
50            if git_config.is_empty() {
51                continue;
52            }
53            let (keys, value) = split_once(git_config);
54            if keys.len() == 0 {
55                continue;
56            }
57            let split_keys = Vec::from_iter(keys.split(".").map(String::from));
58            match split_keys.len() {
59                1 => {
60                    map.insert(split_keys[0].to_owned(), Value::String(value.to_owned()));
61                    ()
62                }
63                2 => {
64                    // TODO: split_keys[0].clone() why clone??
65                    match map.entry(split_keys[0].clone()) {
66                        Entry::Occupied(mut occupied) => {
67                            occupied.get_mut().as_object_mut().unwrap().insert(
68                                split_keys[1]
69                                    .to_owned(),
70                                Value::String(
71                                    value.to_owned(),
72                                ),
73                            );
74                            ()
75                        }
76                        Entry::Vacant(vacant) => {
77                            let mut internal = Map::new();
78                            internal.insert(
79                                split_keys[1].to_owned(),
80                                Value::String(value.to_owned()),
81                            );
82                            vacant.insert(Value::Object(internal));
83                            ()
84                        }
85                    }
86                }
87                n if n >= 3 => {
88                    // TODO: split_keys[0].clone() why clone??
89                    match map.entry(split_keys[0].clone()) {
90                        Entry::Occupied(mut occupied) => {
91                            match occupied.get_mut().as_object_mut().unwrap().entry(
92                                split_keys
93                                    [1..n - 1]
94                                    .join("."),
95                            ) {
96                                Entry::Occupied(mut occupied2) => {
97                                    occupied2.get_mut().as_object_mut().unwrap().insert(
98                                        split_keys[n - 1]
99                                            .to_owned(),
100                                        Value::String(
101                                            value.to_owned(),
102                                        ),
103                                    );
104                                    ()
105                                }
106                                Entry::Vacant(vacant2) => {
107                                    let mut internal = Map::new();
108                                    internal.insert(
109                                        split_keys[n - 1].to_owned(),
110                                        Value::String(value.to_owned()),
111                                    );
112                                    vacant2.insert(Value::Object(internal));
113                                    ()
114                                }
115                            }
116                        }
117                        Entry::Vacant(vacant) => {
118                            let mut internal = Map::new();
119                            internal.insert(
120                                split_keys[n - 1].to_owned(),
121                                Value::String(value.to_owned()),
122                            );
123                            let mut external = Map::new();
124                            external.insert(
125                                split_keys[1..n - 1].join("."),
126                                Value::Object(internal),
127                            );
128                            vacant.insert(Value::Object(external));
129                            ()
130                        }
131                    }
132                }
133                _ => return Err(From::from("unexpected something happens.".to_owned())),
134            }
135        }
136
137        Ok(Value::Object(map))
138    }
139}
140
141#[cfg(test)]
142mod tests {
143    use super::*;
144    #[test]
145    fn parse_empty() {
146        let actual = "";
147        let expected = Value::Object(Map::new());
148        assert_eq!(actual.parse::<Value>().unwrap(), expected);
149    }
150
151    #[test]
152    fn parse_empty2() {
153        let actual = "\n";
154        let expected = Value::Object(Map::new());
155        assert_eq!(actual.parse::<Value>().unwrap(), expected);
156    }
157
158    #[test]
159    fn parse_empty3() {
160        let actual = "\n\n\n\n\n";
161        let expected = Value::Object(Map::new());
162        assert_eq!(actual.parse::<Value>().unwrap(), expected);
163    }
164
165    #[test]
166    fn parse_key_and_empty_value() {
167        let actual = "key\n";
168        let mut internal = Map::new();
169        internal.insert("key".to_owned(), Value::String("".to_owned()));
170        let expected = Value::Object(internal);
171        assert_eq!(actual.parse::<Value>().unwrap(), expected);
172    }
173
174    #[test]
175    fn parse_one_key_and_value() {
176        let actual = "key\nvalue\nvalue";
177        let mut internal = Map::new();
178        internal.insert("key".to_owned(), Value::String("value\nvalue".to_owned()));
179        let expected = Value::Object(internal);
180        assert_eq!(actual.parse::<Value>().unwrap(), expected);
181    }
182
183    #[test]
184    fn parse_2config_key_and_value() {
185        let actual = "key1\nvalue1\nvalue2\0";
186        let mut internal = Map::new();
187        internal.insert(
188            "key1".to_owned(),
189            Value::String("value1\nvalue2".to_owned()),
190        );
191        let expected = Value::Object(internal);
192        assert_eq!(actual.parse::<Value>().unwrap(), expected);
193    }
194
195    //    #[test]
196    //    fn parse_2config_key_and_value2() {
197    //        let actual = "key1\nvalue1\nvalue2\0key2";
198    //        let mut internal = Map::new();
199    //        internal.insert("key1".to_owned(), Value::String("value1\nvalue2".to_owned()));
200    //        let expected = Value::Object(internal);
201    //        assert_eq!(actual.parse::<Value>().unwrap(), expected);
202    //    }
203
204    #[test]
205    fn parse_2config_key_and_value3() {
206        let actual = "key1\nvalue1\nvalue2\0key2\nvalue3";
207        let mut internal = Map::new();
208        internal.insert(
209            "key1".to_owned(),
210            Value::String("value1\nvalue2".to_owned()),
211        );
212        internal.insert("key2".to_owned(), Value::String("value3".to_owned()));
213        let expected = Value::Object(internal);
214        assert_eq!(actual.parse::<Value>().unwrap(), expected);
215    }
216
217    #[test]
218    fn parse_2keys_and_value1() {
219        let actual = "key1.key2\nvalue1\nvalue2";
220        let mut internal = Map::new();
221        let mut internal2 = Map::new();
222        internal2.insert(
223            "key2".to_owned(),
224            Value::String("value1\nvalue2".to_owned()),
225        );
226        internal.insert("key1".to_owned(), Value::Object(internal2));
227        let expected = Value::Object(internal);
228        assert_eq!(actual.parse::<Value>().unwrap(), expected);
229    }
230
231    #[test]
232    fn parse_key_and_value2() {
233        let actual = "key1\nvalue1\nvalue2";
234        let mut internal = Map::new();
235        match internal.entry("key1") {
236            Entry::Occupied(_) => unimplemented!(),
237            Entry::Vacant(vacant) => {
238                vacant.insert(Value::String("value1\nvalue2".to_owned()));
239                ()
240            }
241        }
242        let expected = Value::Object(internal);
243        assert_eq!(actual.parse::<Value>().unwrap(), expected);
244    }
245
246    #[test]
247    fn parse_2keys_and_value2() {
248        let actual = "key1.key2\nvalue1\nvalue2";
249        let mut internal = Map::new();
250        match internal.entry("key1") {
251            Entry::Occupied(_) => unimplemented!(),
252            Entry::Vacant(vacant) => {
253                let mut internal2 = Map::new();
254                internal2.insert(
255                    "key2".to_owned(),
256                    Value::String("value1\nvalue2".to_owned()),
257                );
258                vacant.insert(Value::Object(internal2));
259            }
260        }
261        let expected = Value::Object(internal);
262        assert_eq!(actual.parse::<Value>().unwrap(), expected);
263    }
264
265    #[test]
266    fn parse_3keys_and_value1() {
267        let actual = "key1.key2.key3\nvalue1\nvalue2";
268        let mut internal = Map::new();
269        let mut internal2 = Map::new();
270        let mut internal3 = Map::new();
271        internal3.insert(
272            "key3".to_owned(),
273            Value::String("value1\nvalue2".to_owned()),
274        );
275        internal2.insert("key2".to_owned(), Value::Object((internal3)));
276        internal.insert("key1".to_owned(), Value::Object(internal2));
277        let expected = Value::Object(internal);
278        assert_eq!(actual.parse::<Value>().unwrap(), expected);
279    }
280
281    #[test]
282    fn parse_3keys_and_value2() {
283        let actual = "key1.key2.key3\nvalue1\nvalue2\0key1.key2.key4\nvalue3\nvalue4";
284        let mut internal = Map::new();
285        let mut internal2 = Map::new();
286        let mut internal3 = Map::new();
287        internal3.insert(
288            "key3".to_owned(),
289            Value::String("value1\nvalue2".to_owned()),
290        );
291        internal3.insert(
292            "key4".to_owned(),
293            Value::String("value3\nvalue4".to_owned()),
294        );
295        internal2.insert("key2".to_owned(), Value::Object((internal3)));
296        internal.insert("key1".to_owned(), Value::Object(internal2));
297        let expected = Value::Object(internal);
298        assert_eq!(actual.parse::<Value>().unwrap(), expected);
299    }
300    #[test]
301    fn parse_5keys_and_value2() {
302        let actual = "key1.key2.key3.key4.key5\nvalue1
303value2\0key1.key2.key3.key4.key6\nvalue3\nvalue4";
304        let mut internal = Map::new();
305        let mut internal2 = Map::new();
306        let mut internal3 = Map::new();
307        internal3.insert(
308            "key5".to_owned(),
309            Value::String("value1\nvalue2".to_owned()),
310        );
311        internal3.insert(
312            "key6".to_owned(),
313            Value::String("value3\nvalue4".to_owned()),
314        );
315        internal2.insert("key2.key3.key4".to_owned(), Value::Object((internal3)));
316        internal.insert("key1".to_owned(), Value::Object(internal2));
317        let expected = Value::Object(internal);
318        assert_eq!(actual.parse::<Value>().unwrap(), expected);
319    }
320}
321
322fn split_once(in_string: &str) -> (&str, &str) {
323    let mut splitter = in_string.splitn(2, "\n");
324    let first = splitter.next().unwrap();
325    let second = splitter.next().unwrap();
326    (first, second)
327}