1 //! Sources for key-values.
2 //!
3 //! This module defines the [`Source`] type and supporting APIs for
4 //! working with collections of key-values.
5
6 use crate::kv::{Error, Key, ToKey, ToValue, Value};
7 use std::fmt;
8
9 /// A source of key-values.
10 ///
11 /// The source may be a single pair, a set of pairs, or a filter over a set of pairs.
12 /// Use the [`VisitSource`](trait.VisitSource.html) trait to inspect the structured data
13 /// in a source.
14 ///
15 /// A source is like an iterator over its key-values, except with a push-based API
16 /// instead of a pull-based one.
17 ///
18 /// # Examples
19 ///
20 /// Enumerating the key-values in a source:
21 ///
22 /// ```
23 /// # fn main() -> Result<(), log::kv::Error> {
24 /// use log::kv::{self, Source, Key, Value, VisitSource};
25 ///
26 /// // A `VisitSource` that prints all key-values
27 /// // VisitSources are fed the key-value pairs of each key-values
28 /// struct Printer;
29 ///
30 /// impl<'kvs> VisitSource<'kvs> for Printer {
31 /// fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), kv::Error> {
32 /// println!("{key}: {value}");
33 ///
34 /// Ok(())
35 /// }
36 /// }
37 ///
38 /// // A source with 3 key-values
39 /// // Common collection types implement the `Source` trait
40 /// let source = &[
41 /// ("a", 1),
42 /// ("b", 2),
43 /// ("c", 3),
44 /// ];
45 ///
46 /// // Pass an instance of the `VisitSource` to a `Source` to visit it
47 /// source.visit(&mut Printer)?;
48 /// # Ok(())
49 /// # }
50 /// ```
51 pub trait Source {
52 /// Visit key-values.
53 ///
54 /// A source doesn't have to guarantee any ordering or uniqueness of key-values.
55 /// If the given visitor returns an error then the source may early-return with it,
56 /// even if there are more key-values.
57 ///
58 /// # Implementation notes
59 ///
60 /// A source should yield the same key-values to a subsequent visitor unless
61 /// that visitor itself fails.
visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>62 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>;
63
64 /// Get the value for a given key.
65 ///
66 /// If the key appears multiple times in the source then which key is returned
67 /// is implementation specific.
68 ///
69 /// # Implementation notes
70 ///
71 /// A source that can provide a more efficient implementation of this method
72 /// should override it.
get(&self, key: Key) -> Option<Value<'_>>73 fn get(&self, key: Key) -> Option<Value<'_>> {
74 get_default(self, key)
75 }
76
77 /// Count the number of key-values that can be visited.
78 ///
79 /// # Implementation notes
80 ///
81 /// A source that knows the number of key-values upfront may provide a more
82 /// efficient implementation.
83 ///
84 /// A subsequent call to `visit` should yield the same number of key-values.
count(&self) -> usize85 fn count(&self) -> usize {
86 count_default(self)
87 }
88 }
89
90 /// The default implementation of `Source::get`
get_default<'v>(source: &'v (impl Source + ?Sized), key: Key) -> Option<Value<'v>>91 fn get_default<'v>(source: &'v (impl Source + ?Sized), key: Key) -> Option<Value<'v>> {
92 struct Get<'k, 'v> {
93 key: Key<'k>,
94 found: Option<Value<'v>>,
95 }
96
97 impl<'k, 'kvs> VisitSource<'kvs> for Get<'k, 'kvs> {
98 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
99 if self.key == key {
100 self.found = Some(value);
101 }
102
103 Ok(())
104 }
105 }
106
107 let mut get = Get { key, found: None };
108
109 let _ = source.visit(&mut get);
110 get.found
111 }
112
113 /// The default implementation of `Source::count`.
count_default(source: impl Source) -> usize114 fn count_default(source: impl Source) -> usize {
115 struct Count(usize);
116
117 impl<'kvs> VisitSource<'kvs> for Count {
118 fn visit_pair(&mut self, _: Key<'kvs>, _: Value<'kvs>) -> Result<(), Error> {
119 self.0 += 1;
120
121 Ok(())
122 }
123 }
124
125 let mut count = Count(0);
126 let _ = source.visit(&mut count);
127 count.0
128 }
129
130 impl<'a, T> Source for &'a T
131 where
132 T: Source + ?Sized,
133 {
visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>134 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
135 Source::visit(&**self, visitor)
136 }
137
get(&self, key: Key) -> Option<Value<'_>>138 fn get(&self, key: Key) -> Option<Value<'_>> {
139 Source::get(&**self, key)
140 }
141
count(&self) -> usize142 fn count(&self) -> usize {
143 Source::count(&**self)
144 }
145 }
146
147 impl<K, V> Source for (K, V)
148 where
149 K: ToKey,
150 V: ToValue,
151 {
visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>152 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
153 visitor.visit_pair(self.0.to_key(), self.1.to_value())
154 }
155
get(&self, key: Key) -> Option<Value<'_>>156 fn get(&self, key: Key) -> Option<Value<'_>> {
157 if self.0.to_key() == key {
158 Some(self.1.to_value())
159 } else {
160 None
161 }
162 }
163
count(&self) -> usize164 fn count(&self) -> usize {
165 1
166 }
167 }
168
169 impl<S> Source for [S]
170 where
171 S: Source,
172 {
visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>173 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
174 for source in self {
175 source.visit(visitor)?;
176 }
177
178 Ok(())
179 }
180
get(&self, key: Key) -> Option<Value<'_>>181 fn get(&self, key: Key) -> Option<Value<'_>> {
182 for source in self {
183 if let Some(found) = source.get(key.clone()) {
184 return Some(found);
185 }
186 }
187
188 None
189 }
190
count(&self) -> usize191 fn count(&self) -> usize {
192 self.iter().map(Source::count).sum()
193 }
194 }
195
196 impl<const N: usize, S> Source for [S; N]
197 where
198 S: Source,
199 {
visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>200 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
201 Source::visit(self as &[_], visitor)
202 }
203
get(&self, key: Key) -> Option<Value<'_>>204 fn get(&self, key: Key) -> Option<Value<'_>> {
205 Source::get(self as &[_], key)
206 }
207
count(&self) -> usize208 fn count(&self) -> usize {
209 Source::count(self as &[_])
210 }
211 }
212
213 impl<S> Source for Option<S>
214 where
215 S: Source,
216 {
visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>217 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
218 if let Some(source) = self {
219 source.visit(visitor)?;
220 }
221
222 Ok(())
223 }
224
get(&self, key: Key) -> Option<Value<'_>>225 fn get(&self, key: Key) -> Option<Value<'_>> {
226 self.as_ref().and_then(|s| s.get(key))
227 }
228
count(&self) -> usize229 fn count(&self) -> usize {
230 self.as_ref().map_or(0, Source::count)
231 }
232 }
233
234 /// A visitor for the key-value pairs in a [`Source`](trait.Source.html).
235 pub trait VisitSource<'kvs> {
236 /// Visit a key-value pair.
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>237 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>;
238 }
239
240 impl<'a, 'kvs, T> VisitSource<'kvs> for &'a mut T
241 where
242 T: VisitSource<'kvs> + ?Sized,
243 {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>244 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
245 (**self).visit_pair(key, value)
246 }
247 }
248
249 impl<'a, 'b: 'a, 'kvs> VisitSource<'kvs> for fmt::DebugMap<'a, 'b> {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>250 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
251 self.entry(&key, &value);
252 Ok(())
253 }
254 }
255
256 impl<'a, 'b: 'a, 'kvs> VisitSource<'kvs> for fmt::DebugList<'a, 'b> {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>257 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
258 self.entry(&(key, value));
259 Ok(())
260 }
261 }
262
263 impl<'a, 'b: 'a, 'kvs> VisitSource<'kvs> for fmt::DebugSet<'a, 'b> {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>264 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
265 self.entry(&(key, value));
266 Ok(())
267 }
268 }
269
270 impl<'a, 'b: 'a, 'kvs> VisitSource<'kvs> for fmt::DebugTuple<'a, 'b> {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>271 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
272 self.field(&key);
273 self.field(&value);
274 Ok(())
275 }
276 }
277
278 #[cfg(feature = "std")]
279 mod std_support {
280 use super::*;
281 use std::borrow::Borrow;
282 use std::collections::{BTreeMap, HashMap};
283 use std::hash::{BuildHasher, Hash};
284 use std::rc::Rc;
285 use std::sync::Arc;
286
287 impl<S> Source for Box<S>
288 where
289 S: Source + ?Sized,
290 {
visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>291 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
292 Source::visit(&**self, visitor)
293 }
294
get(&self, key: Key) -> Option<Value<'_>>295 fn get(&self, key: Key) -> Option<Value<'_>> {
296 Source::get(&**self, key)
297 }
298
count(&self) -> usize299 fn count(&self) -> usize {
300 Source::count(&**self)
301 }
302 }
303
304 impl<S> Source for Arc<S>
305 where
306 S: Source + ?Sized,
307 {
visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>308 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
309 Source::visit(&**self, visitor)
310 }
311
get(&self, key: Key) -> Option<Value<'_>>312 fn get(&self, key: Key) -> Option<Value<'_>> {
313 Source::get(&**self, key)
314 }
315
count(&self) -> usize316 fn count(&self) -> usize {
317 Source::count(&**self)
318 }
319 }
320
321 impl<S> Source for Rc<S>
322 where
323 S: Source + ?Sized,
324 {
visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>325 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
326 Source::visit(&**self, visitor)
327 }
328
get(&self, key: Key) -> Option<Value<'_>>329 fn get(&self, key: Key) -> Option<Value<'_>> {
330 Source::get(&**self, key)
331 }
332
count(&self) -> usize333 fn count(&self) -> usize {
334 Source::count(&**self)
335 }
336 }
337
338 impl<S> Source for Vec<S>
339 where
340 S: Source,
341 {
visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>342 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
343 Source::visit(&**self, visitor)
344 }
345
get(&self, key: Key) -> Option<Value<'_>>346 fn get(&self, key: Key) -> Option<Value<'_>> {
347 Source::get(&**self, key)
348 }
349
count(&self) -> usize350 fn count(&self) -> usize {
351 Source::count(&**self)
352 }
353 }
354
355 impl<'kvs, V> VisitSource<'kvs> for Box<V>
356 where
357 V: VisitSource<'kvs> + ?Sized,
358 {
visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>359 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
360 (**self).visit_pair(key, value)
361 }
362 }
363
364 impl<K, V, S> Source for HashMap<K, V, S>
365 where
366 K: ToKey + Borrow<str> + Eq + Hash,
367 V: ToValue,
368 S: BuildHasher,
369 {
visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>370 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
371 for (key, value) in self {
372 visitor.visit_pair(key.to_key(), value.to_value())?;
373 }
374 Ok(())
375 }
376
get(&self, key: Key) -> Option<Value<'_>>377 fn get(&self, key: Key) -> Option<Value<'_>> {
378 HashMap::get(self, key.as_str()).map(|v| v.to_value())
379 }
380
count(&self) -> usize381 fn count(&self) -> usize {
382 self.len()
383 }
384 }
385
386 impl<K, V> Source for BTreeMap<K, V>
387 where
388 K: ToKey + Borrow<str> + Ord,
389 V: ToValue,
390 {
visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>391 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
392 for (key, value) in self {
393 visitor.visit_pair(key.to_key(), value.to_value())?;
394 }
395 Ok(())
396 }
397
get(&self, key: Key) -> Option<Value<'_>>398 fn get(&self, key: Key) -> Option<Value<'_>> {
399 BTreeMap::get(self, key.as_str()).map(|v| v.to_value())
400 }
401
count(&self) -> usize402 fn count(&self) -> usize {
403 self.len()
404 }
405 }
406
407 #[cfg(test)]
408 mod tests {
409 use crate::kv::value;
410
411 use super::*;
412
413 #[test]
count()414 fn count() {
415 assert_eq!(1, Source::count(&Box::new(("a", 1))));
416 assert_eq!(2, Source::count(&vec![("a", 1), ("b", 2)]));
417 }
418
419 #[test]
get()420 fn get() {
421 let source = vec![("a", 1), ("b", 2), ("a", 1)];
422 assert_eq!(
423 value::inner::Token::I64(1),
424 Source::get(&source, Key::from_str("a")).unwrap().to_token()
425 );
426
427 let source = Box::new(None::<(&str, i32)>);
428 assert!(Source::get(&source, Key::from_str("a")).is_none());
429 }
430
431 #[test]
hash_map()432 fn hash_map() {
433 let mut map = HashMap::new();
434 map.insert("a", 1);
435 map.insert("b", 2);
436
437 assert_eq!(2, Source::count(&map));
438 assert_eq!(
439 value::inner::Token::I64(1),
440 Source::get(&map, Key::from_str("a")).unwrap().to_token()
441 );
442 }
443
444 #[test]
btree_map()445 fn btree_map() {
446 let mut map = BTreeMap::new();
447 map.insert("a", 1);
448 map.insert("b", 2);
449
450 assert_eq!(2, Source::count(&map));
451 assert_eq!(
452 value::inner::Token::I64(1),
453 Source::get(&map, Key::from_str("a")).unwrap().to_token()
454 );
455 }
456 }
457 }
458
459 // NOTE: Deprecated; but aliases can't carry this attribute
460 #[cfg(feature = "kv_unstable")]
461 pub use VisitSource as Visitor;
462
463 #[cfg(test)]
464 mod tests {
465 use crate::kv::value;
466
467 use super::*;
468
469 #[test]
source_is_object_safe()470 fn source_is_object_safe() {
471 fn _check(_: &dyn Source) {}
472 }
473
474 #[test]
visitor_is_object_safe()475 fn visitor_is_object_safe() {
476 fn _check(_: &dyn VisitSource) {}
477 }
478
479 #[test]
count()480 fn count() {
481 struct OnePair {
482 key: &'static str,
483 value: i32,
484 }
485
486 impl Source for OnePair {
487 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
488 visitor.visit_pair(self.key.to_key(), self.value.to_value())
489 }
490 }
491
492 assert_eq!(1, Source::count(&("a", 1)));
493 assert_eq!(2, Source::count(&[("a", 1), ("b", 2)] as &[_]));
494 assert_eq!(0, Source::count(&None::<(&str, i32)>));
495 assert_eq!(1, Source::count(&OnePair { key: "a", value: 1 }));
496 }
497
498 #[test]
get()499 fn get() {
500 let source = &[("a", 1), ("b", 2), ("a", 1)] as &[_];
501 assert_eq!(
502 value::inner::Token::I64(1),
503 Source::get(source, Key::from_str("a")).unwrap().to_token()
504 );
505 assert_eq!(
506 value::inner::Token::I64(2),
507 Source::get(source, Key::from_str("b")).unwrap().to_token()
508 );
509 assert!(Source::get(&source, Key::from_str("c")).is_none());
510
511 let source = None::<(&str, i32)>;
512 assert!(Source::get(&source, Key::from_str("a")).is_none());
513 }
514 }
515