scan_rules/scanner/std/
collections.rs

1/*
2Copyright ⓒ 2016 Daniel Keep.
3
4Licensed under the MIT license (see LICENSE or <http://opensource.org
5/licenses/MIT>) or the Apache License, Version 2.0 (see LICENSE of
6<http://www.apache.org/licenses/LICENSE-2.0>), at your option. All
7files in the project carrying such notice may not be copied, modified,
8or distributed except according to those terms.
9*/
10/*!
11Scanner implementations for `std::collections::*`.
12*/
13use std::collections::{
14    BTreeMap, BTreeSet, BinaryHeap,
15    HashMap, HashSet,
16    LinkedList,
17    VecDeque,
18};
19use std::hash::Hash;
20use ::scanner::KeyValuePair;
21
22scanner! { impl<'a, K, V> ScanFromStr for BTreeMap<K, V> => BTreeMap, where {K: Ord} {
23    ("{", [ let es: KeyValuePair<K, V> ],*: BTreeMap<K, V>, "}", ..tail) => (es, tail)
24}}
25
26scanner! { impl<'a, T> ScanFromStr for BTreeSet<T> => BTreeSet, where {T: Ord} {
27    ("{", [ let es: T ],*: BTreeSet<_>, "}", ..tail) => (es, tail)
28}}
29
30scanner! { impl<'a, T> ScanFromStr for BinaryHeap<T> => BinaryHeap, where {T: Ord} {
31    ("[", [ let es: T ],*: BinaryHeap<_>, "]", ..tail) => (es, tail)
32}}
33
34scanner! { impl<'a, K, V> ScanFromStr for HashMap<K, V> => HashMap, where {K: Hash + Eq} {
35    ("{", [ let es: KeyValuePair<K, V> ],*: HashMap<K, V>, "}", ..tail) => (es, tail)
36}}
37
38scanner! { impl<'a, T> ScanFromStr for HashSet<T> => HashSet, where {T: Hash + Eq} {
39    ("{", [ let es: T ],*: HashSet<_>, "}", ..tail) => (es, tail)
40}}
41
42scanner! { impl<'a, T> ScanFromStr for LinkedList<T> => LinkedList {
43    ("[", [ let es: T ],*: LinkedList<_>, "]", ..tail) => (es, tail)
44}}
45
46scanner! { impl<'a, T> ScanFromStr for Vec<T> => Vec {
47    ("[", [ let es: T ],*, "]", ..tail) => (es, tail)
48}}
49
50scanner! { impl<'a, T> ScanFromStr for VecDeque<T> => VecDeque {
51    ("[", [ let es: T ],*: VecDeque<_>, "]", ..tail) => (es, tail)
52}}
53
54#[cfg(test)]
55#[test]
56fn test_btreemap() {
57    use ::scanner::ScanFromStr;
58
59    macro_rules! check {
60        (<$k:ty, $v:ty> $s:expr, Ok($r:expr, $n:expr)) => {
61            assert_match!(
62                <BTreeMap<$k, $v>>::scan_from($s),
63                Ok((ref v, $n)) if &*sorted(v.clone().into_iter()) == &$r
64            )
65        };
66
67        (<$k:ty, $v:ty> $s:expr, Err($err:pat)) => {
68            assert_match!(
69                <BTreeMap<$k, $v>>::scan_self_from($s),
70                Err($err)
71            )
72        };
73    }
74
75    check!(<i32, i32> "{}", Ok([], 2));
76    check!(<i32, i32> "{0: 1}", Ok([(0, 1)], 6));
77    check!(<i32, i32> "{0: 1, 2: 3}", Ok([(0, 1), (2, 3)], 12));
78    check!(<i32, bool> "{0: true, 1: false}", Ok([(0, true), (1, false)], 19));
79}
80
81#[cfg(test)]
82#[test]
83fn test_btreeset() {
84    use ::scanner::ScanFromStr;
85
86    macro_rules! check {
87        (<$ty:ty> $s:expr, Ok($v:expr, $n:expr)) => {
88            assert_match!(
89                <BTreeSet<$ty>>::scan_from($s),
90                Ok((ref v, $n)) if &*sorted(v.into_iter().cloned()) == &$v
91            )
92        };
93
94        (<$ty:ty> $s:expr, Err($err:pat)) => {
95            assert_match!(
96                <BTreeSet<$ty>>::scan_self_from($s),
97                Err($err)
98            )
99        };
100    }
101
102    check!(<i32> "{}", Ok([], 2));
103    check!(<i32> "{0}", Ok([0], 3));
104    check!(<i32> "{0, 1}", Ok([0, 1], 6));
105    check!(<bool> "{true, false}", Ok([false, true], 13));
106}
107
108#[cfg(test)]
109#[test]
110fn test_binaryheap() {
111    use ::scanner::ScanFromStr;
112
113    macro_rules! check {
114        (<$ty:ty> $s:expr, Ok($v:expr, $n:expr)) => {
115            assert_match!(
116                <BinaryHeap<$ty>>::scan_from($s),
117                Ok((ref v, $n)) if &*sorted(v.into_iter().cloned()) == &$v
118            )
119        };
120
121        (<$ty:ty> $s:expr, Err($err:pat)) => {
122            assert_match!(
123                <BinaryHeap<$ty>>::scan_self_from($s),
124                Err($err)
125            )
126        };
127    }
128
129    check!(<i32> "[]", Ok([], 2));
130    check!(<i32> "[0]", Ok([0], 3));
131    check!(<i32> "[0, 1]", Ok([0, 1], 6));
132    check!(<bool> "[true, false]", Ok([false, true], 13));
133}
134
135#[cfg(test)]
136#[test]
137fn test_hashmap() {
138    use ::scanner::ScanFromStr;
139
140    macro_rules! check {
141        (<$k:ty, $v:ty> $s:expr, Ok($r:expr, $n:expr)) => {
142            assert_match!(
143                <HashMap<$k, $v>>::scan_from($s),
144                Ok((ref v, $n)) if &*sorted(v.clone().into_iter()) == &$r
145            )
146        };
147
148        (<$k:ty, $v:ty> $s:expr, Err($err:pat)) => {
149            assert_match!(
150                <HashMap<$k, $v>>::scan_self_from($s),
151                Err($err)
152            )
153        };
154    }
155
156    check!(<i32, i32> "{}", Ok([], 2));
157    check!(<i32, i32> "{0: 1}", Ok([(0, 1)], 6));
158    check!(<i32, i32> "{0: 1, 2: 3}", Ok([(0, 1), (2, 3)], 12));
159    check!(<i32, bool> "{0: true, 1: false}", Ok([(0, true), (1, false)], 19));
160}
161
162#[cfg(test)]
163#[test]
164fn test_hashset() {
165    use ::scanner::ScanFromStr;
166
167    macro_rules! check {
168        (<$ty:ty> $s:expr, Ok($v:expr, $n:expr)) => {
169            assert_match!(
170                <HashSet<$ty>>::scan_from($s),
171                Ok((ref v, $n)) if &*sorted(v.into_iter().cloned()) == &$v
172            )
173        };
174
175        (<$ty:ty> $s:expr, Err($err:pat)) => {
176            assert_match!(
177                <HashSet<$ty>>::scan_self_from($s),
178                Err($err)
179            )
180        };
181    }
182
183    check!(<i32> "{}", Ok([], 2));
184    check!(<i32> "{0}", Ok([0], 3));
185    check!(<i32> "{0, 1}", Ok([0, 1], 6));
186    check!(<bool> "{true, false}", Ok([false, true], 13));
187}
188
189#[cfg(test)]
190#[test]
191fn test_linkedlist() {
192    use ::scanner::ScanFromStr;
193
194    macro_rules! check {
195        (<$ty:ty> $s:expr, Ok($v:expr, $n:expr)) => {
196            assert_match!(
197                <LinkedList<$ty>>::scan_from($s),
198                Ok((ref v, $n)) if &*(v.clone().into_iter().collect::<Vec<_>>()) == &$v
199            )
200        };
201
202        (<$ty:ty> $s:expr, Err($err:pat)) => {
203            assert_match!(
204                <LinkedList<$ty>>::scan_self_from($s),
205                Err($err)
206            )
207        };
208    }
209
210    check!(<i32> "[]", Ok([], 2));
211    check!(<i32> "[0]", Ok([0], 3));
212    check!(<i32> "[0, 1]", Ok([0, 1], 6));
213    check!(<bool> "[true, false]", Ok([true, false], 13));
214}
215
216#[cfg(test)]
217#[test]
218fn test_vec() {
219    use ::scanner::ScanFromStr;
220
221    macro_rules! check {
222        (<$ty:ty> $s:expr, Ok($v:expr, $n:expr)) => {
223            assert_match!(
224                <Vec<$ty>>::scan_from($s),
225                Ok((ref v, $n)) if &*v == &$v
226            )
227        };
228
229        (<$ty:ty> $s:expr, Err($err:pat)) => {
230            assert_match!(
231                <Vec<$ty>>::scan_self_from($s),
232                Err($err)
233            )
234        };
235    }
236
237    check!(<i32> "[]", Ok([], 2));
238    check!(<i32> "[0]", Ok([0], 3));
239    check!(<i32> "[0, 1]", Ok([0, 1], 6));
240    check!(<bool> "[true, false]", Ok([true, false], 13));
241}
242
243#[cfg(test)]
244#[test]
245fn test_vecdeque() {
246    use ::scanner::ScanFromStr;
247
248    macro_rules! check {
249        (<$ty:ty> $s:expr, Ok($v:expr, $n:expr)) => {
250            assert_match!(
251                <VecDeque<$ty>>::scan_from($s),
252                Ok((ref v, $n)) if &*(v.clone().into_iter().collect::<Vec<_>>()) == &$v
253            )
254        };
255
256        (<$ty:ty> $s:expr, Err($err:pat)) => {
257            assert_match!(
258                <VecDeque<$ty>>::scan_self_from($s),
259                Err($err)
260            )
261        };
262    }
263
264    check!(<i32> "[]", Ok([], 2));
265    check!(<i32> "[0]", Ok([0], 3));
266    check!(<i32> "[0, 1]", Ok([0, 1], 6));
267    check!(<bool> "[true, false]", Ok([true, false], 13));
268}
269
270#[cfg(test)]
271fn sorted<It: Iterator>(it: It) -> Vec<It::Item>
272where It::Item: Ord {
273    let mut v: Vec<_> = it.collect();
274    v.sort();
275    v
276}