• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Structured values.
2 
3 use std::fmt;
4 
5 extern crate value_bag;
6 
7 #[cfg(feature = "kv_unstable_sval")]
8 extern crate sval;
9 
10 #[cfg(feature = "kv_unstable_serde")]
11 extern crate serde;
12 
13 use self::value_bag::ValueBag;
14 
15 pub use kv::Error;
16 
17 /// A type that can be converted into a [`Value`](struct.Value.html).
18 pub trait ToValue {
19     /// Perform the conversion.
to_value(&self) -> Value20     fn to_value(&self) -> Value;
21 }
22 
23 impl<'a, T> ToValue for &'a T
24 where
25     T: ToValue + ?Sized,
26 {
to_value(&self) -> Value27     fn to_value(&self) -> Value {
28         (**self).to_value()
29     }
30 }
31 
32 impl<'v> ToValue for Value<'v> {
to_value(&self) -> Value33     fn to_value(&self) -> Value {
34         Value {
35             inner: self.inner.clone(),
36         }
37     }
38 }
39 
40 /// Get a value from a type implementing `std::fmt::Debug`.
41 #[macro_export]
42 macro_rules! as_debug {
43     ($capture:expr) => {
44         $crate::kv::Value::from_debug(&$capture)
45     };
46 }
47 
48 /// Get a value from a type implementing `std::fmt::Display`.
49 #[macro_export]
50 macro_rules! as_display {
51     ($capture:expr) => {
52         $crate::kv::Value::from_display(&$capture)
53     };
54 }
55 
56 /// Get a value from an error.
57 #[cfg(feature = "kv_unstable_std")]
58 #[macro_export]
59 macro_rules! as_error {
60     ($capture:expr) => {
61         $crate::kv::Value::from_dyn_error(&$capture)
62     };
63 }
64 
65 #[cfg(feature = "kv_unstable_serde")]
66 /// Get a value from a type implementing `serde::Serialize`.
67 #[macro_export]
68 macro_rules! as_serde {
69     ($capture:expr) => {
70         $crate::kv::Value::from_serde(&$capture)
71     };
72 }
73 
74 /// Get a value from a type implementing `sval::value::Value`.
75 #[cfg(feature = "kv_unstable_sval")]
76 #[macro_export]
77 macro_rules! as_sval {
78     ($capture:expr) => {
79         $crate::kv::Value::from_sval(&$capture)
80     };
81 }
82 
83 /// A value in a structured key-value pair.
84 ///
85 /// # Capturing values
86 ///
87 /// There are a few ways to capture a value:
88 ///
89 /// - Using the `Value::capture_*` methods.
90 /// - Using the `Value::from_*` methods.
91 /// - Using the `ToValue` trait.
92 /// - Using the standard `From` trait.
93 ///
94 /// ## Using the `Value::capture_*` methods
95 ///
96 /// `Value` offers a few constructor methods that capture values of different kinds.
97 /// These methods require a `T: 'static` to support downcasting.
98 ///
99 /// ```
100 /// use log::kv::Value;
101 ///
102 /// let value = Value::capture_debug(&42i32);
103 ///
104 /// assert_eq!(Some(42), value.to_i64());
105 /// ```
106 ///
107 /// ## Using the `Value::from_*` methods
108 ///
109 /// `Value` offers a few constructor methods that capture values of different kinds.
110 /// These methods don't require `T: 'static`, but can't support downcasting.
111 ///
112 /// ```
113 /// use log::kv::Value;
114 ///
115 /// let value = Value::from_debug(&42i32);
116 ///
117 /// assert_eq!(None, value.to_i64());
118 /// ```
119 ///
120 /// ## Using the `ToValue` trait
121 ///
122 /// The `ToValue` trait can be used to capture values generically.
123 /// It's the bound used by `Source`.
124 ///
125 /// ```
126 /// # use log::kv::ToValue;
127 /// let value = 42i32.to_value();
128 ///
129 /// assert_eq!(Some(42), value.to_i64());
130 /// ```
131 ///
132 /// ```
133 /// # use std::fmt::Debug;
134 /// use log::kv::ToValue;
135 ///
136 /// let value = (&42i32 as &dyn Debug).to_value();
137 ///
138 /// assert_eq!(None, value.to_i64());
139 /// ```
140 ///
141 /// ## Using the standard `From` trait
142 ///
143 /// Standard types that implement `ToValue` also implement `From`.
144 ///
145 /// ```
146 /// use log::kv::Value;
147 ///
148 /// let value = Value::from(42i32);
149 ///
150 /// assert_eq!(Some(42), value.to_i64());
151 /// ```
152 pub struct Value<'v> {
153     inner: ValueBag<'v>,
154 }
155 
156 impl<'v> Value<'v> {
157     /// Get a value from a type implementing `ToValue`.
from_any<T>(value: &'v T) -> Self where T: ToValue,158     pub fn from_any<T>(value: &'v T) -> Self
159     where
160         T: ToValue,
161     {
162         value.to_value()
163     }
164 
165     /// Get a value from a type implementing `std::fmt::Debug`.
capture_debug<T>(value: &'v T) -> Self where T: fmt::Debug + 'static,166     pub fn capture_debug<T>(value: &'v T) -> Self
167     where
168         T: fmt::Debug + 'static,
169     {
170         Value {
171             inner: ValueBag::capture_debug(value),
172         }
173     }
174 
175     /// Get a value from a type implementing `std::fmt::Display`.
capture_display<T>(value: &'v T) -> Self where T: fmt::Display + 'static,176     pub fn capture_display<T>(value: &'v T) -> Self
177     where
178         T: fmt::Display + 'static,
179     {
180         Value {
181             inner: ValueBag::capture_display(value),
182         }
183     }
184 
185     /// Get a value from an error.
186     #[cfg(feature = "kv_unstable_std")]
capture_error<T>(err: &'v T) -> Self where T: std::error::Error + 'static,187     pub fn capture_error<T>(err: &'v T) -> Self
188     where
189         T: std::error::Error + 'static,
190     {
191         Value {
192             inner: ValueBag::capture_error(err),
193         }
194     }
195 
196     #[cfg(feature = "kv_unstable_serde")]
197     /// Get a value from a type implementing `serde::Serialize`.
capture_serde<T>(value: &'v T) -> Self where T: self::serde::Serialize + 'static,198     pub fn capture_serde<T>(value: &'v T) -> Self
199     where
200         T: self::serde::Serialize + 'static,
201     {
202         Value {
203             inner: ValueBag::capture_serde1(value),
204         }
205     }
206 
207     /// Get a value from a type implementing `sval::value::Value`.
208     #[cfg(feature = "kv_unstable_sval")]
capture_sval<T>(value: &'v T) -> Self where T: self::sval::value::Value + 'static,209     pub fn capture_sval<T>(value: &'v T) -> Self
210     where
211         T: self::sval::value::Value + 'static,
212     {
213         Value {
214             inner: ValueBag::capture_sval1(value),
215         }
216     }
217 
218     /// Get a value from a type implementing `std::fmt::Debug`.
from_debug<T>(value: &'v T) -> Self where T: fmt::Debug,219     pub fn from_debug<T>(value: &'v T) -> Self
220     where
221         T: fmt::Debug,
222     {
223         Value {
224             inner: ValueBag::from_debug(value),
225         }
226     }
227 
228     /// Get a value from a type implementing `std::fmt::Display`.
from_display<T>(value: &'v T) -> Self where T: fmt::Display,229     pub fn from_display<T>(value: &'v T) -> Self
230     where
231         T: fmt::Display,
232     {
233         Value {
234             inner: ValueBag::from_display(value),
235         }
236     }
237 
238     /// Get a value from a type implementing `serde::Serialize`.
239     #[cfg(feature = "kv_unstable_serde")]
from_serde<T>(value: &'v T) -> Self where T: self::serde::Serialize,240     pub fn from_serde<T>(value: &'v T) -> Self
241     where
242         T: self::serde::Serialize,
243     {
244         Value {
245             inner: ValueBag::from_serde1(value),
246         }
247     }
248 
249     /// Get a value from a type implementing `sval::value::Value`.
250     #[cfg(feature = "kv_unstable_sval")]
from_sval<T>(value: &'v T) -> Self where T: self::sval::value::Value,251     pub fn from_sval<T>(value: &'v T) -> Self
252     where
253         T: self::sval::value::Value,
254     {
255         Value {
256             inner: ValueBag::from_sval1(value),
257         }
258     }
259 
260     /// Get a value from a dynamic `std::fmt::Debug`.
from_dyn_debug(value: &'v dyn fmt::Debug) -> Self261     pub fn from_dyn_debug(value: &'v dyn fmt::Debug) -> Self {
262         Value {
263             inner: ValueBag::from_dyn_debug(value),
264         }
265     }
266 
267     /// Get a value from a dynamic `std::fmt::Display`.
from_dyn_display(value: &'v dyn fmt::Display) -> Self268     pub fn from_dyn_display(value: &'v dyn fmt::Display) -> Self {
269         Value {
270             inner: ValueBag::from_dyn_display(value),
271         }
272     }
273 
274     /// Get a value from a dynamic error.
275     #[cfg(feature = "kv_unstable_std")]
from_dyn_error(err: &'v (dyn std::error::Error + 'static)) -> Self276     pub fn from_dyn_error(err: &'v (dyn std::error::Error + 'static)) -> Self {
277         Value {
278             inner: ValueBag::from_dyn_error(err),
279         }
280     }
281 
282     /// Get a value from a type implementing `sval::value::Value`.
283     #[cfg(feature = "kv_unstable_sval")]
from_dyn_sval(value: &'v dyn self::sval::value::Value) -> Self284     pub fn from_dyn_sval(value: &'v dyn self::sval::value::Value) -> Self {
285         Value {
286             inner: ValueBag::from_dyn_sval1(value),
287         }
288     }
289 
290     /// Get a value from an internal primitive.
from_value_bag<T>(value: T) -> Self where T: Into<ValueBag<'v>>,291     fn from_value_bag<T>(value: T) -> Self
292     where
293         T: Into<ValueBag<'v>>,
294     {
295         Value {
296             inner: value.into(),
297         }
298     }
299 
300     /// Check whether this value can be downcast to `T`.
is<T: 'static>(&self) -> bool301     pub fn is<T: 'static>(&self) -> bool {
302         self.inner.is::<T>()
303     }
304 
305     /// Try downcast this value to `T`.
downcast_ref<T: 'static>(&self) -> Option<&T>306     pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
307         self.inner.downcast_ref::<T>()
308     }
309 
310     /// Inspect this value using a simple visitor.
visit(&self, visitor: impl Visit<'v>) -> Result<(), Error>311     pub fn visit(&self, visitor: impl Visit<'v>) -> Result<(), Error> {
312         struct Visitor<V>(V);
313 
314         impl<'v, V> value_bag::visit::Visit<'v> for Visitor<V>
315         where
316             V: Visit<'v>,
317         {
318             fn visit_any(&mut self, value: ValueBag) -> Result<(), value_bag::Error> {
319                 self.0
320                     .visit_any(Value { inner: value })
321                     .map_err(Error::into_value)
322             }
323 
324             fn visit_u64(&mut self, value: u64) -> Result<(), value_bag::Error> {
325                 self.0.visit_u64(value).map_err(Error::into_value)
326             }
327 
328             fn visit_i64(&mut self, value: i64) -> Result<(), value_bag::Error> {
329                 self.0.visit_i64(value).map_err(Error::into_value)
330             }
331 
332             fn visit_u128(&mut self, value: u128) -> Result<(), value_bag::Error> {
333                 self.0.visit_u128(value).map_err(Error::into_value)
334             }
335 
336             fn visit_i128(&mut self, value: i128) -> Result<(), value_bag::Error> {
337                 self.0.visit_i128(value).map_err(Error::into_value)
338             }
339 
340             fn visit_f64(&mut self, value: f64) -> Result<(), value_bag::Error> {
341                 self.0.visit_f64(value).map_err(Error::into_value)
342             }
343 
344             fn visit_bool(&mut self, value: bool) -> Result<(), value_bag::Error> {
345                 self.0.visit_bool(value).map_err(Error::into_value)
346             }
347 
348             fn visit_str(&mut self, value: &str) -> Result<(), value_bag::Error> {
349                 self.0.visit_str(value).map_err(Error::into_value)
350             }
351 
352             fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), value_bag::Error> {
353                 self.0.visit_borrowed_str(value).map_err(Error::into_value)
354             }
355 
356             fn visit_char(&mut self, value: char) -> Result<(), value_bag::Error> {
357                 self.0.visit_char(value).map_err(Error::into_value)
358             }
359 
360             #[cfg(feature = "kv_unstable_std")]
361             fn visit_error(
362                 &mut self,
363                 err: &(dyn std::error::Error + 'static),
364             ) -> Result<(), value_bag::Error> {
365                 self.0.visit_error(err).map_err(Error::into_value)
366             }
367 
368             #[cfg(feature = "kv_unstable_std")]
369             fn visit_borrowed_error(
370                 &mut self,
371                 err: &'v (dyn std::error::Error + 'static),
372             ) -> Result<(), value_bag::Error> {
373                 self.0.visit_borrowed_error(err).map_err(Error::into_value)
374             }
375         }
376 
377         self.inner
378             .visit(&mut Visitor(visitor))
379             .map_err(Error::from_value)
380     }
381 }
382 
383 impl<'v> fmt::Debug for Value<'v> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result384     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
385         fmt::Debug::fmt(&self.inner, f)
386     }
387 }
388 
389 impl<'v> fmt::Display for Value<'v> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result390     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
391         fmt::Display::fmt(&self.inner, f)
392     }
393 }
394 
395 impl ToValue for dyn fmt::Debug {
to_value(&self) -> Value396     fn to_value(&self) -> Value {
397         Value::from_dyn_debug(self)
398     }
399 }
400 
401 impl ToValue for dyn fmt::Display {
to_value(&self) -> Value402     fn to_value(&self) -> Value {
403         Value::from_dyn_display(self)
404     }
405 }
406 
407 #[cfg(feature = "kv_unstable_std")]
408 impl ToValue for dyn std::error::Error + 'static {
to_value(&self) -> Value409     fn to_value(&self) -> Value {
410         Value::from_dyn_error(self)
411     }
412 }
413 
414 #[cfg(feature = "kv_unstable_serde")]
415 impl<'v> self::serde::Serialize for Value<'v> {
serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> where S: self::serde::Serializer,416     fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
417     where
418         S: self::serde::Serializer,
419     {
420         self.inner.serialize(s)
421     }
422 }
423 
424 #[cfg(feature = "kv_unstable_sval")]
425 impl<'v> self::sval::value::Value for Value<'v> {
stream(&self, stream: &mut self::sval::value::Stream) -> self::sval::value::Result426     fn stream(&self, stream: &mut self::sval::value::Stream) -> self::sval::value::Result {
427         self::sval::value::Value::stream(&self.inner, stream)
428     }
429 }
430 
431 #[cfg(feature = "kv_unstable_sval")]
432 impl ToValue for dyn self::sval::value::Value {
to_value(&self) -> Value433     fn to_value(&self) -> Value {
434         Value::from_dyn_sval(self)
435     }
436 }
437 
438 impl ToValue for str {
to_value(&self) -> Value439     fn to_value(&self) -> Value {
440         Value::from(self)
441     }
442 }
443 
444 impl ToValue for u128 {
to_value(&self) -> Value445     fn to_value(&self) -> Value {
446         Value::from(self)
447     }
448 }
449 
450 impl ToValue for i128 {
to_value(&self) -> Value451     fn to_value(&self) -> Value {
452         Value::from(self)
453     }
454 }
455 
456 impl ToValue for std::num::NonZeroU128 {
to_value(&self) -> Value457     fn to_value(&self) -> Value {
458         Value::from(self)
459     }
460 }
461 
462 impl ToValue for std::num::NonZeroI128 {
to_value(&self) -> Value463     fn to_value(&self) -> Value {
464         Value::from(self)
465     }
466 }
467 
468 impl<'v> From<&'v str> for Value<'v> {
from(value: &'v str) -> Self469     fn from(value: &'v str) -> Self {
470         Value::from_value_bag(value)
471     }
472 }
473 
474 impl<'v> From<&'v u128> for Value<'v> {
from(value: &'v u128) -> Self475     fn from(value: &'v u128) -> Self {
476         Value::from_value_bag(value)
477     }
478 }
479 
480 impl<'v> From<&'v i128> for Value<'v> {
from(value: &'v i128) -> Self481     fn from(value: &'v i128) -> Self {
482         Value::from_value_bag(value)
483     }
484 }
485 
486 impl<'v> From<&'v std::num::NonZeroU128> for Value<'v> {
from(v: &'v std::num::NonZeroU128) -> Value<'v>487     fn from(v: &'v std::num::NonZeroU128) -> Value<'v> {
488         // SAFETY: `NonZeroU128` and `u128` have the same ABI
489         Value::from_value_bag(unsafe { std::mem::transmute::<&std::num::NonZeroU128, &u128>(v) })
490     }
491 }
492 
493 impl<'v> From<&'v std::num::NonZeroI128> for Value<'v> {
from(v: &'v std::num::NonZeroI128) -> Value<'v>494     fn from(v: &'v std::num::NonZeroI128) -> Value<'v> {
495         // SAFETY: `NonZeroI128` and `i128` have the same ABI
496         Value::from_value_bag(unsafe { std::mem::transmute::<&std::num::NonZeroI128, &i128>(v) })
497     }
498 }
499 
500 impl ToValue for () {
to_value(&self) -> Value501     fn to_value(&self) -> Value {
502         Value::from_value_bag(())
503     }
504 }
505 
506 impl<T> ToValue for Option<T>
507 where
508     T: ToValue,
509 {
to_value(&self) -> Value510     fn to_value(&self) -> Value {
511         match *self {
512             Some(ref value) => value.to_value(),
513             None => Value::from_value_bag(()),
514         }
515     }
516 }
517 
518 macro_rules! impl_to_value_primitive {
519     ($($into_ty:ty,)*) => {
520         $(
521             impl ToValue for $into_ty {
522                 fn to_value(&self) -> Value {
523                     Value::from(*self)
524                 }
525             }
526 
527             impl<'v> From<$into_ty> for Value<'v> {
528                 fn from(value: $into_ty) -> Self {
529                     Value::from_value_bag(value)
530                 }
531             }
532         )*
533     };
534 }
535 
536 macro_rules! impl_to_value_nonzero_primitive {
537     ($($into_ty:ident,)*) => {
538         $(
539             impl ToValue for std::num::$into_ty {
540                 fn to_value(&self) -> Value {
541                     Value::from(self.get())
542                 }
543             }
544 
545             impl<'v> From<std::num::$into_ty> for Value<'v> {
546                 fn from(value: std::num::$into_ty) -> Self {
547                     Value::from(value.get())
548                 }
549             }
550         )*
551     };
552 }
553 
554 macro_rules! impl_value_to_primitive {
555     ($(#[doc = $doc:tt] $into_name:ident -> $into_ty:ty,)*) => {
556         impl<'v> Value<'v> {
557             $(
558                 #[doc = $doc]
559                 pub fn $into_name(&self) -> Option<$into_ty> {
560                     self.inner.$into_name()
561                 }
562             )*
563         }
564     }
565 }
566 
567 impl_to_value_primitive![usize, u8, u16, u32, u64, isize, i8, i16, i32, i64, f32, f64, char, bool,];
568 
569 #[rustfmt::skip]
570 impl_to_value_nonzero_primitive![
571     NonZeroUsize, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64,
572     NonZeroIsize, NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64,
573 ];
574 
575 impl_value_to_primitive![
576     #[doc = "Try convert this value into a `u64`."]
577     to_u64 -> u64,
578     #[doc = "Try convert this value into a `i64`."]
579     to_i64 -> i64,
580     #[doc = "Try convert this value into a `u128`."]
581     to_u128 -> u128,
582     #[doc = "Try convert this value into a `i128`."]
583     to_i128 -> i128,
584     #[doc = "Try convert this value into a `f64`."]
585     to_f64 -> f64,
586     #[doc = "Try convert this value into a `char`."]
587     to_char -> char,
588     #[doc = "Try convert this value into a `bool`."]
589     to_bool -> bool,
590 ];
591 
592 impl<'v> Value<'v> {
593     /// Try convert this value into an error.
594     #[cfg(feature = "kv_unstable_std")]
to_borrowed_error(&self) -> Option<&(dyn std::error::Error + 'static)>595     pub fn to_borrowed_error(&self) -> Option<&(dyn std::error::Error + 'static)> {
596         self.inner.to_borrowed_error()
597     }
598 
599     /// Try convert this value into a borrowed string.
to_borrowed_str(&self) -> Option<&str>600     pub fn to_borrowed_str(&self) -> Option<&str> {
601         self.inner.to_borrowed_str()
602     }
603 }
604 
605 #[cfg(feature = "kv_unstable_std")]
606 mod std_support {
607     use super::*;
608 
609     use std::borrow::Cow;
610 
611     impl<T> ToValue for Box<T>
612     where
613         T: ToValue + ?Sized,
614     {
to_value(&self) -> Value615         fn to_value(&self) -> Value {
616             (**self).to_value()
617         }
618     }
619 
620     impl ToValue for String {
to_value(&self) -> Value621         fn to_value(&self) -> Value {
622             Value::from(&**self)
623         }
624     }
625 
626     impl<'v> ToValue for Cow<'v, str> {
to_value(&self) -> Value627         fn to_value(&self) -> Value {
628             Value::from(&**self)
629         }
630     }
631 
632     impl<'v> Value<'v> {
633         /// Try convert this value into a string.
to_str(&self) -> Option<Cow<str>>634         pub fn to_str(&self) -> Option<Cow<str>> {
635             self.inner.to_str()
636         }
637     }
638 
639     impl<'v> From<&'v String> for Value<'v> {
from(v: &'v String) -> Self640         fn from(v: &'v String) -> Self {
641             Value::from(&**v)
642         }
643     }
644 }
645 
646 /// A visitor for a `Value`.
647 pub trait Visit<'v> {
648     /// Visit a `Value`.
649     ///
650     /// This is the only required method on `Visit` and acts as a fallback for any
651     /// more specific methods that aren't overridden.
652     /// The `Value` may be formatted using its `fmt::Debug` or `fmt::Display` implementation,
653     /// or serialized using its `sval::Value` or `serde::Serialize` implementation.
visit_any(&mut self, value: Value) -> Result<(), Error>654     fn visit_any(&mut self, value: Value) -> Result<(), Error>;
655 
656     /// Visit an unsigned integer.
visit_u64(&mut self, value: u64) -> Result<(), Error>657     fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
658         self.visit_any(value.into())
659     }
660 
661     /// Visit a signed integer.
visit_i64(&mut self, value: i64) -> Result<(), Error>662     fn visit_i64(&mut self, value: i64) -> Result<(), Error> {
663         self.visit_any(value.into())
664     }
665 
666     /// Visit a big unsigned integer.
visit_u128(&mut self, value: u128) -> Result<(), Error>667     fn visit_u128(&mut self, value: u128) -> Result<(), Error> {
668         self.visit_any((&value).into())
669     }
670 
671     /// Visit a big signed integer.
visit_i128(&mut self, value: i128) -> Result<(), Error>672     fn visit_i128(&mut self, value: i128) -> Result<(), Error> {
673         self.visit_any((&value).into())
674     }
675 
676     /// Visit a floating point.
visit_f64(&mut self, value: f64) -> Result<(), Error>677     fn visit_f64(&mut self, value: f64) -> Result<(), Error> {
678         self.visit_any(value.into())
679     }
680 
681     /// Visit a boolean.
visit_bool(&mut self, value: bool) -> Result<(), Error>682     fn visit_bool(&mut self, value: bool) -> Result<(), Error> {
683         self.visit_any(value.into())
684     }
685 
686     /// Visit a string.
visit_str(&mut self, value: &str) -> Result<(), Error>687     fn visit_str(&mut self, value: &str) -> Result<(), Error> {
688         self.visit_any(value.into())
689     }
690 
691     /// Visit a string.
visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error>692     fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
693         self.visit_str(value)
694     }
695 
696     /// Visit a Unicode character.
visit_char(&mut self, value: char) -> Result<(), Error>697     fn visit_char(&mut self, value: char) -> Result<(), Error> {
698         let mut b = [0; 4];
699         self.visit_str(&*value.encode_utf8(&mut b))
700     }
701 
702     /// Visit an error.
703     #[cfg(feature = "kv_unstable_std")]
visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error>704     fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> {
705         self.visit_any(Value::from_dyn_error(err))
706     }
707 
708     /// Visit an error.
709     #[cfg(feature = "kv_unstable_std")]
visit_borrowed_error( &mut self, err: &'v (dyn std::error::Error + 'static), ) -> Result<(), Error>710     fn visit_borrowed_error(
711         &mut self,
712         err: &'v (dyn std::error::Error + 'static),
713     ) -> Result<(), Error> {
714         self.visit_any(Value::from_dyn_error(err))
715     }
716 }
717 
718 impl<'a, 'v, T: ?Sized> Visit<'v> for &'a mut T
719 where
720     T: Visit<'v>,
721 {
visit_any(&mut self, value: Value) -> Result<(), Error>722     fn visit_any(&mut self, value: Value) -> Result<(), Error> {
723         (**self).visit_any(value)
724     }
725 
visit_u64(&mut self, value: u64) -> Result<(), Error>726     fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
727         (**self).visit_u64(value)
728     }
729 
visit_i64(&mut self, value: i64) -> Result<(), Error>730     fn visit_i64(&mut self, value: i64) -> Result<(), Error> {
731         (**self).visit_i64(value)
732     }
733 
visit_u128(&mut self, value: u128) -> Result<(), Error>734     fn visit_u128(&mut self, value: u128) -> Result<(), Error> {
735         (**self).visit_u128(value)
736     }
737 
visit_i128(&mut self, value: i128) -> Result<(), Error>738     fn visit_i128(&mut self, value: i128) -> Result<(), Error> {
739         (**self).visit_i128(value)
740     }
741 
visit_f64(&mut self, value: f64) -> Result<(), Error>742     fn visit_f64(&mut self, value: f64) -> Result<(), Error> {
743         (**self).visit_f64(value)
744     }
745 
visit_bool(&mut self, value: bool) -> Result<(), Error>746     fn visit_bool(&mut self, value: bool) -> Result<(), Error> {
747         (**self).visit_bool(value)
748     }
749 
visit_str(&mut self, value: &str) -> Result<(), Error>750     fn visit_str(&mut self, value: &str) -> Result<(), Error> {
751         (**self).visit_str(value)
752     }
753 
visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error>754     fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
755         (**self).visit_borrowed_str(value)
756     }
757 
visit_char(&mut self, value: char) -> Result<(), Error>758     fn visit_char(&mut self, value: char) -> Result<(), Error> {
759         (**self).visit_char(value)
760     }
761 
762     #[cfg(feature = "kv_unstable_std")]
visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error>763     fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> {
764         (**self).visit_error(err)
765     }
766 
767     #[cfg(feature = "kv_unstable_std")]
visit_borrowed_error( &mut self, err: &'v (dyn std::error::Error + 'static), ) -> Result<(), Error>768     fn visit_borrowed_error(
769         &mut self,
770         err: &'v (dyn std::error::Error + 'static),
771     ) -> Result<(), Error> {
772         (**self).visit_borrowed_error(err)
773     }
774 }
775 
776 #[cfg(test)]
777 pub(crate) mod tests {
778     use super::*;
779 
780     pub(crate) use super::value_bag::test::Token;
781 
782     impl<'v> Value<'v> {
to_token(&self) -> Token783         pub(crate) fn to_token(&self) -> Token {
784             self.inner.to_token()
785         }
786     }
787 
unsigned() -> impl Iterator<Item = Value<'static>>788     fn unsigned() -> impl Iterator<Item = Value<'static>> {
789         vec![
790             Value::from(8u8),
791             Value::from(16u16),
792             Value::from(32u32),
793             Value::from(64u64),
794             Value::from(1usize),
795             Value::from(std::num::NonZeroU8::new(8).unwrap()),
796             Value::from(std::num::NonZeroU16::new(16).unwrap()),
797             Value::from(std::num::NonZeroU32::new(32).unwrap()),
798             Value::from(std::num::NonZeroU64::new(64).unwrap()),
799             Value::from(std::num::NonZeroUsize::new(1).unwrap()),
800         ]
801         .into_iter()
802     }
803 
signed() -> impl Iterator<Item = Value<'static>>804     fn signed() -> impl Iterator<Item = Value<'static>> {
805         vec![
806             Value::from(-8i8),
807             Value::from(-16i16),
808             Value::from(-32i32),
809             Value::from(-64i64),
810             Value::from(-1isize),
811             Value::from(std::num::NonZeroI8::new(-8).unwrap()),
812             Value::from(std::num::NonZeroI16::new(-16).unwrap()),
813             Value::from(std::num::NonZeroI32::new(-32).unwrap()),
814             Value::from(std::num::NonZeroI64::new(-64).unwrap()),
815             Value::from(std::num::NonZeroIsize::new(-1).unwrap()),
816         ]
817         .into_iter()
818     }
819 
float() -> impl Iterator<Item = Value<'static>>820     fn float() -> impl Iterator<Item = Value<'static>> {
821         vec![Value::from(32.32f32), Value::from(64.64f64)].into_iter()
822     }
823 
bool() -> impl Iterator<Item = Value<'static>>824     fn bool() -> impl Iterator<Item = Value<'static>> {
825         vec![Value::from(true), Value::from(false)].into_iter()
826     }
827 
str() -> impl Iterator<Item = Value<'static>>828     fn str() -> impl Iterator<Item = Value<'static>> {
829         vec![Value::from("a string"), Value::from("a loong string")].into_iter()
830     }
831 
char() -> impl Iterator<Item = Value<'static>>832     fn char() -> impl Iterator<Item = Value<'static>> {
833         vec![Value::from('a'), Value::from('⛰')].into_iter()
834     }
835 
836     #[test]
test_capture_fmt()837     fn test_capture_fmt() {
838         assert_eq!(Some(42u64), Value::capture_display(&42).to_u64());
839         assert_eq!(Some(42u64), Value::capture_debug(&42).to_u64());
840 
841         assert!(Value::from_display(&42).to_u64().is_none());
842         assert!(Value::from_debug(&42).to_u64().is_none());
843     }
844 
845     #[cfg(feature = "kv_unstable_std")]
846     #[test]
test_capture_error()847     fn test_capture_error() {
848         let err = std::io::Error::from(std::io::ErrorKind::Other);
849 
850         assert!(Value::capture_error(&err).to_borrowed_error().is_some());
851         assert!(Value::from_dyn_error(&err).to_borrowed_error().is_some());
852     }
853 
854     #[cfg(feature = "kv_unstable_serde")]
855     #[test]
test_capture_serde()856     fn test_capture_serde() {
857         assert_eq!(Some(42u64), Value::capture_serde(&42).to_u64());
858 
859         assert_eq!(Some(42u64), Value::from_serde(&42).to_u64());
860     }
861 
862     #[cfg(feature = "kv_unstable_sval")]
863     #[test]
test_capture_sval()864     fn test_capture_sval() {
865         assert_eq!(Some(42u64), Value::capture_sval(&42).to_u64());
866 
867         assert_eq!(Some(42u64), Value::from_sval(&42).to_u64());
868     }
869 
870     #[test]
test_to_value_display()871     fn test_to_value_display() {
872         assert_eq!(42u64.to_value().to_string(), "42");
873         assert_eq!(42i64.to_value().to_string(), "42");
874         assert_eq!(42.01f64.to_value().to_string(), "42.01");
875         assert_eq!(true.to_value().to_string(), "true");
876         assert_eq!('a'.to_value().to_string(), "a");
877         assert_eq!("a loong string".to_value().to_string(), "a loong string");
878         assert_eq!(Some(true).to_value().to_string(), "true");
879         assert_eq!(().to_value().to_string(), "None");
880         assert_eq!(Option::None::<bool>.to_value().to_string(), "None");
881     }
882 
883     #[test]
test_to_value_structured()884     fn test_to_value_structured() {
885         assert_eq!(42u64.to_value().to_token(), Token::U64(42));
886         assert_eq!(42i64.to_value().to_token(), Token::I64(42));
887         assert_eq!(42.01f64.to_value().to_token(), Token::F64(42.01));
888         assert_eq!(true.to_value().to_token(), Token::Bool(true));
889         assert_eq!('a'.to_value().to_token(), Token::Char('a'));
890         assert_eq!(
891             "a loong string".to_value().to_token(),
892             Token::Str("a loong string".into())
893         );
894         assert_eq!(Some(true).to_value().to_token(), Token::Bool(true));
895         assert_eq!(().to_value().to_token(), Token::None);
896         assert_eq!(Option::None::<bool>.to_value().to_token(), Token::None);
897     }
898 
899     #[test]
test_to_number()900     fn test_to_number() {
901         for v in unsigned() {
902             assert!(v.to_u64().is_some());
903             assert!(v.to_i64().is_some());
904         }
905 
906         for v in signed() {
907             assert!(v.to_i64().is_some());
908         }
909 
910         for v in unsigned().chain(signed()).chain(float()) {
911             assert!(v.to_f64().is_some());
912         }
913 
914         for v in bool().chain(str()).chain(char()) {
915             assert!(v.to_u64().is_none());
916             assert!(v.to_i64().is_none());
917             assert!(v.to_f64().is_none());
918         }
919     }
920 
921     #[test]
test_to_str()922     fn test_to_str() {
923         for v in str() {
924             assert!(v.to_borrowed_str().is_some());
925 
926             #[cfg(feature = "kv_unstable_std")]
927             assert!(v.to_str().is_some());
928         }
929 
930         let short_lived = String::from("short lived");
931         let v = Value::from(&*short_lived);
932 
933         assert!(v.to_borrowed_str().is_some());
934 
935         #[cfg(feature = "kv_unstable_std")]
936         assert!(v.to_str().is_some());
937 
938         for v in unsigned().chain(signed()).chain(float()).chain(bool()) {
939             assert!(v.to_borrowed_str().is_none());
940 
941             #[cfg(feature = "kv_unstable_std")]
942             assert!(v.to_str().is_none());
943         }
944     }
945 
946     #[test]
test_to_bool()947     fn test_to_bool() {
948         for v in bool() {
949             assert!(v.to_bool().is_some());
950         }
951 
952         for v in unsigned()
953             .chain(signed())
954             .chain(float())
955             .chain(str())
956             .chain(char())
957         {
958             assert!(v.to_bool().is_none());
959         }
960     }
961 
962     #[test]
test_to_char()963     fn test_to_char() {
964         for v in char() {
965             assert!(v.to_char().is_some());
966         }
967 
968         for v in unsigned()
969             .chain(signed())
970             .chain(float())
971             .chain(str())
972             .chain(bool())
973         {
974             assert!(v.to_char().is_none());
975         }
976     }
977 
978     #[test]
test_downcast_ref()979     fn test_downcast_ref() {
980         #[derive(Debug)]
981         struct Foo(u64);
982 
983         let v = Value::capture_debug(&Foo(42));
984 
985         assert!(v.is::<Foo>());
986         assert_eq!(42u64, v.downcast_ref::<Foo>().expect("invalid downcast").0);
987     }
988 
989     #[test]
test_visit_integer()990     fn test_visit_integer() {
991         struct Extract(Option<u64>);
992 
993         impl<'v> Visit<'v> for Extract {
994             fn visit_any(&mut self, value: Value) -> Result<(), Error> {
995                 unimplemented!("unexpected value: {:?}", value)
996             }
997 
998             fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
999                 self.0 = Some(value);
1000 
1001                 Ok(())
1002             }
1003         }
1004 
1005         let mut extract = Extract(None);
1006         Value::from(42u64).visit(&mut extract).unwrap();
1007 
1008         assert_eq!(Some(42), extract.0);
1009     }
1010 
1011     #[test]
test_visit_borrowed_str()1012     fn test_visit_borrowed_str() {
1013         struct Extract<'v>(Option<&'v str>);
1014 
1015         impl<'v> Visit<'v> for Extract<'v> {
1016             fn visit_any(&mut self, value: Value) -> Result<(), Error> {
1017                 unimplemented!("unexpected value: {:?}", value)
1018             }
1019 
1020             fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
1021                 self.0 = Some(value);
1022 
1023                 Ok(())
1024             }
1025         }
1026 
1027         let mut extract = Extract(None);
1028 
1029         let short_lived = String::from("A short-lived string");
1030         Value::from(&*short_lived).visit(&mut extract).unwrap();
1031 
1032         assert_eq!(Some("A short-lived string"), extract.0);
1033     }
1034 }
1035