log/kv/
value.rs

1//! Structured values.
2//!
3//! This module defines the [`Value`] type and supporting APIs for
4//! capturing and serializing them.
5
6use std::fmt;
7
8pub use crate::kv::Error;
9
10/// A type that can be converted into a [`Value`](struct.Value.html).
11pub trait ToValue {
12    /// Perform the conversion.
13    fn to_value(&self) -> Value;
14}
15
16impl<'a, T> ToValue for &'a T
17where
18    T: ToValue + ?Sized,
19{
20    fn to_value(&self) -> Value {
21        (**self).to_value()
22    }
23}
24
25impl<'v> ToValue for Value<'v> {
26    fn to_value(&self) -> Value {
27        Value {
28            inner: self.inner.clone(),
29        }
30    }
31}
32
33/// A value in a key-value.
34///
35/// Values are an anonymous bag containing some structured datum.
36///
37/// # Capturing values
38///
39/// There are a few ways to capture a value:
40///
41/// - Using the `Value::from_*` methods.
42/// - Using the `ToValue` trait.
43/// - Using the standard `From` trait.
44///
45/// ## Using the `Value::from_*` methods
46///
47/// `Value` offers a few constructor methods that capture values of different kinds.
48///
49/// ```
50/// use log::kv::Value;
51///
52/// let value = Value::from_debug(&42i32);
53///
54/// assert_eq!(None, value.to_i64());
55/// ```
56///
57/// ## Using the `ToValue` trait
58///
59/// The `ToValue` trait can be used to capture values generically.
60/// It's the bound used by `Source`.
61///
62/// ```
63/// # use log::kv::ToValue;
64/// let value = 42i32.to_value();
65///
66/// assert_eq!(Some(42), value.to_i64());
67/// ```
68///
69/// ## Using the standard `From` trait
70///
71/// Standard types that implement `ToValue` also implement `From`.
72///
73/// ```
74/// use log::kv::Value;
75///
76/// let value = Value::from(42i32);
77///
78/// assert_eq!(Some(42), value.to_i64());
79/// ```
80///
81/// # Data model
82///
83/// Values can hold one of a number of types:
84///
85/// - **Null:** The absence of any other meaningful value. Note that
86///   `Some(Value::null())` is not the same as `None`. The former is
87///   `null` while the latter is `undefined`. This is important to be
88///   able to tell the difference between a key-value that was logged,
89///   but its value was empty (`Some(Value::null())`) and a key-value
90///   that was never logged at all (`None`).
91/// - **Strings:** `str`, `char`.
92/// - **Booleans:** `bool`.
93/// - **Integers:** `u8`-`u128`, `i8`-`i128`, `NonZero*`.
94/// - **Floating point numbers:** `f32`-`f64`.
95/// - **Errors:** `dyn (Error + 'static)`.
96/// - **`serde`:** Any type in `serde`'s data model.
97/// - **`sval`:** Any type in `sval`'s data model.
98///
99/// # Serialization
100///
101/// Values provide a number of ways to be serialized.
102///
103/// For basic types the [`Value::visit`] method can be used to extract the
104/// underlying typed value. However, this is limited in the amount of types
105/// supported (see the [`VisitValue`] trait methods).
106///
107/// For more complex types one of the following traits can be used:
108///  * `sval::Value`, requires the `kv_sval` feature.
109///  * `serde::Serialize`, requires the `kv_serde` feature.
110///
111/// You don't need a visitor to serialize values through `serde` or `sval`.
112///
113/// A value can always be serialized using any supported framework, regardless
114/// of how it was captured. If, for example, a value was captured using its
115/// `Display` implementation, it will serialize through `serde` as a string. If it was
116/// captured as a struct using `serde`, it will also serialize as a struct
117/// through `sval`, or can be formatted using a `Debug`-compatible representation.
118#[derive(Clone)]
119pub struct Value<'v> {
120    inner: inner::Inner<'v>,
121}
122
123impl<'v> Value<'v> {
124    /// Get a value from a type implementing `ToValue`.
125    pub fn from_any<T>(value: &'v T) -> Self
126    where
127        T: ToValue,
128    {
129        value.to_value()
130    }
131
132    /// Get a value from a type implementing `std::fmt::Debug`.
133    pub fn from_debug<T>(value: &'v T) -> Self
134    where
135        T: fmt::Debug,
136    {
137        Value {
138            inner: inner::Inner::from_debug(value),
139        }
140    }
141
142    /// Get a value from a type implementing `std::fmt::Display`.
143    pub fn from_display<T>(value: &'v T) -> Self
144    where
145        T: fmt::Display,
146    {
147        Value {
148            inner: inner::Inner::from_display(value),
149        }
150    }
151
152    /// Get a value from a type implementing `serde::Serialize`.
153    #[cfg(feature = "kv_serde")]
154    pub fn from_serde<T>(value: &'v T) -> Self
155    where
156        T: serde::Serialize,
157    {
158        Value {
159            inner: inner::Inner::from_serde1(value),
160        }
161    }
162
163    /// Get a value from a type implementing `sval::Value`.
164    #[cfg(feature = "kv_sval")]
165    pub fn from_sval<T>(value: &'v T) -> Self
166    where
167        T: sval::Value,
168    {
169        Value {
170            inner: inner::Inner::from_sval2(value),
171        }
172    }
173
174    /// Get a value from a dynamic `std::fmt::Debug`.
175    pub fn from_dyn_debug(value: &'v dyn fmt::Debug) -> Self {
176        Value {
177            inner: inner::Inner::from_dyn_debug(value),
178        }
179    }
180
181    /// Get a value from a dynamic `std::fmt::Display`.
182    pub fn from_dyn_display(value: &'v dyn fmt::Display) -> Self {
183        Value {
184            inner: inner::Inner::from_dyn_display(value),
185        }
186    }
187
188    /// Get a value from a dynamic error.
189    #[cfg(feature = "kv_std")]
190    pub fn from_dyn_error(err: &'v (dyn std::error::Error + 'static)) -> Self {
191        Value {
192            inner: inner::Inner::from_dyn_error(err),
193        }
194    }
195
196    /// Get a `null` value.
197    pub fn null() -> Self {
198        Value {
199            inner: inner::Inner::empty(),
200        }
201    }
202
203    /// Get a value from an internal primitive.
204    fn from_inner<T>(value: T) -> Self
205    where
206        T: Into<inner::Inner<'v>>,
207    {
208        Value {
209            inner: value.into(),
210        }
211    }
212
213    /// Inspect this value using a simple visitor.
214    ///
215    /// When the `kv_serde` or `kv_sval` features are enabled, you can also
216    /// serialize a value using its `Serialize` or `Value` implementation.
217    pub fn visit(&self, visitor: impl VisitValue<'v>) -> Result<(), Error> {
218        inner::visit(&self.inner, visitor)
219    }
220}
221
222impl<'v> fmt::Debug for Value<'v> {
223    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
224        fmt::Debug::fmt(&self.inner, f)
225    }
226}
227
228impl<'v> fmt::Display for Value<'v> {
229    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
230        fmt::Display::fmt(&self.inner, f)
231    }
232}
233
234#[cfg(feature = "kv_serde")]
235impl<'v> serde::Serialize for Value<'v> {
236    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
237    where
238        S: serde::Serializer,
239    {
240        self.inner.serialize(s)
241    }
242}
243
244#[cfg(feature = "kv_sval")]
245impl<'v> sval::Value for Value<'v> {
246    fn stream<'sval, S: sval::Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> sval::Result {
247        sval::Value::stream(&self.inner, stream)
248    }
249}
250
251#[cfg(feature = "kv_sval")]
252impl<'v> sval_ref::ValueRef<'v> for Value<'v> {
253    fn stream_ref<S: sval::Stream<'v> + ?Sized>(&self, stream: &mut S) -> sval::Result {
254        sval_ref::ValueRef::stream_ref(&self.inner, stream)
255    }
256}
257
258impl ToValue for str {
259    fn to_value(&self) -> Value {
260        Value::from(self)
261    }
262}
263
264impl<'v> From<&'v str> for Value<'v> {
265    fn from(value: &'v str) -> Self {
266        Value::from_inner(value)
267    }
268}
269
270impl ToValue for () {
271    fn to_value(&self) -> Value {
272        Value::from_inner(())
273    }
274}
275
276impl<T> ToValue for Option<T>
277where
278    T: ToValue,
279{
280    fn to_value(&self) -> Value {
281        match *self {
282            Some(ref value) => value.to_value(),
283            None => Value::from_inner(()),
284        }
285    }
286}
287
288macro_rules! impl_to_value_primitive {
289    ($($into_ty:ty,)*) => {
290        $(
291            impl ToValue for $into_ty {
292                fn to_value(&self) -> Value {
293                    Value::from(*self)
294                }
295            }
296
297            impl<'v> From<$into_ty> for Value<'v> {
298                fn from(value: $into_ty) -> Self {
299                    Value::from_inner(value)
300                }
301            }
302
303            impl<'v> From<&'v $into_ty> for Value<'v> {
304                fn from(value: &'v $into_ty) -> Self {
305                    Value::from_inner(*value)
306                }
307            }
308        )*
309    };
310}
311
312macro_rules! impl_to_value_nonzero_primitive {
313    ($($into_ty:ident,)*) => {
314        $(
315            impl ToValue for std::num::$into_ty {
316                fn to_value(&self) -> Value {
317                    Value::from(self.get())
318                }
319            }
320
321            impl<'v> From<std::num::$into_ty> for Value<'v> {
322                fn from(value: std::num::$into_ty) -> Self {
323                    Value::from(value.get())
324                }
325            }
326
327            impl<'v> From<&'v std::num::$into_ty> for Value<'v> {
328                fn from(value: &'v std::num::$into_ty) -> Self {
329                    Value::from(value.get())
330                }
331            }
332        )*
333    };
334}
335
336macro_rules! impl_value_to_primitive {
337    ($(#[doc = $doc:tt] $into_name:ident -> $into_ty:ty,)*) => {
338        impl<'v> Value<'v> {
339            $(
340                #[doc = $doc]
341                pub fn $into_name(&self) -> Option<$into_ty> {
342                    self.inner.$into_name()
343                }
344            )*
345        }
346    }
347}
348
349impl_to_value_primitive![
350    usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64, char, bool,
351];
352
353#[rustfmt::skip]
354impl_to_value_nonzero_primitive![
355    NonZeroUsize, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128,
356    NonZeroIsize, NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128,
357];
358
359impl_value_to_primitive![
360    #[doc = "Try convert this value into a `u64`."]
361    to_u64 -> u64,
362    #[doc = "Try convert this value into a `i64`."]
363    to_i64 -> i64,
364    #[doc = "Try convert this value into a `u128`."]
365    to_u128 -> u128,
366    #[doc = "Try convert this value into a `i128`."]
367    to_i128 -> i128,
368    #[doc = "Try convert this value into a `f64`."]
369    to_f64 -> f64,
370    #[doc = "Try convert this value into a `char`."]
371    to_char -> char,
372    #[doc = "Try convert this value into a `bool`."]
373    to_bool -> bool,
374];
375
376impl<'v> Value<'v> {
377    /// Try to convert this value into an error.
378    #[cfg(feature = "kv_std")]
379    pub fn to_borrowed_error(&self) -> Option<&(dyn std::error::Error + 'static)> {
380        self.inner.to_borrowed_error()
381    }
382
383    /// Try to convert this value into a borrowed string.
384    pub fn to_borrowed_str(&self) -> Option<&'v str> {
385        self.inner.to_borrowed_str()
386    }
387}
388
389#[cfg(feature = "kv_std")]
390mod std_support {
391    use std::borrow::Cow;
392    use std::rc::Rc;
393    use std::sync::Arc;
394
395    use super::*;
396
397    impl<T> ToValue for Box<T>
398    where
399        T: ToValue + ?Sized,
400    {
401        fn to_value(&self) -> Value {
402            (**self).to_value()
403        }
404    }
405
406    impl<T> ToValue for Arc<T>
407    where
408        T: ToValue + ?Sized,
409    {
410        fn to_value(&self) -> Value {
411            (**self).to_value()
412        }
413    }
414
415    impl<T> ToValue for Rc<T>
416    where
417        T: ToValue + ?Sized,
418    {
419        fn to_value(&self) -> Value {
420            (**self).to_value()
421        }
422    }
423
424    impl ToValue for String {
425        fn to_value(&self) -> Value {
426            Value::from(&**self)
427        }
428    }
429
430    impl<'v> ToValue for Cow<'v, str> {
431        fn to_value(&self) -> Value {
432            Value::from(&**self)
433        }
434    }
435
436    impl<'v> Value<'v> {
437        /// Try convert this value into a string.
438        pub fn to_cow_str(&self) -> Option<Cow<'v, str>> {
439            self.inner.to_str()
440        }
441    }
442
443    impl<'v> From<&'v String> for Value<'v> {
444        fn from(v: &'v String) -> Self {
445            Value::from(&**v)
446        }
447    }
448}
449
450/// A visitor for a [`Value`].
451///
452/// Also see [`Value`'s documentation on seralization]. Value visitors are a simple alternative
453/// to a more fully-featured serialization framework like `serde` or `sval`. A value visitor
454/// can differentiate primitive types through methods like [`VisitValue::visit_bool`] and
455/// [`VisitValue::visit_str`], but more complex types like maps and sequences
456/// will fallthrough to [`VisitValue::visit_any`].
457///
458/// If you're trying to serialize a value to a format like JSON, you can use either `serde`
459/// or `sval` directly with the value. You don't need a visitor.
460///
461/// [`Value`'s documentation on seralization]: Value#serialization
462pub trait VisitValue<'v> {
463    /// Visit a `Value`.
464    ///
465    /// This is the only required method on `VisitValue` and acts as a fallback for any
466    /// more specific methods that aren't overridden.
467    /// The `Value` may be formatted using its `fmt::Debug` or `fmt::Display` implementation,
468    /// or serialized using its `sval::Value` or `serde::Serialize` implementation.
469    fn visit_any(&mut self, value: Value) -> Result<(), Error>;
470
471    /// Visit an empty value.
472    fn visit_null(&mut self) -> Result<(), Error> {
473        self.visit_any(Value::null())
474    }
475
476    /// Visit an unsigned integer.
477    fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
478        self.visit_any(value.into())
479    }
480
481    /// Visit a signed integer.
482    fn visit_i64(&mut self, value: i64) -> Result<(), Error> {
483        self.visit_any(value.into())
484    }
485
486    /// Visit a big unsigned integer.
487    fn visit_u128(&mut self, value: u128) -> Result<(), Error> {
488        self.visit_any((value).into())
489    }
490
491    /// Visit a big signed integer.
492    fn visit_i128(&mut self, value: i128) -> Result<(), Error> {
493        self.visit_any((value).into())
494    }
495
496    /// Visit a floating point.
497    fn visit_f64(&mut self, value: f64) -> Result<(), Error> {
498        self.visit_any(value.into())
499    }
500
501    /// Visit a boolean.
502    fn visit_bool(&mut self, value: bool) -> Result<(), Error> {
503        self.visit_any(value.into())
504    }
505
506    /// Visit a string.
507    fn visit_str(&mut self, value: &str) -> Result<(), Error> {
508        self.visit_any(value.into())
509    }
510
511    /// Visit a string.
512    fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
513        self.visit_str(value)
514    }
515
516    /// Visit a Unicode character.
517    fn visit_char(&mut self, value: char) -> Result<(), Error> {
518        let mut b = [0; 4];
519        self.visit_str(&*value.encode_utf8(&mut b))
520    }
521
522    /// Visit an error.
523    #[cfg(feature = "kv_std")]
524    fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> {
525        self.visit_any(Value::from_dyn_error(err))
526    }
527
528    /// Visit an error.
529    #[cfg(feature = "kv_std")]
530    fn visit_borrowed_error(
531        &mut self,
532        err: &'v (dyn std::error::Error + 'static),
533    ) -> Result<(), Error> {
534        self.visit_any(Value::from_dyn_error(err))
535    }
536}
537
538impl<'a, 'v, T: ?Sized> VisitValue<'v> for &'a mut T
539where
540    T: VisitValue<'v>,
541{
542    fn visit_any(&mut self, value: Value) -> Result<(), Error> {
543        (**self).visit_any(value)
544    }
545
546    fn visit_null(&mut self) -> Result<(), Error> {
547        (**self).visit_null()
548    }
549
550    fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
551        (**self).visit_u64(value)
552    }
553
554    fn visit_i64(&mut self, value: i64) -> Result<(), Error> {
555        (**self).visit_i64(value)
556    }
557
558    fn visit_u128(&mut self, value: u128) -> Result<(), Error> {
559        (**self).visit_u128(value)
560    }
561
562    fn visit_i128(&mut self, value: i128) -> Result<(), Error> {
563        (**self).visit_i128(value)
564    }
565
566    fn visit_f64(&mut self, value: f64) -> Result<(), Error> {
567        (**self).visit_f64(value)
568    }
569
570    fn visit_bool(&mut self, value: bool) -> Result<(), Error> {
571        (**self).visit_bool(value)
572    }
573
574    fn visit_str(&mut self, value: &str) -> Result<(), Error> {
575        (**self).visit_str(value)
576    }
577
578    fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
579        (**self).visit_borrowed_str(value)
580    }
581
582    fn visit_char(&mut self, value: char) -> Result<(), Error> {
583        (**self).visit_char(value)
584    }
585
586    #[cfg(feature = "kv_std")]
587    fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> {
588        (**self).visit_error(err)
589    }
590
591    #[cfg(feature = "kv_std")]
592    fn visit_borrowed_error(
593        &mut self,
594        err: &'v (dyn std::error::Error + 'static),
595    ) -> Result<(), Error> {
596        (**self).visit_borrowed_error(err)
597    }
598}
599
600#[cfg(feature = "value-bag")]
601pub(in crate::kv) mod inner {
602    /**
603    An implementation of `Value` based on a library called `value_bag`.
604
605    `value_bag` was written specifically for use in `log`'s value, but was split out when it outgrew
606    the codebase here. It's a general-purpose type-erasure library that handles mapping between
607    more fully-featured serialization frameworks.
608    */
609    use super::*;
610
611    pub use value_bag::ValueBag as Inner;
612
613    pub use value_bag::Error;
614
615    #[cfg(test)]
616    pub use value_bag::test::TestToken as Token;
617
618    pub fn visit<'v>(
619        inner: &Inner<'v>,
620        visitor: impl VisitValue<'v>,
621    ) -> Result<(), crate::kv::Error> {
622        struct InnerVisitValue<V>(V);
623
624        impl<'v, V> value_bag::visit::Visit<'v> for InnerVisitValue<V>
625        where
626            V: VisitValue<'v>,
627        {
628            fn visit_any(&mut self, value: value_bag::ValueBag) -> Result<(), Error> {
629                self.0
630                    .visit_any(Value { inner: value })
631                    .map_err(crate::kv::Error::into_value)
632            }
633
634            fn visit_empty(&mut self) -> Result<(), Error> {
635                self.0.visit_null().map_err(crate::kv::Error::into_value)
636            }
637
638            fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
639                self.0
640                    .visit_u64(value)
641                    .map_err(crate::kv::Error::into_value)
642            }
643
644            fn visit_i64(&mut self, value: i64) -> Result<(), Error> {
645                self.0
646                    .visit_i64(value)
647                    .map_err(crate::kv::Error::into_value)
648            }
649
650            fn visit_u128(&mut self, value: u128) -> Result<(), Error> {
651                self.0
652                    .visit_u128(value)
653                    .map_err(crate::kv::Error::into_value)
654            }
655
656            fn visit_i128(&mut self, value: i128) -> Result<(), Error> {
657                self.0
658                    .visit_i128(value)
659                    .map_err(crate::kv::Error::into_value)
660            }
661
662            fn visit_f64(&mut self, value: f64) -> Result<(), Error> {
663                self.0
664                    .visit_f64(value)
665                    .map_err(crate::kv::Error::into_value)
666            }
667
668            fn visit_bool(&mut self, value: bool) -> Result<(), Error> {
669                self.0
670                    .visit_bool(value)
671                    .map_err(crate::kv::Error::into_value)
672            }
673
674            fn visit_str(&mut self, value: &str) -> Result<(), Error> {
675                self.0
676                    .visit_str(value)
677                    .map_err(crate::kv::Error::into_value)
678            }
679
680            fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
681                self.0
682                    .visit_borrowed_str(value)
683                    .map_err(crate::kv::Error::into_value)
684            }
685
686            fn visit_char(&mut self, value: char) -> Result<(), Error> {
687                self.0
688                    .visit_char(value)
689                    .map_err(crate::kv::Error::into_value)
690            }
691
692            #[cfg(feature = "kv_std")]
693            fn visit_error(
694                &mut self,
695                err: &(dyn std::error::Error + 'static),
696            ) -> Result<(), Error> {
697                self.0
698                    .visit_error(err)
699                    .map_err(crate::kv::Error::into_value)
700            }
701
702            #[cfg(feature = "kv_std")]
703            fn visit_borrowed_error(
704                &mut self,
705                err: &'v (dyn std::error::Error + 'static),
706            ) -> Result<(), Error> {
707                self.0
708                    .visit_borrowed_error(err)
709                    .map_err(crate::kv::Error::into_value)
710            }
711        }
712
713        inner
714            .visit(&mut InnerVisitValue(visitor))
715            .map_err(crate::kv::Error::from_value)
716    }
717}
718
719#[cfg(not(feature = "value-bag"))]
720pub(in crate::kv) mod inner {
721    /**
722    This is a dependency-free implementation of `Value` when there's no serialization frameworks involved.
723    In these simple cases a more fully featured solution like `value_bag` isn't needed, so we avoid pulling it in.
724
725    There are a few things here that need to remain consistent with the `value_bag`-based implementation:
726
727    1. Conversions should always produce the same results. If a conversion here returns `Some`, then
728       the same `value_bag`-based conversion must also. Of particular note here are floats to ints; they're
729       based on the standard library's `TryInto` conversions, which need to be converted to `i32` or `u32`,
730       and then to `f64`.
731    2. VisitValues should always be called in the same way. If a particular type of value calls `visit_i64`,
732       then the same `value_bag`-based visitor must also.
733    */
734    use super::*;
735
736    #[derive(Clone)]
737    pub enum Inner<'v> {
738        None,
739        Bool(bool),
740        Str(&'v str),
741        Char(char),
742        I64(i64),
743        U64(u64),
744        F64(f64),
745        I128(i128),
746        U128(u128),
747        Debug(&'v dyn fmt::Debug),
748        Display(&'v dyn fmt::Display),
749    }
750
751    impl<'v> From<()> for Inner<'v> {
752        fn from(_: ()) -> Self {
753            Inner::None
754        }
755    }
756
757    impl<'v> From<bool> for Inner<'v> {
758        fn from(v: bool) -> Self {
759            Inner::Bool(v)
760        }
761    }
762
763    impl<'v> From<char> for Inner<'v> {
764        fn from(v: char) -> Self {
765            Inner::Char(v)
766        }
767    }
768
769    impl<'v> From<f32> for Inner<'v> {
770        fn from(v: f32) -> Self {
771            Inner::F64(v as f64)
772        }
773    }
774
775    impl<'v> From<f64> for Inner<'v> {
776        fn from(v: f64) -> Self {
777            Inner::F64(v)
778        }
779    }
780
781    impl<'v> From<i8> for Inner<'v> {
782        fn from(v: i8) -> Self {
783            Inner::I64(v as i64)
784        }
785    }
786
787    impl<'v> From<i16> for Inner<'v> {
788        fn from(v: i16) -> Self {
789            Inner::I64(v as i64)
790        }
791    }
792
793    impl<'v> From<i32> for Inner<'v> {
794        fn from(v: i32) -> Self {
795            Inner::I64(v as i64)
796        }
797    }
798
799    impl<'v> From<i64> for Inner<'v> {
800        fn from(v: i64) -> Self {
801            Inner::I64(v as i64)
802        }
803    }
804
805    impl<'v> From<isize> for Inner<'v> {
806        fn from(v: isize) -> Self {
807            Inner::I64(v as i64)
808        }
809    }
810
811    impl<'v> From<u8> for Inner<'v> {
812        fn from(v: u8) -> Self {
813            Inner::U64(v as u64)
814        }
815    }
816
817    impl<'v> From<u16> for Inner<'v> {
818        fn from(v: u16) -> Self {
819            Inner::U64(v as u64)
820        }
821    }
822
823    impl<'v> From<u32> for Inner<'v> {
824        fn from(v: u32) -> Self {
825            Inner::U64(v as u64)
826        }
827    }
828
829    impl<'v> From<u64> for Inner<'v> {
830        fn from(v: u64) -> Self {
831            Inner::U64(v as u64)
832        }
833    }
834
835    impl<'v> From<usize> for Inner<'v> {
836        fn from(v: usize) -> Self {
837            Inner::U64(v as u64)
838        }
839    }
840
841    impl<'v> From<i128> for Inner<'v> {
842        fn from(v: i128) -> Self {
843            Inner::I128(v)
844        }
845    }
846
847    impl<'v> From<u128> for Inner<'v> {
848        fn from(v: u128) -> Self {
849            Inner::U128(v)
850        }
851    }
852
853    impl<'v> From<&'v str> for Inner<'v> {
854        fn from(v: &'v str) -> Self {
855            Inner::Str(v)
856        }
857    }
858
859    impl<'v> fmt::Debug for Inner<'v> {
860        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
861            match self {
862                Inner::None => fmt::Debug::fmt(&None::<()>, f),
863                Inner::Bool(v) => fmt::Debug::fmt(v, f),
864                Inner::Str(v) => fmt::Debug::fmt(v, f),
865                Inner::Char(v) => fmt::Debug::fmt(v, f),
866                Inner::I64(v) => fmt::Debug::fmt(v, f),
867                Inner::U64(v) => fmt::Debug::fmt(v, f),
868                Inner::F64(v) => fmt::Debug::fmt(v, f),
869                Inner::I128(v) => fmt::Debug::fmt(v, f),
870                Inner::U128(v) => fmt::Debug::fmt(v, f),
871                Inner::Debug(v) => fmt::Debug::fmt(v, f),
872                Inner::Display(v) => fmt::Display::fmt(v, f),
873            }
874        }
875    }
876
877    impl<'v> fmt::Display for Inner<'v> {
878        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
879            match self {
880                Inner::None => fmt::Debug::fmt(&None::<()>, f),
881                Inner::Bool(v) => fmt::Display::fmt(v, f),
882                Inner::Str(v) => fmt::Display::fmt(v, f),
883                Inner::Char(v) => fmt::Display::fmt(v, f),
884                Inner::I64(v) => fmt::Display::fmt(v, f),
885                Inner::U64(v) => fmt::Display::fmt(v, f),
886                Inner::F64(v) => fmt::Display::fmt(v, f),
887                Inner::I128(v) => fmt::Display::fmt(v, f),
888                Inner::U128(v) => fmt::Display::fmt(v, f),
889                Inner::Debug(v) => fmt::Debug::fmt(v, f),
890                Inner::Display(v) => fmt::Display::fmt(v, f),
891            }
892        }
893    }
894
895    impl<'v> Inner<'v> {
896        pub fn from_debug<T: fmt::Debug>(value: &'v T) -> Self {
897            Inner::Debug(value)
898        }
899
900        pub fn from_display<T: fmt::Display>(value: &'v T) -> Self {
901            Inner::Display(value)
902        }
903
904        pub fn from_dyn_debug(value: &'v dyn fmt::Debug) -> Self {
905            Inner::Debug(value)
906        }
907
908        pub fn from_dyn_display(value: &'v dyn fmt::Display) -> Self {
909            Inner::Display(value)
910        }
911
912        pub fn empty() -> Self {
913            Inner::None
914        }
915
916        pub fn to_bool(&self) -> Option<bool> {
917            match self {
918                Inner::Bool(v) => Some(*v),
919                _ => None,
920            }
921        }
922
923        pub fn to_char(&self) -> Option<char> {
924            match self {
925                Inner::Char(v) => Some(*v),
926                _ => None,
927            }
928        }
929
930        pub fn to_f64(&self) -> Option<f64> {
931            match self {
932                Inner::F64(v) => Some(*v),
933                Inner::I64(v) => {
934                    let v: i32 = (*v).try_into().ok()?;
935                    v.try_into().ok()
936                }
937                Inner::U64(v) => {
938                    let v: u32 = (*v).try_into().ok()?;
939                    v.try_into().ok()
940                }
941                Inner::I128(v) => {
942                    let v: i32 = (*v).try_into().ok()?;
943                    v.try_into().ok()
944                }
945                Inner::U128(v) => {
946                    let v: u32 = (*v).try_into().ok()?;
947                    v.try_into().ok()
948                }
949                _ => None,
950            }
951        }
952
953        pub fn to_i64(&self) -> Option<i64> {
954            match self {
955                Inner::I64(v) => Some(*v),
956                Inner::U64(v) => (*v).try_into().ok(),
957                Inner::I128(v) => (*v).try_into().ok(),
958                Inner::U128(v) => (*v).try_into().ok(),
959                _ => None,
960            }
961        }
962
963        pub fn to_u64(&self) -> Option<u64> {
964            match self {
965                Inner::U64(v) => Some(*v),
966                Inner::I64(v) => (*v).try_into().ok(),
967                Inner::I128(v) => (*v).try_into().ok(),
968                Inner::U128(v) => (*v).try_into().ok(),
969                _ => None,
970            }
971        }
972
973        pub fn to_u128(&self) -> Option<u128> {
974            match self {
975                Inner::U128(v) => Some(*v),
976                Inner::I64(v) => (*v).try_into().ok(),
977                Inner::U64(v) => (*v).try_into().ok(),
978                Inner::I128(v) => (*v).try_into().ok(),
979                _ => None,
980            }
981        }
982
983        pub fn to_i128(&self) -> Option<i128> {
984            match self {
985                Inner::I128(v) => Some(*v),
986                Inner::I64(v) => (*v).try_into().ok(),
987                Inner::U64(v) => (*v).try_into().ok(),
988                Inner::U128(v) => (*v).try_into().ok(),
989                _ => None,
990            }
991        }
992
993        pub fn to_borrowed_str(&self) -> Option<&'v str> {
994            match self {
995                Inner::Str(v) => Some(v),
996                _ => None,
997            }
998        }
999
1000        #[cfg(test)]
1001        pub fn to_test_token(&self) -> Token {
1002            match self {
1003                Inner::None => Token::None,
1004                Inner::Bool(v) => Token::Bool(*v),
1005                Inner::Str(v) => Token::Str(*v),
1006                Inner::Char(v) => Token::Char(*v),
1007                Inner::I64(v) => Token::I64(*v),
1008                Inner::U64(v) => Token::U64(*v),
1009                Inner::F64(v) => Token::F64(*v),
1010                Inner::I128(_) => unimplemented!(),
1011                Inner::U128(_) => unimplemented!(),
1012                Inner::Debug(_) => unimplemented!(),
1013                Inner::Display(_) => unimplemented!(),
1014            }
1015        }
1016    }
1017
1018    #[cfg(test)]
1019    #[derive(Debug, PartialEq)]
1020    pub enum Token<'v> {
1021        None,
1022        Bool(bool),
1023        Char(char),
1024        Str(&'v str),
1025        F64(f64),
1026        I64(i64),
1027        U64(u64),
1028    }
1029
1030    pub fn visit<'v>(
1031        inner: &Inner<'v>,
1032        mut visitor: impl VisitValue<'v>,
1033    ) -> Result<(), crate::kv::Error> {
1034        match inner {
1035            Inner::None => visitor.visit_null(),
1036            Inner::Bool(v) => visitor.visit_bool(*v),
1037            Inner::Str(v) => visitor.visit_borrowed_str(*v),
1038            Inner::Char(v) => visitor.visit_char(*v),
1039            Inner::I64(v) => visitor.visit_i64(*v),
1040            Inner::U64(v) => visitor.visit_u64(*v),
1041            Inner::F64(v) => visitor.visit_f64(*v),
1042            Inner::I128(v) => visitor.visit_i128(*v),
1043            Inner::U128(v) => visitor.visit_u128(*v),
1044            Inner::Debug(v) => visitor.visit_any(Value::from_dyn_debug(*v)),
1045            Inner::Display(v) => visitor.visit_any(Value::from_dyn_display(*v)),
1046        }
1047    }
1048}
1049
1050impl<'v> Value<'v> {
1051    /// Get a value from a type implementing `std::fmt::Debug`.
1052    #[cfg(feature = "kv_unstable")]
1053    #[deprecated(note = "use `from_debug` instead")]
1054    pub fn capture_debug<T>(value: &'v T) -> Self
1055    where
1056        T: fmt::Debug + 'static,
1057    {
1058        Value::from_debug(value)
1059    }
1060
1061    /// Get a value from a type implementing `std::fmt::Display`.
1062    #[cfg(feature = "kv_unstable")]
1063    #[deprecated(note = "use `from_display` instead")]
1064    pub fn capture_display<T>(value: &'v T) -> Self
1065    where
1066        T: fmt::Display + 'static,
1067    {
1068        Value::from_display(value)
1069    }
1070
1071    /// Get a value from an error.
1072    #[cfg(feature = "kv_unstable_std")]
1073    #[deprecated(note = "use `from_dyn_error` instead")]
1074    pub fn capture_error<T>(err: &'v T) -> Self
1075    where
1076        T: std::error::Error + 'static,
1077    {
1078        Value::from_dyn_error(err)
1079    }
1080
1081    /// Get a value from a type implementing `serde::Serialize`.
1082    #[cfg(feature = "kv_unstable_serde")]
1083    #[deprecated(note = "use `from_serde` instead")]
1084    pub fn capture_serde<T>(value: &'v T) -> Self
1085    where
1086        T: serde::Serialize + 'static,
1087    {
1088        Value::from_serde(value)
1089    }
1090
1091    /// Get a value from a type implementing `sval::Value`.
1092    #[cfg(feature = "kv_unstable_sval")]
1093    #[deprecated(note = "use `from_sval` instead")]
1094    pub fn capture_sval<T>(value: &'v T) -> Self
1095    where
1096        T: sval::Value + 'static,
1097    {
1098        Value::from_sval(value)
1099    }
1100
1101    /// Check whether this value can be downcast to `T`.
1102    #[cfg(feature = "kv_unstable")]
1103    #[deprecated(
1104        note = "downcasting has been removed; log an issue at https://github.com/rust-lang/log/issues if this is something you rely on"
1105    )]
1106    pub fn is<T: 'static>(&self) -> bool {
1107        false
1108    }
1109
1110    /// Try downcast this value to `T`.
1111    #[cfg(feature = "kv_unstable")]
1112    #[deprecated(
1113        note = "downcasting has been removed; log an issue at https://github.com/rust-lang/log/issues if this is something you rely on"
1114    )]
1115    pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
1116        None
1117    }
1118}
1119
1120// NOTE: Deprecated; but aliases can't carry this attribute
1121#[cfg(feature = "kv_unstable")]
1122pub use VisitValue as Visit;
1123
1124/// Get a value from a type implementing `std::fmt::Debug`.
1125#[cfg(feature = "kv_unstable")]
1126#[deprecated(note = "use the `key:? = value` macro syntax instead")]
1127#[macro_export]
1128macro_rules! as_debug {
1129    ($capture:expr) => {
1130        $crate::kv::Value::from_debug(&$capture)
1131    };
1132}
1133
1134/// Get a value from a type implementing `std::fmt::Display`.
1135#[cfg(feature = "kv_unstable")]
1136#[deprecated(note = "use the `key:% = value` macro syntax instead")]
1137#[macro_export]
1138macro_rules! as_display {
1139    ($capture:expr) => {
1140        $crate::kv::Value::from_display(&$capture)
1141    };
1142}
1143
1144/// Get a value from an error.
1145#[cfg(feature = "kv_unstable_std")]
1146#[deprecated(note = "use the `key:err = value` macro syntax instead")]
1147#[macro_export]
1148macro_rules! as_error {
1149    ($capture:expr) => {
1150        $crate::kv::Value::from_dyn_error(&$capture)
1151    };
1152}
1153
1154#[cfg(feature = "kv_unstable_serde")]
1155#[deprecated(note = "use the `key:serde = value` macro syntax instead")]
1156/// Get a value from a type implementing `serde::Serialize`.
1157#[macro_export]
1158macro_rules! as_serde {
1159    ($capture:expr) => {
1160        $crate::kv::Value::from_serde(&$capture)
1161    };
1162}
1163
1164/// Get a value from a type implementing `sval::Value`.
1165#[cfg(feature = "kv_unstable_sval")]
1166#[deprecated(note = "use the `key:sval = value` macro syntax instead")]
1167#[macro_export]
1168macro_rules! as_sval {
1169    ($capture:expr) => {
1170        $crate::kv::Value::from_sval(&$capture)
1171    };
1172}
1173
1174#[cfg(test)]
1175pub(crate) mod tests {
1176    use super::*;
1177
1178    impl<'v> Value<'v> {
1179        pub(crate) fn to_token(&self) -> inner::Token {
1180            self.inner.to_test_token()
1181        }
1182    }
1183
1184    fn unsigned() -> impl Iterator<Item = Value<'static>> {
1185        vec![
1186            Value::from(8u8),
1187            Value::from(16u16),
1188            Value::from(32u32),
1189            Value::from(64u64),
1190            Value::from(1usize),
1191            Value::from(std::num::NonZeroU8::new(8).unwrap()),
1192            Value::from(std::num::NonZeroU16::new(16).unwrap()),
1193            Value::from(std::num::NonZeroU32::new(32).unwrap()),
1194            Value::from(std::num::NonZeroU64::new(64).unwrap()),
1195            Value::from(std::num::NonZeroUsize::new(1).unwrap()),
1196        ]
1197        .into_iter()
1198    }
1199
1200    fn signed() -> impl Iterator<Item = Value<'static>> {
1201        vec![
1202            Value::from(-8i8),
1203            Value::from(-16i16),
1204            Value::from(-32i32),
1205            Value::from(-64i64),
1206            Value::from(-1isize),
1207            Value::from(std::num::NonZeroI8::new(-8).unwrap()),
1208            Value::from(std::num::NonZeroI16::new(-16).unwrap()),
1209            Value::from(std::num::NonZeroI32::new(-32).unwrap()),
1210            Value::from(std::num::NonZeroI64::new(-64).unwrap()),
1211            Value::from(std::num::NonZeroIsize::new(-1).unwrap()),
1212        ]
1213        .into_iter()
1214    }
1215
1216    fn float() -> impl Iterator<Item = Value<'static>> {
1217        vec![Value::from(32.32f32), Value::from(64.64f64)].into_iter()
1218    }
1219
1220    fn bool() -> impl Iterator<Item = Value<'static>> {
1221        vec![Value::from(true), Value::from(false)].into_iter()
1222    }
1223
1224    fn str() -> impl Iterator<Item = Value<'static>> {
1225        vec![Value::from("a string"), Value::from("a loong string")].into_iter()
1226    }
1227
1228    fn char() -> impl Iterator<Item = Value<'static>> {
1229        vec![Value::from('a'), Value::from('⛰')].into_iter()
1230    }
1231
1232    #[test]
1233    fn test_to_value_display() {
1234        assert_eq!(42u64.to_value().to_string(), "42");
1235        assert_eq!(42i64.to_value().to_string(), "42");
1236        assert_eq!(42.01f64.to_value().to_string(), "42.01");
1237        assert_eq!(true.to_value().to_string(), "true");
1238        assert_eq!('a'.to_value().to_string(), "a");
1239        assert_eq!("a loong string".to_value().to_string(), "a loong string");
1240        assert_eq!(Some(true).to_value().to_string(), "true");
1241        assert_eq!(().to_value().to_string(), "None");
1242        assert_eq!(None::<bool>.to_value().to_string(), "None");
1243    }
1244
1245    #[test]
1246    fn test_to_value_structured() {
1247        assert_eq!(42u64.to_value().to_token(), inner::Token::U64(42));
1248        assert_eq!(42i64.to_value().to_token(), inner::Token::I64(42));
1249        assert_eq!(42.01f64.to_value().to_token(), inner::Token::F64(42.01));
1250        assert_eq!(true.to_value().to_token(), inner::Token::Bool(true));
1251        assert_eq!('a'.to_value().to_token(), inner::Token::Char('a'));
1252        assert_eq!(
1253            "a loong string".to_value().to_token(),
1254            inner::Token::Str("a loong string".into())
1255        );
1256        assert_eq!(Some(true).to_value().to_token(), inner::Token::Bool(true));
1257        assert_eq!(().to_value().to_token(), inner::Token::None);
1258        assert_eq!(None::<bool>.to_value().to_token(), inner::Token::None);
1259    }
1260
1261    #[test]
1262    fn test_to_number() {
1263        for v in unsigned() {
1264            assert!(v.to_u64().is_some());
1265            assert!(v.to_i64().is_some());
1266        }
1267
1268        for v in signed() {
1269            assert!(v.to_i64().is_some());
1270        }
1271
1272        for v in unsigned().chain(signed()).chain(float()) {
1273            assert!(v.to_f64().is_some());
1274        }
1275
1276        for v in bool().chain(str()).chain(char()) {
1277            assert!(v.to_u64().is_none());
1278            assert!(v.to_i64().is_none());
1279            assert!(v.to_f64().is_none());
1280        }
1281    }
1282
1283    #[test]
1284    fn test_to_float() {
1285        // Only integers from i32::MIN..=u32::MAX can be converted into floats
1286        assert!(Value::from(i32::MIN).to_f64().is_some());
1287        assert!(Value::from(u32::MAX).to_f64().is_some());
1288
1289        assert!(Value::from((i32::MIN as i64) - 1).to_f64().is_none());
1290        assert!(Value::from((u32::MAX as u64) + 1).to_f64().is_none());
1291    }
1292
1293    #[test]
1294    fn test_to_cow_str() {
1295        for v in str() {
1296            assert!(v.to_borrowed_str().is_some());
1297
1298            #[cfg(feature = "kv_std")]
1299            assert!(v.to_cow_str().is_some());
1300        }
1301
1302        let short_lived = String::from("short lived");
1303        let v = Value::from(&*short_lived);
1304
1305        assert!(v.to_borrowed_str().is_some());
1306
1307        #[cfg(feature = "kv_std")]
1308        assert!(v.to_cow_str().is_some());
1309
1310        for v in unsigned().chain(signed()).chain(float()).chain(bool()) {
1311            assert!(v.to_borrowed_str().is_none());
1312
1313            #[cfg(feature = "kv_std")]
1314            assert!(v.to_cow_str().is_none());
1315        }
1316    }
1317
1318    #[test]
1319    fn test_to_bool() {
1320        for v in bool() {
1321            assert!(v.to_bool().is_some());
1322        }
1323
1324        for v in unsigned()
1325            .chain(signed())
1326            .chain(float())
1327            .chain(str())
1328            .chain(char())
1329        {
1330            assert!(v.to_bool().is_none());
1331        }
1332    }
1333
1334    #[test]
1335    fn test_to_char() {
1336        for v in char() {
1337            assert!(v.to_char().is_some());
1338        }
1339
1340        for v in unsigned()
1341            .chain(signed())
1342            .chain(float())
1343            .chain(str())
1344            .chain(bool())
1345        {
1346            assert!(v.to_char().is_none());
1347        }
1348    }
1349
1350    #[test]
1351    fn test_visit_integer() {
1352        struct Extract(Option<u64>);
1353
1354        impl<'v> VisitValue<'v> for Extract {
1355            fn visit_any(&mut self, value: Value) -> Result<(), Error> {
1356                unimplemented!("unexpected value: {value:?}")
1357            }
1358
1359            fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
1360                self.0 = Some(value);
1361
1362                Ok(())
1363            }
1364        }
1365
1366        let mut extract = Extract(None);
1367        Value::from(42u64).visit(&mut extract).unwrap();
1368
1369        assert_eq!(Some(42), extract.0);
1370    }
1371
1372    #[test]
1373    fn test_visit_borrowed_str() {
1374        struct Extract<'v>(Option<&'v str>);
1375
1376        impl<'v> VisitValue<'v> for Extract<'v> {
1377            fn visit_any(&mut self, value: Value) -> Result<(), Error> {
1378                unimplemented!("unexpected value: {value:?}")
1379            }
1380
1381            fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
1382                self.0 = Some(value);
1383
1384                Ok(())
1385            }
1386        }
1387
1388        let mut extract = Extract(None);
1389
1390        let short_lived = String::from("A short-lived string");
1391        Value::from(&*short_lived).visit(&mut extract).unwrap();
1392
1393        assert_eq!(Some("A short-lived string"), extract.0);
1394    }
1395}