1 //! Sources for key-value pairs.
2 
3 use std::fmt;
4 use kv::{Error, Key, ToKey, Value, ToValue};
5 
6 /// A source of key-value pairs.
7 ///
8 /// The source may be a single pair, a set of pairs, or a filter over a set of pairs.
9 /// Use the [`Visitor`](trait.Visitor.html) trait to inspect the structured data
10 /// in a source.
11 pub trait Source {
12     /// Visit key-value pairs.
13     ///
14     /// A source doesn't have to guarantee any ordering or uniqueness of key-value pairs.
15     /// If the given visitor returns an error then the source may early-return with it,
16     /// even if there are more key-value pairs.
17     ///
18     /// # Implementation notes
19     ///
20     /// A source should yield the same key-value pairs to a subsequent visitor unless
21     /// that visitor itself fails.
visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>22     fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>;
23 
24     /// Get the value for a given key.
25     ///
26     /// If the key appears multiple times in the source then which key is returned
27     /// is implementation specific.
28     ///
29     /// # Implementation notes
30     ///
31     /// A source that can provide a more efficient implementation of this method
32     /// should override it.
get<'v>(&'v self, key: Key) -> Option<Value<'v>>33     fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
34         struct Get<'k, 'v> {
35             key: Key<'k>,
36             found: Option<Value<'v>>,
37         }
38 
39         impl<'k, 'kvs> Visitor<'kvs> for Get<'k, 'kvs> {
40             fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
41                 if self.key == key {
42                     self.found = Some(value);
43                 }
44 
45                 Ok(())
46             }
47         }
48 
49         let mut get = Get {
50             key,
51             found: None,
52         };
53 
54         let _ = self.visit(&mut get);
55         get.found
56     }
57 
58     /// Count the number of key-value pairs that can be visited.
59     ///
60     /// # Implementation notes
61     ///
62     /// A source that knows the number of key-value pairs upfront may provide a more
63     /// efficient implementation.
64     ///
65     /// A subsequent call to `visit` should yield the same number of key-value pairs
66     /// to the visitor, unless that visitor fails part way through.
count(&self) -> usize67     fn count(&self) -> usize {
68         struct Count(usize);
69 
70         impl<'kvs> Visitor<'kvs> for Count {
71             fn visit_pair(&mut self, _: Key<'kvs>, _: Value<'kvs>) -> Result<(), Error> {
72                 self.0 += 1;
73 
74                 Ok(())
75             }
76         }
77 
78         let mut count = Count(0);
79         let _ = self.visit(&mut count);
80         count.0
81     }
82 }
83 
84 impl<'a, T> Source for &'a T
85 where
86     T: Source + ?Sized,
87 {
visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>88     fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> {
89         Source::visit(&**self, visitor)
90     }
91 
get<'v>(&'v self, key: Key) -> Option<Value<'v>>92     fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
93         Source::get(&**self, key)
94     }
95 
count(&self) -> usize96     fn count(&self) -> usize {
97         Source::count(&**self)
98     }
99 }
100 
101 impl<K, V> Source for (K, V)
102 where
103     K: ToKey,
104     V: ToValue,
105 {
visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>106     fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> {
107         visitor.visit_pair(self.0.to_key(), self.1.to_value())
108     }
109 
get<'v>(&'v self, key: Key) -> Option<Value<'v>>110     fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
111         if self.0.to_key() == key {
112             Some(self.1.to_value())
113         } else {
114             None
115         }
116     }
117 
count(&self) -> usize118     fn count(&self) -> usize {
119         1
120     }
121 }
122 
123 impl<S> Source for [S]
124 where
125     S: Source,
126 {
visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>127     fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> {
128         for source in self {
129             source.visit(visitor)?;
130         }
131 
132         Ok(())
133     }
134 
count(&self) -> usize135     fn count(&self) -> usize {
136         self.len()
137     }
138 }
139 
140 impl<S> Source for Option<S>
141 where
142     S: Source,
143 {
visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>144     fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> {
145         if let Some(ref source) = *self {
146             source.visit(visitor)?;
147         }
148 
149         Ok(())
150     }
151 
count(&self) -> usize152     fn count(&self) -> usize {
153         self.as_ref().map(Source::count).unwrap_or(0)
154     }
155 }
156 
157 /// A visitor for the key-value pairs in a [`Source`](trait.Source.html).
158 pub trait Visitor<'kvs> {
159     /// Visit a key-value pair.
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>160     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>;
161 }
162 
163 impl<'a, 'kvs, T> Visitor<'kvs> for &'a mut T
164 where
165     T: Visitor<'kvs> + ?Sized,
166 {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>167     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
168         (**self).visit_pair(key, value)
169     }
170 }
171 
172 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugMap<'a, 'b> {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>173     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
174         self.entry(&key, &value);
175         Ok(())
176     }
177 }
178 
179 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugList<'a, 'b> {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>180     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
181         self.entry(&(key, value));
182         Ok(())
183     }
184 }
185 
186 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugSet<'a, 'b> {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>187     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
188         self.entry(&(key, value));
189         Ok(())
190     }
191 }
192 
193 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugTuple<'a, 'b> {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>194     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
195         self.field(&key);
196         self.field(&value);
197         Ok(())
198     }
199 }
200 
201 #[cfg(feature = "std")]
202 mod std_support {
203     use super::*;
204     use std::borrow::Borrow;
205     use std::collections::{BTreeMap, HashMap};
206     use std::hash::{BuildHasher, Hash};
207 
208     impl<S> Source for Box<S>
209     where
210         S: Source + ?Sized,
211     {
visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>212         fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> {
213             Source::visit(&**self, visitor)
214         }
215 
get<'v>(&'v self, key: Key) -> Option<Value<'v>>216         fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
217             Source::get(&**self, key)
218         }
219 
count(&self) -> usize220         fn count(&self) -> usize {
221             Source::count(&**self)
222         }
223     }
224 
225     impl<S> Source for Vec<S>
226     where
227         S: Source,
228     {
visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>229         fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> {
230             Source::visit(&**self, visitor)
231         }
232 
get<'v>(&'v self, key: Key) -> Option<Value<'v>>233         fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
234             Source::get(&**self, key)
235         }
236 
count(&self) -> usize237         fn count(&self) -> usize {
238             Source::count(&**self)
239         }
240     }
241 
242     impl<'kvs, V> Visitor<'kvs> for Box<V>
243     where
244         V: Visitor<'kvs> + ?Sized,
245     {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>246         fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
247             (**self).visit_pair(key, value)
248         }
249     }
250 
251     impl<K, V, S> Source for HashMap<K, V, S>
252     where
253         K: ToKey + Borrow<str> + Eq + Hash,
254         V: ToValue,
255         S: BuildHasher,
256     {
visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>257         fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> {
258             for (key, value) in self {
259                 visitor.visit_pair(key.to_key(), value.to_value())?;
260             }
261             Ok(())
262         }
263 
get<'v>(&'v self, key: Key) -> Option<Value<'v>>264         fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
265             HashMap::get(self, key.as_str()).map(|v| v.to_value())
266         }
267 
count(&self) -> usize268         fn count(&self) -> usize {
269             self.len()
270         }
271     }
272 
273     impl<K, V> Source for BTreeMap<K, V>
274     where
275         K: ToKey + Borrow<str> + Ord,
276         V: ToValue,
277     {
visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>278         fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> {
279             for (key, value) in self {
280                 visitor.visit_pair(key.to_key(), value.to_value())?;
281             }
282             Ok(())
283         }
284 
get<'v>(&'v self, key: Key) -> Option<Value<'v>>285         fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
286             BTreeMap::get(self, key.as_str()).map(|v| v.to_value())
287         }
288 
count(&self) -> usize289         fn count(&self) -> usize {
290             self.len()
291         }
292     }
293 
294     #[cfg(test)]
295     mod tests {
296         use super::*;
297         use kv::value::test::Token;
298         use std::collections::{BTreeMap, HashMap};
299 
300         #[test]
count()301         fn count() {
302             assert_eq!(1, Source::count(&Box::new(("a", 1))));
303             assert_eq!(2, Source::count(&vec![("a", 1), ("b", 2)]));
304         }
305 
306         #[test]
get()307         fn get() {
308             let source = vec![("a", 1), ("b", 2), ("a", 1)];
309             assert_eq!(
310                 Token::I64(1),
311                 Source::get(&source, Key::from_str("a")).unwrap().to_token()
312             );
313 
314             let source = Box::new(Option::None::<(&str, i32)>);
315             assert!(Source::get(&source, Key::from_str("a")).is_none());
316         }
317 
318         #[test]
hash_map()319         fn hash_map() {
320             let mut map = HashMap::new();
321             map.insert("a", 1);
322             map.insert("b", 2);
323 
324             assert_eq!(2, Source::count(&map));
325             assert_eq!(
326                 Token::I64(1),
327                 Source::get(&map, Key::from_str("a")).unwrap().to_token()
328             );
329         }
330 
331         #[test]
btree_map()332         fn btree_map() {
333             let mut map = BTreeMap::new();
334             map.insert("a", 1);
335             map.insert("b", 2);
336 
337             assert_eq!(2, Source::count(&map));
338             assert_eq!(
339                 Token::I64(1),
340                 Source::get(&map, Key::from_str("a")).unwrap().to_token()
341             );
342         }
343     }
344 }
345 
346 #[cfg(test)]
347 mod tests {
348     use super::*;
349     use kv::value::test::Token;
350 
351     #[test]
source_is_object_safe()352     fn source_is_object_safe() {
353         fn _check(_: &Source) {}
354     }
355 
356     #[test]
visitor_is_object_safe()357     fn visitor_is_object_safe() {
358         fn _check(_: &Visitor) {}
359     }
360 
361     #[test]
count()362     fn count() {
363         struct OnePair {
364             key: &'static str,
365             value: i32,
366         }
367 
368         impl Source for OnePair {
369             fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> {
370                 visitor.visit_pair(self.key.to_key(), self.value.to_value())
371             }
372         }
373 
374         assert_eq!(1, Source::count(&("a", 1)));
375         assert_eq!(2, Source::count(&[("a", 1), ("b", 2)] as &[_]));
376         assert_eq!(0, Source::count(&Option::None::<(&str, i32)>));
377         assert_eq!(1, Source::count(&OnePair { key: "a", value: 1 }));
378     }
379 
380     #[test]
get()381     fn get() {
382         let source = &[("a", 1), ("b", 2), ("a", 1)] as &[_];
383         assert_eq!(
384             Token::I64(1),
385             Source::get(source, Key::from_str("a")).unwrap().to_token()
386         );
387         assert_eq!(
388             Token::I64(2),
389             Source::get(source, Key::from_str("b")).unwrap().to_token()
390         );
391         assert!(Source::get(&source, Key::from_str("c")).is_none());
392 
393         let source = Option::None::<(&str, i32)>;
394         assert!(Source::get(&source, Key::from_str("a")).is_none());
395     }
396 }
397