xref: /third_party/rust/crates/log/src/kv/source.rs (revision 2d8ae3ab)
1//! Sources for key-value pairs.
2
3#[cfg(feature = "kv_unstable_sval")]
4extern crate sval;
5
6#[cfg(feature = "kv_unstable_serde")]
7extern crate serde;
8
9use kv::{Error, Key, ToKey, ToValue, Value};
10use std::fmt;
11
12/// A source of key-value pairs.
13///
14/// The source may be a single pair, a set of pairs, or a filter over a set of pairs.
15/// Use the [`Visitor`](trait.Visitor.html) trait to inspect the structured data
16/// in a source.
17pub trait Source {
18    /// Visit key-value pairs.
19    ///
20    /// A source doesn't have to guarantee any ordering or uniqueness of key-value pairs.
21    /// If the given visitor returns an error then the source may early-return with it,
22    /// even if there are more key-value pairs.
23    ///
24    /// # Implementation notes
25    ///
26    /// A source should yield the same key-value pairs to a subsequent visitor unless
27    /// that visitor itself fails.
28    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>;
29
30    /// Get the value for a given key.
31    ///
32    /// If the key appears multiple times in the source then which key is returned
33    /// is implementation specific.
34    ///
35    /// # Implementation notes
36    ///
37    /// A source that can provide a more efficient implementation of this method
38    /// should override it.
39    #[cfg(not(test))]
40    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
41        get_default(self, key)
42    }
43
44    #[cfg(test)]
45    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>>;
46
47    /// Count the number of key-value pairs that can be visited.
48    ///
49    /// # Implementation notes
50    ///
51    /// A source that knows the number of key-value pairs upfront may provide a more
52    /// efficient implementation.
53    ///
54    /// A subsequent call to `visit` should yield the same number of key-value pairs
55    /// to the visitor, unless that visitor fails part way through.
56    #[cfg(not(test))]
57    fn count(&self) -> usize {
58        count_default(self)
59    }
60
61    #[cfg(test)]
62    fn count(&self) -> usize;
63}
64
65/// The default implemention of `Source::get`
66pub(crate) fn get_default<'v>(source: &'v (impl Source + ?Sized), key: Key) -> Option<Value<'v>> {
67    struct Get<'k, 'v> {
68        key: Key<'k>,
69        found: Option<Value<'v>>,
70    }
71
72    impl<'k, 'kvs> Visitor<'kvs> for Get<'k, 'kvs> {
73        fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
74            if self.key == key {
75                self.found = Some(value);
76            }
77
78            Ok(())
79        }
80    }
81
82    let mut get = Get { key, found: None };
83
84    let _ = source.visit(&mut get);
85    get.found
86}
87
88/// The default implementation of `Source::count`.
89pub(crate) fn count_default(source: impl Source) -> usize {
90    struct Count(usize);
91
92    impl<'kvs> Visitor<'kvs> for Count {
93        fn visit_pair(&mut self, _: Key<'kvs>, _: Value<'kvs>) -> Result<(), Error> {
94            self.0 += 1;
95
96            Ok(())
97        }
98    }
99
100    let mut count = Count(0);
101    let _ = source.visit(&mut count);
102    count.0
103}
104
105impl<'a, T> Source for &'a T
106where
107    T: Source + ?Sized,
108{
109    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
110        Source::visit(&**self, visitor)
111    }
112
113    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
114        Source::get(&**self, key)
115    }
116
117    fn count(&self) -> usize {
118        Source::count(&**self)
119    }
120}
121
122impl<K, V> Source for (K, V)
123where
124    K: ToKey,
125    V: ToValue,
126{
127    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
128        visitor.visit_pair(self.0.to_key(), self.1.to_value())
129    }
130
131    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
132        if self.0.to_key() == key {
133            Some(self.1.to_value())
134        } else {
135            None
136        }
137    }
138
139    fn count(&self) -> usize {
140        1
141    }
142}
143
144impl<S> Source for [S]
145where
146    S: Source,
147{
148    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
149        for source in self {
150            source.visit(visitor)?;
151        }
152
153        Ok(())
154    }
155
156    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
157        for source in self {
158            if let Some(found) = source.get(key.clone()) {
159                return Some(found);
160            }
161        }
162
163        None
164    }
165
166    fn count(&self) -> usize {
167        self.len()
168    }
169}
170
171impl<S> Source for Option<S>
172where
173    S: Source,
174{
175    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
176        if let Some(ref source) = *self {
177            source.visit(visitor)?;
178        }
179
180        Ok(())
181    }
182
183    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
184        self.as_ref().and_then(|s| s.get(key))
185    }
186
187    fn count(&self) -> usize {
188        self.as_ref().map(Source::count).unwrap_or(0)
189    }
190}
191
192/// A visitor for the key-value pairs in a [`Source`](trait.Source.html).
193pub trait Visitor<'kvs> {
194    /// Visit a key-value pair.
195    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>;
196}
197
198impl<'a, 'kvs, T> Visitor<'kvs> for &'a mut T
199where
200    T: Visitor<'kvs> + ?Sized,
201{
202    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
203        (**self).visit_pair(key, value)
204    }
205}
206
207impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugMap<'a, 'b> {
208    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
209        self.entry(&key, &value);
210        Ok(())
211    }
212}
213
214impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugList<'a, 'b> {
215    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
216        self.entry(&(key, value));
217        Ok(())
218    }
219}
220
221impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugSet<'a, 'b> {
222    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
223        self.entry(&(key, value));
224        Ok(())
225    }
226}
227
228impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugTuple<'a, 'b> {
229    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
230        self.field(&key);
231        self.field(&value);
232        Ok(())
233    }
234}
235
236#[cfg(feature = "std")]
237mod std_support {
238    use super::*;
239    use std::borrow::Borrow;
240    use std::collections::{BTreeMap, HashMap};
241    use std::hash::{BuildHasher, Hash};
242
243    impl<S> Source for Box<S>
244    where
245        S: Source + ?Sized,
246    {
247        fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
248            Source::visit(&**self, visitor)
249        }
250
251        fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
252            Source::get(&**self, key)
253        }
254
255        fn count(&self) -> usize {
256            Source::count(&**self)
257        }
258    }
259
260    impl<S> Source for Vec<S>
261    where
262        S: Source,
263    {
264        fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
265            Source::visit(&**self, visitor)
266        }
267
268        fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
269            Source::get(&**self, key)
270        }
271
272        fn count(&self) -> usize {
273            Source::count(&**self)
274        }
275    }
276
277    impl<'kvs, V> Visitor<'kvs> for Box<V>
278    where
279        V: Visitor<'kvs> + ?Sized,
280    {
281        fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
282            (**self).visit_pair(key, value)
283        }
284    }
285
286    impl<K, V, S> Source for HashMap<K, V, S>
287    where
288        K: ToKey + Borrow<str> + Eq + Hash,
289        V: ToValue,
290        S: BuildHasher,
291    {
292        fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
293            for (key, value) in self {
294                visitor.visit_pair(key.to_key(), value.to_value())?;
295            }
296            Ok(())
297        }
298
299        fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
300            HashMap::get(self, key.as_str()).map(|v| v.to_value())
301        }
302
303        fn count(&self) -> usize {
304            self.len()
305        }
306    }
307
308    impl<K, V> Source for BTreeMap<K, V>
309    where
310        K: ToKey + Borrow<str> + Ord,
311        V: ToValue,
312    {
313        fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
314            for (key, value) in self {
315                visitor.visit_pair(key.to_key(), value.to_value())?;
316            }
317            Ok(())
318        }
319
320        fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
321            BTreeMap::get(self, key.as_str()).map(|v| v.to_value())
322        }
323
324        fn count(&self) -> usize {
325            self.len()
326        }
327    }
328
329    #[cfg(test)]
330    mod tests {
331        use super::*;
332        use kv::value::tests::Token;
333        use std::collections::{BTreeMap, HashMap};
334
335        #[test]
336        fn count() {
337            assert_eq!(1, Source::count(&Box::new(("a", 1))));
338            assert_eq!(2, Source::count(&vec![("a", 1), ("b", 2)]));
339        }
340
341        #[test]
342        fn get() {
343            let source = vec![("a", 1), ("b", 2), ("a", 1)];
344            assert_eq!(
345                Token::I64(1),
346                Source::get(&source, Key::from_str("a")).unwrap().to_token()
347            );
348
349            let source = Box::new(Option::None::<(&str, i32)>);
350            assert!(Source::get(&source, Key::from_str("a")).is_none());
351        }
352
353        #[test]
354        fn hash_map() {
355            let mut map = HashMap::new();
356            map.insert("a", 1);
357            map.insert("b", 2);
358
359            assert_eq!(2, Source::count(&map));
360            assert_eq!(
361                Token::I64(1),
362                Source::get(&map, Key::from_str("a")).unwrap().to_token()
363            );
364        }
365
366        #[test]
367        fn btree_map() {
368            let mut map = BTreeMap::new();
369            map.insert("a", 1);
370            map.insert("b", 2);
371
372            assert_eq!(2, Source::count(&map));
373            assert_eq!(
374                Token::I64(1),
375                Source::get(&map, Key::from_str("a")).unwrap().to_token()
376            );
377        }
378    }
379}
380
381/// The result of calling `Source::as_map`.
382pub struct AsMap<S>(S);
383
384/// Visit this source as a map.
385pub fn as_map<S>(source: S) -> AsMap<S>
386where
387    S: Source,
388{
389    AsMap(source)
390}
391
392impl<S> Source for AsMap<S>
393where
394    S: Source,
395{
396    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
397        self.0.visit(visitor)
398    }
399
400    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
401        self.0.get(key)
402    }
403
404    fn count(&self) -> usize {
405        self.0.count()
406    }
407}
408
409impl<S> fmt::Debug for AsMap<S>
410where
411    S: Source,
412{
413    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
414        let mut f = f.debug_map();
415        self.0.visit(&mut f).map_err(|_| fmt::Error)?;
416        f.finish()
417    }
418}
419
420/// The result of calling `Source::as_list`
421pub struct AsList<S>(S);
422
423/// Visit this source as a list.
424pub fn as_list<S>(source: S) -> AsList<S>
425where
426    S: Source,
427{
428    AsList(source)
429}
430
431impl<S> Source for AsList<S>
432where
433    S: Source,
434{
435    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
436        self.0.visit(visitor)
437    }
438
439    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
440        self.0.get(key)
441    }
442
443    fn count(&self) -> usize {
444        self.0.count()
445    }
446}
447
448impl<S> fmt::Debug for AsList<S>
449where
450    S: Source,
451{
452    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
453        let mut f = f.debug_list();
454        self.0.visit(&mut f).map_err(|_| fmt::Error)?;
455        f.finish()
456    }
457}
458
459#[cfg(feature = "kv_unstable_sval")]
460mod sval_support {
461    use super::*;
462
463    use self::sval::value;
464
465    impl<S> value::Value for AsMap<S>
466    where
467        S: Source,
468    {
469        fn stream(&self, stream: &mut value::Stream) -> value::Result {
470            struct StreamVisitor<'a, 'b>(&'a mut value::Stream<'b>);
471
472            impl<'a, 'b, 'kvs> Visitor<'kvs> for StreamVisitor<'a, 'b> {
473                fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
474                    self.0
475                        .map_key(key)
476                        .map_err(|_| Error::msg("failed to stream map key"))?;
477                    self.0
478                        .map_value(value)
479                        .map_err(|_| Error::msg("failed to stream map value"))?;
480                    Ok(())
481                }
482            }
483
484            stream
485                .map_begin(Some(self.count()))
486                .map_err(|_| self::sval::Error::msg("failed to begin map"))?;
487
488            self.visit(&mut StreamVisitor(stream))
489                .map_err(|_| self::sval::Error::msg("failed to visit key-values"))?;
490
491            stream
492                .map_end()
493                .map_err(|_| self::sval::Error::msg("failed to end map"))
494        }
495    }
496
497    impl<S> value::Value for AsList<S>
498    where
499        S: Source,
500    {
501        fn stream(&self, stream: &mut value::Stream) -> value::Result {
502            struct StreamVisitor<'a, 'b>(&'a mut value::Stream<'b>);
503
504            impl<'a, 'b, 'kvs> Visitor<'kvs> for StreamVisitor<'a, 'b> {
505                fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
506                    self.0
507                        .seq_elem((key, value))
508                        .map_err(|_| Error::msg("failed to stream seq entry"))?;
509                    Ok(())
510                }
511            }
512
513            stream
514                .seq_begin(Some(self.count()))
515                .map_err(|_| self::sval::Error::msg("failed to begin seq"))?;
516
517            self.visit(&mut StreamVisitor(stream))
518                .map_err(|_| self::sval::Error::msg("failed to visit key-values"))?;
519
520            stream
521                .seq_end()
522                .map_err(|_| self::sval::Error::msg("failed to end seq"))
523        }
524    }
525
526    #[cfg(test)]
527    mod tests {
528        use super::*;
529
530        use self::sval::Value;
531
532        use crate::kv::source;
533
534        #[test]
535        fn derive_stream() {
536            #[derive(Value)]
537            pub struct MyRecordAsMap<'a> {
538                msg: &'a str,
539                kvs: source::AsMap<&'a dyn Source>,
540            }
541
542            #[derive(Value)]
543            pub struct MyRecordAsList<'a> {
544                msg: &'a str,
545                kvs: source::AsList<&'a dyn Source>,
546            }
547        }
548    }
549}
550
551#[cfg(feature = "kv_unstable_serde")]
552pub mod as_map {
553    //! `serde` adapters for serializing a `Source` as a map.
554
555    use super::*;
556
557    use self::serde::{Serialize, Serializer};
558
559    /// Serialize a `Source` as a map.
560    pub fn serialize<T, S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
561    where
562        T: Source,
563        S: Serializer,
564    {
565        as_map(source).serialize(serializer)
566    }
567}
568
569#[cfg(feature = "kv_unstable_serde")]
570pub mod as_list {
571    //! `serde` adapters for serializing a `Source` as a list.
572
573    use super::*;
574
575    use self::serde::{Serialize, Serializer};
576
577    /// Serialize a `Source` as a list.
578    pub fn serialize<T, S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
579    where
580        T: Source,
581        S: Serializer,
582    {
583        as_list(source).serialize(serializer)
584    }
585}
586
587#[cfg(feature = "kv_unstable_serde")]
588mod serde_support {
589    use super::*;
590
591    use self::serde::ser::{Error as SerError, Serialize, SerializeMap, SerializeSeq, Serializer};
592
593    impl<T> Serialize for AsMap<T>
594    where
595        T: Source,
596    {
597        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
598        where
599            S: Serializer,
600        {
601            struct SerializerVisitor<'a, S>(&'a mut S);
602
603            impl<'a, 'kvs, S> Visitor<'kvs> for SerializerVisitor<'a, S>
604            where
605                S: SerializeMap,
606            {
607                fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
608                    self.0
609                        .serialize_entry(&key, &value)
610                        .map_err(|_| Error::msg("failed to serialize map entry"))?;
611                    Ok(())
612                }
613            }
614
615            let mut map = serializer.serialize_map(Some(self.count()))?;
616
617            self.visit(&mut SerializerVisitor(&mut map))
618                .map_err(|_| S::Error::custom("failed to visit key-values"))?;
619
620            map.end()
621        }
622    }
623
624    impl<T> Serialize for AsList<T>
625    where
626        T: Source,
627    {
628        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
629        where
630            S: Serializer,
631        {
632            struct SerializerVisitor<'a, S>(&'a mut S);
633
634            impl<'a, 'kvs, S> Visitor<'kvs> for SerializerVisitor<'a, S>
635            where
636                S: SerializeSeq,
637            {
638                fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
639                    self.0
640                        .serialize_element(&(key, value))
641                        .map_err(|_| Error::msg("failed to serialize seq entry"))?;
642                    Ok(())
643                }
644            }
645
646            let mut seq = serializer.serialize_seq(Some(self.count()))?;
647
648            self.visit(&mut SerializerVisitor(&mut seq))
649                .map_err(|_| S::Error::custom("failed to visit seq"))?;
650
651            seq.end()
652        }
653    }
654
655    #[cfg(test)]
656    mod tests {
657        use super::*;
658
659        use self::serde::Serialize;
660
661        use crate::kv::source;
662
663        #[test]
664        fn derive_serialize() {
665            #[derive(Serialize)]
666            pub struct MyRecordAsMap<'a> {
667                msg: &'a str,
668                #[serde(flatten)]
669                #[serde(with = "source::as_map")]
670                kvs: &'a dyn Source,
671            }
672
673            #[derive(Serialize)]
674            pub struct MyRecordAsList<'a> {
675                msg: &'a str,
676                #[serde(flatten)]
677                #[serde(with = "source::as_list")]
678                kvs: &'a dyn Source,
679            }
680        }
681    }
682}
683
684#[cfg(test)]
685mod tests {
686    use super::*;
687    use kv::value::tests::Token;
688
689    #[test]
690    fn source_is_object_safe() {
691        fn _check(_: &dyn Source) {}
692    }
693
694    #[test]
695    fn visitor_is_object_safe() {
696        fn _check(_: &dyn Visitor) {}
697    }
698
699    #[test]
700    fn count() {
701        struct OnePair {
702            key: &'static str,
703            value: i32,
704        }
705
706        impl Source for OnePair {
707            fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
708                visitor.visit_pair(self.key.to_key(), self.value.to_value())
709            }
710
711            fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
712                get_default(self, key)
713            }
714
715            fn count(&self) -> usize {
716                count_default(self)
717            }
718        }
719
720        assert_eq!(1, Source::count(&("a", 1)));
721        assert_eq!(2, Source::count(&[("a", 1), ("b", 2)] as &[_]));
722        assert_eq!(0, Source::count(&Option::None::<(&str, i32)>));
723        assert_eq!(1, Source::count(&OnePair { key: "a", value: 1 }));
724    }
725
726    #[test]
727    fn get() {
728        let source = &[("a", 1), ("b", 2), ("a", 1)] as &[_];
729        assert_eq!(
730            Token::I64(1),
731            Source::get(source, Key::from_str("a")).unwrap().to_token()
732        );
733        assert_eq!(
734            Token::I64(2),
735            Source::get(source, Key::from_str("b")).unwrap().to_token()
736        );
737        assert!(Source::get(&source, Key::from_str("c")).is_none());
738
739        let source = Option::None::<(&str, i32)>;
740        assert!(Source::get(&source, Key::from_str("a")).is_none());
741    }
742
743    #[test]
744    fn as_map() {
745        let _ = crate::kv::source::as_map(("a", 1));
746        let _ = crate::kv::source::as_map(&("a", 1) as &dyn Source);
747    }
748
749    #[test]
750    fn as_list() {
751        let _ = crate::kv::source::as_list(("a", 1));
752        let _ = crate::kv::source::as_list(&("a", 1) as &dyn Source);
753    }
754}
755