Coverage Report

Created: 2026-09-28 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/log-0.4.33/src/kv/source.rs
Line
Count
Source
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.
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.
73
0
    fn get(&self, key: Key) -> Option<Value<'_>> {
74
0
        get_default(self, key)
75
0
    }
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.
85
0
    fn count(&self) -> usize {
86
0
        count_default(self)
87
0
    }
88
}
89
90
/// The default implementation of `Source::get`
91
0
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
0
        fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
99
0
            if self.key == key {
100
0
                self.found = Some(value);
101
0
            }
102
103
0
            Ok(())
104
0
        }
105
    }
106
107
0
    let mut get = Get { key, found: None };
108
109
0
    let _ = source.visit(&mut get);
110
0
    get.found
111
0
}
112
113
/// The default implementation of `Source::count`.
114
0
fn count_default(source: impl Source) -> usize {
115
    struct Count(usize);
116
117
    impl<'kvs> VisitSource<'kvs> for Count {
118
0
        fn visit_pair(&mut self, _: Key<'kvs>, _: Value<'kvs>) -> Result<(), Error> {
119
0
            self.0 += 1;
120
121
0
            Ok(())
122
0
        }
123
    }
124
125
0
    let mut count = Count(0);
126
0
    let _ = source.visit(&mut count);
127
0
    count.0
128
0
}
129
130
impl<T> Source for &T
131
where
132
    T: Source + ?Sized,
133
{
134
0
    fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
135
0
        Source::visit(&**self, visitor)
136
0
    }
Unexecuted instantiation: <&[(log::kv::key::Key, log::kv::value::Value)] as log::kv::source::Source>::visit
Unexecuted instantiation: <&[(log::kv::key::Key, log::kv::value::Value)] as log::kv::source::Source>::visit
Unexecuted instantiation: <&_ as log::kv::source::Source>::visit
137
138
0
    fn get(&self, key: Key) -> Option<Value<'_>> {
139
0
        Source::get(&**self, key)
140
0
    }
Unexecuted instantiation: <&[(log::kv::key::Key, log::kv::value::Value)] as log::kv::source::Source>::get
Unexecuted instantiation: <&[(log::kv::key::Key, log::kv::value::Value)] as log::kv::source::Source>::get
Unexecuted instantiation: <&_ as log::kv::source::Source>::get
141
142
0
    fn count(&self) -> usize {
143
0
        Source::count(&**self)
144
0
    }
Unexecuted instantiation: <&[(log::kv::key::Key, log::kv::value::Value)] as log::kv::source::Source>::count
Unexecuted instantiation: <&[(log::kv::key::Key, log::kv::value::Value)] as log::kv::source::Source>::count
Unexecuted instantiation: <&_ as log::kv::source::Source>::count
145
}
146
147
impl<K, V> Source for (K, V)
148
where
149
    K: ToKey,
150
    V: ToValue,
151
{
152
0
    fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
153
0
        visitor.visit_pair(self.0.to_key(), self.1.to_value())
154
0
    }
155
156
0
    fn get(&self, key: Key) -> Option<Value<'_>> {
157
0
        if self.0.to_key() == key {
158
0
            Some(self.1.to_value())
159
        } else {
160
0
            None
161
        }
162
0
    }
163
164
0
    fn count(&self) -> usize {
165
0
        1
166
0
    }
167
}
168
169
impl<S> Source for [S]
170
where
171
    S: Source,
172
{
173
0
    fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
174
0
        for source in self {
175
0
            source.visit(visitor)?;
176
        }
177
178
0
        Ok(())
179
0
    }
Unexecuted instantiation: <[(log::kv::key::Key, log::kv::value::Value)] as log::kv::source::Source>::visit
Unexecuted instantiation: <[(log::kv::key::Key, log::kv::value::Value)] as log::kv::source::Source>::visit
Unexecuted instantiation: <[_] as log::kv::source::Source>::visit
180
181
0
    fn get(&self, key: Key) -> Option<Value<'_>> {
182
0
        for source in self {
183
0
            if let Some(found) = source.get(key.clone()) {
184
0
                return Some(found);
185
0
            }
186
        }
187
188
0
        None
189
0
    }
Unexecuted instantiation: <[(log::kv::key::Key, log::kv::value::Value)] as log::kv::source::Source>::get
Unexecuted instantiation: <[(log::kv::key::Key, log::kv::value::Value)] as log::kv::source::Source>::get
Unexecuted instantiation: <[_] as log::kv::source::Source>::get
190
191
0
    fn count(&self) -> usize {
192
0
        self.iter().map(Source::count).sum()
193
0
    }
Unexecuted instantiation: <[(log::kv::key::Key, log::kv::value::Value)] as log::kv::source::Source>::count
Unexecuted instantiation: <[(log::kv::key::Key, log::kv::value::Value)] as log::kv::source::Source>::count
Unexecuted instantiation: <[_] as log::kv::source::Source>::count
194
}
195
196
impl<const N: usize, S> Source for [S; N]
197
where
198
    S: Source,
199
{
200
0
    fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
201
0
        Source::visit(self as &[_], visitor)
202
0
    }
203
204
0
    fn get(&self, key: Key) -> Option<Value<'_>> {
205
0
        Source::get(self as &[_], key)
206
0
    }
207
208
0
    fn count(&self) -> usize {
209
0
        Source::count(self as &[_])
210
0
    }
211
}
212
213
impl<S> Source for Option<S>
214
where
215
    S: Source,
216
{
217
0
    fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
218
0
        if let Some(source) = self {
219
0
            source.visit(visitor)?;
220
0
        }
221
222
0
        Ok(())
223
0
    }
Unexecuted instantiation: <core::option::Option<&[(log::kv::key::Key, log::kv::value::Value)]> as log::kv::source::Source>::visit
Unexecuted instantiation: <core::option::Option<&[(log::kv::key::Key, log::kv::value::Value)]> as log::kv::source::Source>::visit
Unexecuted instantiation: <core::option::Option<(log::kv::key::Key, log::kv::value::Value)> as log::kv::source::Source>::visit
224
225
0
    fn get(&self, key: Key) -> Option<Value<'_>> {
226
0
        self.as_ref().and_then(|s| s.get(key))
Unexecuted instantiation: <core::option::Option<&[(log::kv::key::Key, log::kv::value::Value)]> as log::kv::source::Source>::get::{closure#0}
Unexecuted instantiation: <core::option::Option<&[(log::kv::key::Key, log::kv::value::Value)]> as log::kv::source::Source>::get::{closure#0}
Unexecuted instantiation: <core::option::Option<(log::kv::key::Key, log::kv::value::Value)> as log::kv::source::Source>::get::{closure#0}
227
0
    }
Unexecuted instantiation: <core::option::Option<&[(log::kv::key::Key, log::kv::value::Value)]> as log::kv::source::Source>::get
Unexecuted instantiation: <core::option::Option<&[(log::kv::key::Key, log::kv::value::Value)]> as log::kv::source::Source>::get
Unexecuted instantiation: <core::option::Option<(log::kv::key::Key, log::kv::value::Value)> as log::kv::source::Source>::get
228
229
0
    fn count(&self) -> usize {
230
0
        self.as_ref().map_or(0, Source::count)
231
0
    }
Unexecuted instantiation: <core::option::Option<&[(log::kv::key::Key, log::kv::value::Value)]> as log::kv::source::Source>::count
Unexecuted instantiation: <core::option::Option<&[(log::kv::key::Key, log::kv::value::Value)]> as log::kv::source::Source>::count
Unexecuted instantiation: <core::option::Option<(log::kv::key::Key, log::kv::value::Value)> as log::kv::source::Source>::count
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.
237
    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>;
238
}
239
240
#[allow(clippy::needless_lifetimes)] // Not needless.
241
impl<'a, 'kvs, T> VisitSource<'kvs> for &'a mut T
242
where
243
    T: VisitSource<'kvs> + ?Sized,
244
{
245
0
    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
246
0
        (**self).visit_pair(key, value)
247
0
    }
248
}
249
250
impl<'a, 'b: 'a, 'kvs> VisitSource<'kvs> for fmt::DebugMap<'a, 'b> {
251
0
    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
252
0
        self.entry(&key, &value);
253
0
        Ok(())
254
0
    }
255
}
256
257
impl<'a, 'b: 'a, 'kvs> VisitSource<'kvs> for fmt::DebugList<'a, 'b> {
258
0
    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
259
0
        self.entry(&(key, value));
260
0
        Ok(())
261
0
    }
262
}
263
264
impl<'a, 'b: 'a, 'kvs> VisitSource<'kvs> for fmt::DebugSet<'a, 'b> {
265
0
    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
266
0
        self.entry(&(key, value));
267
0
        Ok(())
268
0
    }
269
}
270
271
impl<'a, 'b: 'a, 'kvs> VisitSource<'kvs> for fmt::DebugTuple<'a, 'b> {
272
0
    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
273
0
        self.field(&key);
274
0
        self.field(&value);
275
0
        Ok(())
276
0
    }
277
}
278
279
#[cfg(feature = "std")]
280
mod std_support {
281
    use super::*;
282
    use std::borrow::Borrow;
283
    use std::collections::{BTreeMap, HashMap};
284
    use std::hash::{BuildHasher, Hash};
285
    use std::rc::Rc;
286
    use std::sync::Arc;
287
288
    impl<S> Source for Box<S>
289
    where
290
        S: Source + ?Sized,
291
    {
292
0
        fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
293
0
            Source::visit(&**self, visitor)
294
0
        }
295
296
0
        fn get(&self, key: Key) -> Option<Value<'_>> {
297
0
            Source::get(&**self, key)
298
0
        }
299
300
0
        fn count(&self) -> usize {
301
0
            Source::count(&**self)
302
0
        }
303
    }
304
305
    impl<S> Source for Arc<S>
306
    where
307
        S: Source + ?Sized,
308
    {
309
0
        fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
310
0
            Source::visit(&**self, visitor)
311
0
        }
312
313
0
        fn get(&self, key: Key) -> Option<Value<'_>> {
314
0
            Source::get(&**self, key)
315
0
        }
316
317
0
        fn count(&self) -> usize {
318
0
            Source::count(&**self)
319
0
        }
320
    }
321
322
    impl<S> Source for Rc<S>
323
    where
324
        S: Source + ?Sized,
325
    {
326
0
        fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
327
0
            Source::visit(&**self, visitor)
328
0
        }
329
330
0
        fn get(&self, key: Key) -> Option<Value<'_>> {
331
0
            Source::get(&**self, key)
332
0
        }
333
334
0
        fn count(&self) -> usize {
335
0
            Source::count(&**self)
336
0
        }
337
    }
338
339
    impl<S> Source for Vec<S>
340
    where
341
        S: Source,
342
    {
343
0
        fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
344
0
            Source::visit(&**self, visitor)
345
0
        }
346
347
0
        fn get(&self, key: Key) -> Option<Value<'_>> {
348
0
            Source::get(&**self, key)
349
0
        }
350
351
0
        fn count(&self) -> usize {
352
0
            Source::count(&**self)
353
0
        }
354
    }
355
356
    impl<'kvs, V> VisitSource<'kvs> for Box<V>
357
    where
358
        V: VisitSource<'kvs> + ?Sized,
359
    {
360
0
        fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
361
0
            (**self).visit_pair(key, value)
362
0
        }
363
    }
364
365
    impl<K, V, S> Source for HashMap<K, V, S>
366
    where
367
        K: ToKey + Borrow<str> + Eq + Hash,
368
        V: ToValue,
369
        S: BuildHasher,
370
    {
371
0
        fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
372
0
            for (key, value) in self {
373
0
                visitor.visit_pair(key.to_key(), value.to_value())?;
374
            }
375
0
            Ok(())
376
0
        }
377
378
0
        fn get(&self, key: Key) -> Option<Value<'_>> {
379
0
            HashMap::get(self, key.as_str()).map(|v| v.to_value())
380
0
        }
381
382
0
        fn count(&self) -> usize {
383
0
            self.len()
384
0
        }
385
    }
386
387
    impl<K, V> Source for BTreeMap<K, V>
388
    where
389
        K: ToKey + Borrow<str> + Ord,
390
        V: ToValue,
391
    {
392
0
        fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
393
0
            for (key, value) in self {
394
0
                visitor.visit_pair(key.to_key(), value.to_value())?;
395
            }
396
0
            Ok(())
397
0
        }
398
399
0
        fn get(&self, key: Key) -> Option<Value<'_>> {
400
0
            BTreeMap::get(self, key.as_str()).map(|v| v.to_value())
401
0
        }
402
403
0
        fn count(&self) -> usize {
404
0
            self.len()
405
0
        }
406
    }
407
408
    #[cfg(test)]
409
    mod tests {
410
        use crate::kv::value;
411
412
        use super::*;
413
414
        #[test]
415
        fn count() {
416
            assert_eq!(1, Source::count(&Box::new(("a", 1))));
417
            assert_eq!(2, Source::count(&vec![("a", 1), ("b", 2)]));
418
        }
419
420
        #[test]
421
        fn get() {
422
            let source = vec![("a", 1), ("b", 2), ("a", 1)];
423
            assert_eq!(
424
                value::inner::Token::I64(1),
425
                Source::get(&source, Key::from_str("a")).unwrap().to_token()
426
            );
427
428
            let source = Box::new(None::<(&str, i32)>);
429
            assert!(Source::get(&source, Key::from_str("a")).is_none());
430
        }
431
432
        #[test]
433
        fn hash_map() {
434
            let mut map = HashMap::new();
435
            map.insert("a", 1);
436
            map.insert("b", 2);
437
438
            assert_eq!(2, Source::count(&map));
439
            assert_eq!(
440
                value::inner::Token::I64(1),
441
                Source::get(&map, Key::from_str("a")).unwrap().to_token()
442
            );
443
        }
444
445
        #[test]
446
        fn btree_map() {
447
            let mut map = BTreeMap::new();
448
            map.insert("a", 1);
449
            map.insert("b", 2);
450
451
            assert_eq!(2, Source::count(&map));
452
            assert_eq!(
453
                value::inner::Token::I64(1),
454
                Source::get(&map, Key::from_str("a")).unwrap().to_token()
455
            );
456
        }
457
    }
458
}
459
460
// NOTE: Deprecated; but aliases can't carry this attribute
461
#[cfg(feature = "kv_unstable")]
462
pub use VisitSource as Visitor;
463
464
#[cfg(test)]
465
mod tests {
466
    use crate::kv::value;
467
468
    use super::*;
469
470
    #[test]
471
    fn source_is_object_safe() {
472
        fn _check(_: &dyn Source) {}
473
    }
474
475
    #[test]
476
    fn visitor_is_object_safe() {
477
        fn _check(_: &dyn VisitSource) {}
478
    }
479
480
    #[test]
481
    fn count() {
482
        struct OnePair {
483
            key: &'static str,
484
            value: i32,
485
        }
486
487
        impl Source for OnePair {
488
            fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
489
                visitor.visit_pair(self.key.to_key(), self.value.to_value())
490
            }
491
        }
492
493
        assert_eq!(1, Source::count(&("a", 1)));
494
        assert_eq!(2, Source::count(&[("a", 1), ("b", 2)] as &[_]));
495
        assert_eq!(0, Source::count(&None::<(&str, i32)>));
496
        assert_eq!(1, Source::count(&OnePair { key: "a", value: 1 }));
497
    }
498
499
    #[test]
500
    fn get() {
501
        let source = &[("a", 1), ("b", 2), ("a", 1)] as &[_];
502
        assert_eq!(
503
            value::inner::Token::I64(1),
504
            Source::get(source, Key::from_str("a")).unwrap().to_token()
505
        );
506
        assert_eq!(
507
            value::inner::Token::I64(2),
508
            Source::get(source, Key::from_str("b")).unwrap().to_token()
509
        );
510
        assert!(Source::get(&source, Key::from_str("c")).is_none());
511
512
        let source = None::<(&str, i32)>;
513
        assert!(Source::get(&source, Key::from_str("a")).is_none());
514
    }
515
}