/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 | | } |