1 //! Sources for key-value pairs.
2 
3 use kv::{Error, Key, ToKey, ToValue, Value};
4 use std::fmt;
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 dyn Visitor<'kvs>) -> Result<(), Error>22     fn visit<'kvs>(&'kvs self, visitor: &mut dyn 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 { key, found: None };
50 
51         let _ = self.visit(&mut get);
52         get.found
53     }
54 
55     /// Count the number of key-value pairs that can be visited.
56     ///
57     /// # Implementation notes
58     ///
59     /// A source that knows the number of key-value pairs upfront may provide a more
60     /// efficient implementation.
61     ///
62     /// A subsequent call to `visit` should yield the same number of key-value pairs
63     /// to the visitor, unless that visitor fails part way through.
count(&self) -> usize64     fn count(&self) -> usize {
65         struct Count(usize);
66 
67         impl<'kvs> Visitor<'kvs> for Count {
68             fn visit_pair(&mut self, _: Key<'kvs>, _: Value<'kvs>) -> Result<(), Error> {
69                 self.0 += 1;
70 
71                 Ok(())
72             }
73         }
74 
75         let mut count = Count(0);
76         let _ = self.visit(&mut count);
77         count.0
78     }
79 }
80 
81 impl<'a, T> Source for &'a T
82 where
83     T: Source + ?Sized,
84 {
visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>85     fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
86         Source::visit(&**self, visitor)
87     }
88 
get<'v>(&'v self, key: Key) -> Option<Value<'v>>89     fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
90         Source::get(&**self, key)
91     }
92 
count(&self) -> usize93     fn count(&self) -> usize {
94         Source::count(&**self)
95     }
96 }
97 
98 impl<K, V> Source for (K, V)
99 where
100     K: ToKey,
101     V: ToValue,
102 {
visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>103     fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
104         visitor.visit_pair(self.0.to_key(), self.1.to_value())
105     }
106 
get<'v>(&'v self, key: Key) -> Option<Value<'v>>107     fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
108         if self.0.to_key() == key {
109             Some(self.1.to_value())
110         } else {
111             None
112         }
113     }
114 
count(&self) -> usize115     fn count(&self) -> usize {
116         1
117     }
118 }
119 
120 impl<S> Source for [S]
121 where
122     S: Source,
123 {
visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>124     fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
125         for source in self {
126             source.visit(visitor)?;
127         }
128 
129         Ok(())
130     }
131 
count(&self) -> usize132     fn count(&self) -> usize {
133         self.len()
134     }
135 }
136 
137 impl<S> Source for Option<S>
138 where
139     S: Source,
140 {
visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>141     fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
142         if let Some(ref source) = *self {
143             source.visit(visitor)?;
144         }
145 
146         Ok(())
147     }
148 
count(&self) -> usize149     fn count(&self) -> usize {
150         self.as_ref().map(Source::count).unwrap_or(0)
151     }
152 }
153 
154 /// A visitor for the key-value pairs in a [`Source`](trait.Source.html).
155 pub trait Visitor<'kvs> {
156     /// Visit a key-value pair.
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>157     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>;
158 }
159 
160 impl<'a, 'kvs, T> Visitor<'kvs> for &'a mut T
161 where
162     T: Visitor<'kvs> + ?Sized,
163 {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>164     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
165         (**self).visit_pair(key, value)
166     }
167 }
168 
169 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugMap<'a, 'b> {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>170     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
171         self.entry(&key, &value);
172         Ok(())
173     }
174 }
175 
176 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugList<'a, 'b> {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>177     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
178         self.entry(&(key, value));
179         Ok(())
180     }
181 }
182 
183 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugSet<'a, 'b> {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>184     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
185         self.entry(&(key, value));
186         Ok(())
187     }
188 }
189 
190 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugTuple<'a, 'b> {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>191     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
192         self.field(&key);
193         self.field(&value);
194         Ok(())
195     }
196 }
197 
198 #[cfg(feature = "std")]
199 mod std_support {
200     use super::*;
201     use std::borrow::Borrow;
202     use std::collections::{BTreeMap, HashMap};
203     use std::hash::{BuildHasher, Hash};
204 
205     impl<S> Source for Box<S>
206     where
207         S: Source + ?Sized,
208     {
visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>209         fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
210             Source::visit(&**self, visitor)
211         }
212 
get<'v>(&'v self, key: Key) -> Option<Value<'v>>213         fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
214             Source::get(&**self, key)
215         }
216 
count(&self) -> usize217         fn count(&self) -> usize {
218             Source::count(&**self)
219         }
220     }
221 
222     impl<S> Source for Vec<S>
223     where
224         S: Source,
225     {
visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>226         fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
227             Source::visit(&**self, visitor)
228         }
229 
get<'v>(&'v self, key: Key) -> Option<Value<'v>>230         fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
231             Source::get(&**self, key)
232         }
233 
count(&self) -> usize234         fn count(&self) -> usize {
235             Source::count(&**self)
236         }
237     }
238 
239     impl<'kvs, V> Visitor<'kvs> for Box<V>
240     where
241         V: Visitor<'kvs> + ?Sized,
242     {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>243         fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
244             (**self).visit_pair(key, value)
245         }
246     }
247 
248     impl<K, V, S> Source for HashMap<K, V, S>
249     where
250         K: ToKey + Borrow<str> + Eq + Hash,
251         V: ToValue,
252         S: BuildHasher,
253     {
visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>254         fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
255             for (key, value) in self {
256                 visitor.visit_pair(key.to_key(), value.to_value())?;
257             }
258             Ok(())
259         }
260 
get<'v>(&'v self, key: Key) -> Option<Value<'v>>261         fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
262             HashMap::get(self, key.as_str()).map(|v| v.to_value())
263         }
264 
count(&self) -> usize265         fn count(&self) -> usize {
266             self.len()
267         }
268     }
269 
270     impl<K, V> Source for BTreeMap<K, V>
271     where
272         K: ToKey + Borrow<str> + Ord,
273         V: ToValue,
274     {
visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>275         fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
276             for (key, value) in self {
277                 visitor.visit_pair(key.to_key(), value.to_value())?;
278             }
279             Ok(())
280         }
281 
get<'v>(&'v self, key: Key) -> Option<Value<'v>>282         fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
283             BTreeMap::get(self, key.as_str()).map(|v| v.to_value())
284         }
285 
count(&self) -> usize286         fn count(&self) -> usize {
287             self.len()
288         }
289     }
290 
291     #[cfg(test)]
292     mod tests {
293         use super::*;
294         use kv::value::test::Token;
295         use std::collections::{BTreeMap, HashMap};
296 
297         #[test]
count()298         fn count() {
299             assert_eq!(1, Source::count(&Box::new(("a", 1))));
300             assert_eq!(2, Source::count(&vec![("a", 1), ("b", 2)]));
301         }
302 
303         #[test]
get()304         fn get() {
305             let source = vec![("a", 1), ("b", 2), ("a", 1)];
306             assert_eq!(
307                 Token::I64(1),
308                 Source::get(&source, Key::from_str("a")).unwrap().to_token()
309             );
310 
311             let source = Box::new(Option::None::<(&str, i32)>);
312             assert!(Source::get(&source, Key::from_str("a")).is_none());
313         }
314 
315         #[test]
hash_map()316         fn hash_map() {
317             let mut map = HashMap::new();
318             map.insert("a", 1);
319             map.insert("b", 2);
320 
321             assert_eq!(2, Source::count(&map));
322             assert_eq!(
323                 Token::I64(1),
324                 Source::get(&map, Key::from_str("a")).unwrap().to_token()
325             );
326         }
327 
328         #[test]
btree_map()329         fn btree_map() {
330             let mut map = BTreeMap::new();
331             map.insert("a", 1);
332             map.insert("b", 2);
333 
334             assert_eq!(2, Source::count(&map));
335             assert_eq!(
336                 Token::I64(1),
337                 Source::get(&map, Key::from_str("a")).unwrap().to_token()
338             );
339         }
340     }
341 }
342 
343 #[cfg(test)]
344 mod tests {
345     use super::*;
346     use kv::value::test::Token;
347 
348     #[test]
source_is_object_safe()349     fn source_is_object_safe() {
350         fn _check(_: &dyn Source) {}
351     }
352 
353     #[test]
visitor_is_object_safe()354     fn visitor_is_object_safe() {
355         fn _check(_: &dyn Visitor) {}
356     }
357 
358     #[test]
count()359     fn count() {
360         struct OnePair {
361             key: &'static str,
362             value: i32,
363         }
364 
365         impl Source for OnePair {
366             fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
367                 visitor.visit_pair(self.key.to_key(), self.value.to_value())
368             }
369         }
370 
371         assert_eq!(1, Source::count(&("a", 1)));
372         assert_eq!(2, Source::count(&[("a", 1), ("b", 2)] as &[_]));
373         assert_eq!(0, Source::count(&Option::None::<(&str, i32)>));
374         assert_eq!(1, Source::count(&OnePair { key: "a", value: 1 }));
375     }
376 
377     #[test]
get()378     fn get() {
379         let source = &[("a", 1), ("b", 2), ("a", 1)] as &[_];
380         assert_eq!(
381             Token::I64(1),
382             Source::get(source, Key::from_str("a")).unwrap().to_token()
383         );
384         assert_eq!(
385             Token::I64(2),
386             Source::get(source, Key::from_str("b")).unwrap().to_token()
387         );
388         assert!(Source::get(&source, Key::from_str("c")).is_none());
389 
390         let source = Option::None::<(&str, i32)>;
391         assert!(Source::get(&source, Key::from_str("a")).is_none());
392     }
393 }
394