1use crate::kv::{Error, Key, ToKey, ToValue, Value};
7use std::fmt;
8
9pub trait Source {
52 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error>;
63
64 fn get(&self, key: Key) -> Option<Value<'_>> {
74 get_default(self, key)
75 }
76
77 fn count(&self) -> usize {
86 count_default(self)
87 }
88}
89
90fn 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
113fn 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
130impl<T> Source for &T
131where
132 T: Source + ?Sized,
133{
134 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
135 Source::visit(&**self, visitor)
136 }
137
138 fn get(&self, key: Key) -> Option<Value<'_>> {
139 Source::get(&**self, key)
140 }
141
142 fn count(&self) -> usize {
143 Source::count(&**self)
144 }
145}
146
147impl<K, V> Source for (K, V)
148where
149 K: ToKey,
150 V: ToValue,
151{
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
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
164 fn count(&self) -> usize {
165 1
166 }
167}
168
169impl<S> Source for [S]
170where
171 S: Source,
172{
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
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
191 fn count(&self) -> usize {
192 self.iter().map(Source::count).sum()
193 }
194}
195
196impl<const N: usize, S> Source for [S; N]
197where
198 S: Source,
199{
200 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
201 Source::visit(self as &[_], visitor)
202 }
203
204 fn get(&self, key: Key) -> Option<Value<'_>> {
205 Source::get(self as &[_], key)
206 }
207
208 fn count(&self) -> usize {
209 Source::count(self as &[_])
210 }
211}
212
213impl<S> Source for Option<S>
214where
215 S: Source,
216{
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
225 fn get(&self, key: Key) -> Option<Value<'_>> {
226 self.as_ref().and_then(|s| s.get(key))
227 }
228
229 fn count(&self) -> usize {
230 self.as_ref().map_or(0, Source::count)
231 }
232}
233
234pub trait VisitSource<'kvs> {
236 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>;
238}
239
240#[allow(clippy::needless_lifetimes)] impl<'a, 'kvs, T> VisitSource<'kvs> for &'a mut T
242where
243 T: VisitSource<'kvs> + ?Sized,
244{
245 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
246 (**self).visit_pair(key, value)
247 }
248}
249
250impl<'a, 'b: 'a, 'kvs> VisitSource<'kvs> for fmt::DebugMap<'a, 'b> {
251 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
252 self.entry(&key, &value);
253 Ok(())
254 }
255}
256
257impl<'a, 'b: 'a, 'kvs> VisitSource<'kvs> for fmt::DebugList<'a, 'b> {
258 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
259 self.entry(&(key, value));
260 Ok(())
261 }
262}
263
264impl<'a, 'b: 'a, 'kvs> VisitSource<'kvs> for fmt::DebugSet<'a, 'b> {
265 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
266 self.entry(&(key, value));
267 Ok(())
268 }
269}
270
271impl<'a, 'b: 'a, 'kvs> VisitSource<'kvs> for fmt::DebugTuple<'a, 'b> {
272 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
273 self.field(&key);
274 self.field(&value);
275 Ok(())
276 }
277}
278
279#[cfg(feature = "std")]
280mod 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 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
293 Source::visit(&**self, visitor)
294 }
295
296 fn get(&self, key: Key) -> Option<Value<'_>> {
297 Source::get(&**self, key)
298 }
299
300 fn count(&self) -> usize {
301 Source::count(&**self)
302 }
303 }
304
305 impl<S> Source for Arc<S>
306 where
307 S: Source + ?Sized,
308 {
309 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
310 Source::visit(&**self, visitor)
311 }
312
313 fn get(&self, key: Key) -> Option<Value<'_>> {
314 Source::get(&**self, key)
315 }
316
317 fn count(&self) -> usize {
318 Source::count(&**self)
319 }
320 }
321
322 impl<S> Source for Rc<S>
323 where
324 S: Source + ?Sized,
325 {
326 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
327 Source::visit(&**self, visitor)
328 }
329
330 fn get(&self, key: Key) -> Option<Value<'_>> {
331 Source::get(&**self, key)
332 }
333
334 fn count(&self) -> usize {
335 Source::count(&**self)
336 }
337 }
338
339 impl<S> Source for Vec<S>
340 where
341 S: Source,
342 {
343 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
344 Source::visit(&**self, visitor)
345 }
346
347 fn get(&self, key: Key) -> Option<Value<'_>> {
348 Source::get(&**self, key)
349 }
350
351 fn count(&self) -> usize {
352 Source::count(&**self)
353 }
354 }
355
356 impl<'kvs, V> VisitSource<'kvs> for Box<V>
357 where
358 V: VisitSource<'kvs> + ?Sized,
359 {
360 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
361 (**self).visit_pair(key, value)
362 }
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 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
372 for (key, value) in self {
373 visitor.visit_pair(key.to_key(), value.to_value())?;
374 }
375 Ok(())
376 }
377
378 fn get(&self, key: Key) -> Option<Value<'_>> {
379 HashMap::get(self, key.as_str()).map(|v| v.to_value())
380 }
381
382 fn count(&self) -> usize {
383 self.len()
384 }
385 }
386
387 impl<K, V> Source for BTreeMap<K, V>
388 where
389 K: ToKey + Borrow<str> + Ord,
390 V: ToValue,
391 {
392 fn visit<'kvs>(&'kvs self, visitor: &mut dyn VisitSource<'kvs>) -> Result<(), Error> {
393 for (key, value) in self {
394 visitor.visit_pair(key.to_key(), value.to_value())?;
395 }
396 Ok(())
397 }
398
399 fn get(&self, key: Key) -> Option<Value<'_>> {
400 BTreeMap::get(self, key.as_str()).map(|v| v.to_value())
401 }
402
403 fn count(&self) -> usize {
404 self.len()
405 }
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#[cfg(feature = "kv_unstable")]
462pub use VisitSource as Visitor;
463
464#[cfg(test)]
465mod 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}