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<T> ToValue for &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_core::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_core::Serialize for Value<'v> {
236    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
237    where
238        S: serde_core::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 serialization]. 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 serialization]: 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
538#[allow(clippy::needless_lifetimes)] // Not needless.
539impl<'a, 'v, T: ?Sized> VisitValue<'v> for &'a mut T
540where
541    T: VisitValue<'v>,
542{
543    fn visit_any(&mut self, value: Value) -> Result<(), Error> {
544        (**self).visit_any(value)
545    }
546
547    fn visit_null(&mut self) -> Result<(), Error> {
548        (**self).visit_null()
549    }
550
551    fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
552        (**self).visit_u64(value)
553    }
554
555    fn visit_i64(&mut self, value: i64) -> Result<(), Error> {
556        (**self).visit_i64(value)
557    }
558
559    fn visit_u128(&mut self, value: u128) -> Result<(), Error> {
560        (**self).visit_u128(value)
561    }
562
563    fn visit_i128(&mut self, value: i128) -> Result<(), Error> {
564        (**self).visit_i128(value)
565    }
566
567    fn visit_f64(&mut self, value: f64) -> Result<(), Error> {
568        (**self).visit_f64(value)
569    }
570
571    fn visit_bool(&mut self, value: bool) -> Result<(), Error> {
572        (**self).visit_bool(value)
573    }
574
575    fn visit_str(&mut self, value: &str) -> Result<(), Error> {
576        (**self).visit_str(value)
577    }
578
579    fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
580        (**self).visit_borrowed_str(value)
581    }
582
583    fn visit_char(&mut self, value: char) -> Result<(), Error> {
584        (**self).visit_char(value)
585    }
586
587    #[cfg(feature = "kv_std")]
588    fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> {
589        (**self).visit_error(err)
590    }
591
592    #[cfg(feature = "kv_std")]
593    fn visit_borrowed_error(
594        &mut self,
595        err: &'v (dyn std::error::Error + 'static),
596    ) -> Result<(), Error> {
597        (**self).visit_borrowed_error(err)
598    }
599}
600
601#[cfg(feature = "value-bag")]
602pub(in crate::kv) mod inner {
603    /**
604    An implementation of `Value` based on a library called `value_bag`.
605
606    `value_bag` was written specifically for use in `log`'s value, but was split out when it outgrew
607    the codebase here. It's a general-purpose type-erasure library that handles mapping between
608    more fully-featured serialization frameworks.
609    */
610    use super::*;
611
612    pub use value_bag::ValueBag as Inner;
613
614    pub use value_bag::Error;
615
616    #[cfg(test)]
617    pub use value_bag::test::TestToken as Token;
618
619    pub fn visit<'v>(
620        inner: &Inner<'v>,
621        visitor: impl VisitValue<'v>,
622    ) -> Result<(), crate::kv::Error> {
623        struct InnerVisitValue<V>(V);
624
625        impl<'v, V> value_bag::visit::Visit<'v> for InnerVisitValue<V>
626        where
627            V: VisitValue<'v>,
628        {
629            fn visit_any(&mut self, value: value_bag::ValueBag) -> Result<(), Error> {
630                self.0
631                    .visit_any(Value { inner: value })
632                    .map_err(crate::kv::Error::into_value)
633            }
634
635            fn visit_empty(&mut self) -> Result<(), Error> {
636                self.0.visit_null().map_err(crate::kv::Error::into_value)
637            }
638
639            fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
640                self.0
641                    .visit_u64(value)
642                    .map_err(crate::kv::Error::into_value)
643            }
644
645            fn visit_i64(&mut self, value: i64) -> Result<(), Error> {
646                self.0
647                    .visit_i64(value)
648                    .map_err(crate::kv::Error::into_value)
649            }
650
651            fn visit_u128(&mut self, value: u128) -> Result<(), Error> {
652                self.0
653                    .visit_u128(value)
654                    .map_err(crate::kv::Error::into_value)
655            }
656
657            fn visit_i128(&mut self, value: i128) -> Result<(), Error> {
658                self.0
659                    .visit_i128(value)
660                    .map_err(crate::kv::Error::into_value)
661            }
662
663            fn visit_f64(&mut self, value: f64) -> Result<(), Error> {
664                self.0
665                    .visit_f64(value)
666                    .map_err(crate::kv::Error::into_value)
667            }
668
669            fn visit_bool(&mut self, value: bool) -> Result<(), Error> {
670                self.0
671                    .visit_bool(value)
672                    .map_err(crate::kv::Error::into_value)
673            }
674
675            fn visit_str(&mut self, value: &str) -> Result<(), Error> {
676                self.0
677                    .visit_str(value)
678                    .map_err(crate::kv::Error::into_value)
679            }
680
681            fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
682                self.0
683                    .visit_borrowed_str(value)
684                    .map_err(crate::kv::Error::into_value)
685            }
686
687            fn visit_char(&mut self, value: char) -> Result<(), Error> {
688                self.0
689                    .visit_char(value)
690                    .map_err(crate::kv::Error::into_value)
691            }
692
693            #[cfg(feature = "kv_std")]
694            fn visit_error(
695                &mut self,
696                err: &(dyn std::error::Error + 'static),
697            ) -> Result<(), Error> {
698                self.0
699                    .visit_error(err)
700                    .map_err(crate::kv::Error::into_value)
701            }
702
703            #[cfg(feature = "kv_std")]
704            fn visit_borrowed_error(
705                &mut self,
706                err: &'v (dyn std::error::Error + 'static),
707            ) -> Result<(), Error> {
708                self.0
709                    .visit_borrowed_error(err)
710                    .map_err(crate::kv::Error::into_value)
711            }
712        }
713
714        inner
715            .visit(&mut InnerVisitValue(visitor))
716            .map_err(crate::kv::Error::from_value)
717    }
718}
719
720#[cfg(not(feature = "value-bag"))]
721pub(in crate::kv) mod inner {
722    /**
723    This is a dependency-free implementation of `Value` when there's no serialization frameworks involved.
724    In these simple cases a more fully featured solution like `value_bag` isn't needed, so we avoid pulling it in.
725
726    There are a few things here that need to remain consistent with the `value_bag`-based implementation:
727
728    1. Conversions should always produce the same results. If a conversion here returns `Some`, then
729       the same `value_bag`-based conversion must also. Of particular note here are floats to ints; they're
730       based on the standard library's `TryInto` conversions, which need to be converted to `i32` or `u32`,
731       and then to `f64`.
732    2. VisitValues should always be called in the same way. If a particular type of value calls `visit_i64`,
733       then the same `value_bag`-based visitor must also.
734    */
735    use super::*;
736
737    #[derive(Clone)]
738    pub enum Inner<'v> {
739        None,
740        Bool(bool),
741        Str(&'v str),
742        Char(char),
743        I64(i64),
744        U64(u64),
745        F64(f64),
746        I128(i128),
747        U128(u128),
748        Debug(&'v dyn fmt::Debug),
749        Display(&'v dyn fmt::Display),
750    }
751
752    impl<'v> From<()> for Inner<'v> {
753        fn from(_: ()) -> Self {
754            Inner::None
755        }
756    }
757
758    impl<'v> From<bool> for Inner<'v> {
759        fn from(v: bool) -> Self {
760            Inner::Bool(v)
761        }
762    }
763
764    impl<'v> From<char> for Inner<'v> {
765        fn from(v: char) -> Self {
766            Inner::Char(v)
767        }
768    }
769
770    impl<'v> From<f32> for Inner<'v> {
771        fn from(v: f32) -> Self {
772            Inner::F64(v as f64)
773        }
774    }
775
776    impl<'v> From<f64> for Inner<'v> {
777        fn from(v: f64) -> Self {
778            Inner::F64(v)
779        }
780    }
781
782    impl<'v> From<i8> for Inner<'v> {
783        fn from(v: i8) -> Self {
784            Inner::I64(v as i64)
785        }
786    }
787
788    impl<'v> From<i16> for Inner<'v> {
789        fn from(v: i16) -> Self {
790            Inner::I64(v as i64)
791        }
792    }
793
794    impl<'v> From<i32> for Inner<'v> {
795        fn from(v: i32) -> Self {
796            Inner::I64(v as i64)
797        }
798    }
799
800    impl<'v> From<i64> for Inner<'v> {
801        fn from(v: i64) -> Self {
802            Inner::I64(v as i64)
803        }
804    }
805
806    impl<'v> From<isize> for Inner<'v> {
807        fn from(v: isize) -> Self {
808            Inner::I64(v as i64)
809        }
810    }
811
812    impl<'v> From<u8> for Inner<'v> {
813        fn from(v: u8) -> Self {
814            Inner::U64(v as u64)
815        }
816    }
817
818    impl<'v> From<u16> for Inner<'v> {
819        fn from(v: u16) -> Self {
820            Inner::U64(v as u64)
821        }
822    }
823
824    impl<'v> From<u32> for Inner<'v> {
825        fn from(v: u32) -> Self {
826            Inner::U64(v as u64)
827        }
828    }
829
830    impl<'v> From<u64> for Inner<'v> {
831        fn from(v: u64) -> Self {
832            Inner::U64(v as u64)
833        }
834    }
835
836    impl<'v> From<usize> for Inner<'v> {
837        fn from(v: usize) -> Self {
838            Inner::U64(v as u64)
839        }
840    }
841
842    impl<'v> From<i128> for Inner<'v> {
843        fn from(v: i128) -> Self {
844            Inner::I128(v)
845        }
846    }
847
848    impl<'v> From<u128> for Inner<'v> {
849        fn from(v: u128) -> Self {
850            Inner::U128(v)
851        }
852    }
853
854    impl<'v> From<&'v str> for Inner<'v> {
855        fn from(v: &'v str) -> Self {
856            Inner::Str(v)
857        }
858    }
859
860    impl<'v> fmt::Debug for Inner<'v> {
861        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
862            match self {
863                Inner::None => fmt::Debug::fmt(&None::<()>, f),
864                Inner::Bool(v) => fmt::Debug::fmt(v, f),
865                Inner::Str(v) => fmt::Debug::fmt(v, f),
866                Inner::Char(v) => fmt::Debug::fmt(v, f),
867                Inner::I64(v) => fmt::Debug::fmt(v, f),
868                Inner::U64(v) => fmt::Debug::fmt(v, f),
869                Inner::F64(v) => fmt::Debug::fmt(v, f),
870                Inner::I128(v) => fmt::Debug::fmt(v, f),
871                Inner::U128(v) => fmt::Debug::fmt(v, f),
872                Inner::Debug(v) => fmt::Debug::fmt(v, f),
873                Inner::Display(v) => fmt::Display::fmt(v, f),
874            }
875        }
876    }
877
878    impl<'v> fmt::Display for Inner<'v> {
879        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
880            match self {
881                Inner::None => fmt::Debug::fmt(&None::<()>, f),
882                Inner::Bool(v) => fmt::Display::fmt(v, f),
883                Inner::Str(v) => fmt::Display::fmt(v, f),
884                Inner::Char(v) => fmt::Display::fmt(v, f),
885                Inner::I64(v) => fmt::Display::fmt(v, f),
886                Inner::U64(v) => fmt::Display::fmt(v, f),
887                Inner::F64(v) => fmt::Display::fmt(v, f),
888                Inner::I128(v) => fmt::Display::fmt(v, f),
889                Inner::U128(v) => fmt::Display::fmt(v, f),
890                Inner::Debug(v) => fmt::Debug::fmt(v, f),
891                Inner::Display(v) => fmt::Display::fmt(v, f),
892            }
893        }
894    }
895
896    impl<'v> Inner<'v> {
897        pub fn from_debug<T: fmt::Debug>(value: &'v T) -> Self {
898            Inner::Debug(value)
899        }
900
901        pub fn from_display<T: fmt::Display>(value: &'v T) -> Self {
902            Inner::Display(value)
903        }
904
905        pub fn from_dyn_debug(value: &'v dyn fmt::Debug) -> Self {
906            Inner::Debug(value)
907        }
908
909        pub fn from_dyn_display(value: &'v dyn fmt::Display) -> Self {
910            Inner::Display(value)
911        }
912
913        pub fn empty() -> Self {
914            Inner::None
915        }
916
917        pub fn to_bool(&self) -> Option<bool> {
918            match self {
919                Inner::Bool(v) => Some(*v),
920                _ => None,
921            }
922        }
923
924        pub fn to_char(&self) -> Option<char> {
925            match self {
926                Inner::Char(v) => Some(*v),
927                _ => None,
928            }
929        }
930
931        pub fn to_f64(&self) -> Option<f64> {
932            match self {
933                Inner::F64(v) => Some(*v),
934                Inner::I64(v) => {
935                    let v: i32 = (*v).try_into().ok()?;
936                    v.try_into().ok()
937                }
938                Inner::U64(v) => {
939                    let v: u32 = (*v).try_into().ok()?;
940                    v.try_into().ok()
941                }
942                Inner::I128(v) => {
943                    let v: i32 = (*v).try_into().ok()?;
944                    v.try_into().ok()
945                }
946                Inner::U128(v) => {
947                    let v: u32 = (*v).try_into().ok()?;
948                    v.try_into().ok()
949                }
950                _ => None,
951            }
952        }
953
954        pub fn to_i64(&self) -> Option<i64> {
955            match self {
956                Inner::I64(v) => Some(*v),
957                Inner::U64(v) => (*v).try_into().ok(),
958                Inner::I128(v) => (*v).try_into().ok(),
959                Inner::U128(v) => (*v).try_into().ok(),
960                _ => None,
961            }
962        }
963
964        pub fn to_u64(&self) -> Option<u64> {
965            match self {
966                Inner::U64(v) => Some(*v),
967                Inner::I64(v) => (*v).try_into().ok(),
968                Inner::I128(v) => (*v).try_into().ok(),
969                Inner::U128(v) => (*v).try_into().ok(),
970                _ => None,
971            }
972        }
973
974        pub fn to_u128(&self) -> Option<u128> {
975            match self {
976                Inner::U128(v) => Some(*v),
977                Inner::I64(v) => (*v).try_into().ok(),
978                Inner::U64(v) => (*v).try_into().ok(),
979                Inner::I128(v) => (*v).try_into().ok(),
980                _ => None,
981            }
982        }
983
984        pub fn to_i128(&self) -> Option<i128> {
985            match self {
986                Inner::I128(v) => Some(*v),
987                Inner::I64(v) => (*v).try_into().ok(),
988                Inner::U64(v) => (*v).try_into().ok(),
989                Inner::U128(v) => (*v).try_into().ok(),
990                _ => None,
991            }
992        }
993
994        pub fn to_borrowed_str(&self) -> Option<&'v str> {
995            match self {
996                Inner::Str(v) => Some(v),
997                _ => None,
998            }
999        }
1000
1001        #[cfg(test)]
1002        pub fn to_test_token(&self) -> Token {
1003            match self {
1004                Inner::None => Token::None,
1005                Inner::Bool(v) => Token::Bool(*v),
1006                Inner::Str(v) => Token::Str(*v),
1007                Inner::Char(v) => Token::Char(*v),
1008                Inner::I64(v) => Token::I64(*v),
1009                Inner::U64(v) => Token::U64(*v),
1010                Inner::F64(v) => Token::F64(*v),
1011                Inner::I128(_) => unimplemented!(),
1012                Inner::U128(_) => unimplemented!(),
1013                Inner::Debug(_) => unimplemented!(),
1014                Inner::Display(_) => unimplemented!(),
1015            }
1016        }
1017    }
1018
1019    #[cfg(test)]
1020    #[derive(Debug, PartialEq)]
1021    pub enum Token<'v> {
1022        None,
1023        Bool(bool),
1024        Char(char),
1025        Str(&'v str),
1026        F64(f64),
1027        I64(i64),
1028        U64(u64),
1029    }
1030
1031    pub fn visit<'v>(
1032        inner: &Inner<'v>,
1033        mut visitor: impl VisitValue<'v>,
1034    ) -> Result<(), crate::kv::Error> {
1035        match inner {
1036            Inner::None => visitor.visit_null(),
1037            Inner::Bool(v) => visitor.visit_bool(*v),
1038            Inner::Str(v) => visitor.visit_borrowed_str(*v),
1039            Inner::Char(v) => visitor.visit_char(*v),
1040            Inner::I64(v) => visitor.visit_i64(*v),
1041            Inner::U64(v) => visitor.visit_u64(*v),
1042            Inner::F64(v) => visitor.visit_f64(*v),
1043            Inner::I128(v) => visitor.visit_i128(*v),
1044            Inner::U128(v) => visitor.visit_u128(*v),
1045            Inner::Debug(v) => visitor.visit_any(Value::from_dyn_debug(*v)),
1046            Inner::Display(v) => visitor.visit_any(Value::from_dyn_display(*v)),
1047        }
1048    }
1049}
1050
1051impl<'v> Value<'v> {
1052    /// Get a value from a type implementing `std::fmt::Debug`.
1053    #[cfg(feature = "kv_unstable")]
1054    #[deprecated(note = "use `from_debug` instead")]
1055    pub fn capture_debug<T>(value: &'v T) -> Self
1056    where
1057        T: fmt::Debug + 'static,
1058    {
1059        Value::from_debug(value)
1060    }
1061
1062    /// Get a value from a type implementing `std::fmt::Display`.
1063    #[cfg(feature = "kv_unstable")]
1064    #[deprecated(note = "use `from_display` instead")]
1065    pub fn capture_display<T>(value: &'v T) -> Self
1066    where
1067        T: fmt::Display + 'static,
1068    {
1069        Value::from_display(value)
1070    }
1071
1072    /// Get a value from an error.
1073    #[cfg(feature = "kv_unstable_std")]
1074    #[deprecated(note = "use `from_dyn_error` instead")]
1075    pub fn capture_error<T>(err: &'v T) -> Self
1076    where
1077        T: std::error::Error + 'static,
1078    {
1079        Value::from_dyn_error(err)
1080    }
1081
1082    /// Get a value from a type implementing `serde::Serialize`.
1083    #[cfg(feature = "kv_unstable_serde")]
1084    #[deprecated(note = "use `from_serde` instead")]
1085    pub fn capture_serde<T>(value: &'v T) -> Self
1086    where
1087        T: serde_core::Serialize + 'static,
1088    {
1089        Value::from_serde(value)
1090    }
1091
1092    /// Get a value from a type implementing `sval::Value`.
1093    #[cfg(feature = "kv_unstable_sval")]
1094    #[deprecated(note = "use `from_sval` instead")]
1095    pub fn capture_sval<T>(value: &'v T) -> Self
1096    where
1097        T: sval::Value + 'static,
1098    {
1099        Value::from_sval(value)
1100    }
1101
1102    /// Check whether this value can be downcast to `T`.
1103    #[cfg(feature = "kv_unstable")]
1104    #[deprecated(
1105        note = "downcasting has been removed; log an issue at https://github.com/rust-lang/log/issues if this is something you rely on"
1106    )]
1107    pub fn is<T: 'static>(&self) -> bool {
1108        false
1109    }
1110
1111    /// Try downcast this value to `T`.
1112    #[cfg(feature = "kv_unstable")]
1113    #[deprecated(
1114        note = "downcasting has been removed; log an issue at https://github.com/rust-lang/log/issues if this is something you rely on"
1115    )]
1116    pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
1117        None
1118    }
1119}
1120
1121// NOTE: Deprecated; but aliases can't carry this attribute
1122#[cfg(feature = "kv_unstable")]
1123pub use VisitValue as Visit;
1124
1125/// Get a value from a type implementing `std::fmt::Debug`.
1126#[cfg(feature = "kv_unstable")]
1127#[deprecated(note = "use the `key:? = value` macro syntax instead")]
1128#[macro_export]
1129macro_rules! as_debug {
1130    ($capture:expr) => {
1131        $crate::kv::Value::from_debug(&$capture)
1132    };
1133}
1134
1135/// Get a value from a type implementing `std::fmt::Display`.
1136#[cfg(feature = "kv_unstable")]
1137#[deprecated(note = "use the `key:% = value` macro syntax instead")]
1138#[macro_export]
1139macro_rules! as_display {
1140    ($capture:expr) => {
1141        $crate::kv::Value::from_display(&$capture)
1142    };
1143}
1144
1145/// Get a value from an error.
1146#[cfg(feature = "kv_unstable_std")]
1147#[deprecated(note = "use the `key:err = value` macro syntax instead")]
1148#[macro_export]
1149macro_rules! as_error {
1150    ($capture:expr) => {
1151        $crate::kv::Value::from_dyn_error(&$capture)
1152    };
1153}
1154
1155#[cfg(feature = "kv_unstable_serde")]
1156#[deprecated(note = "use the `key:serde = value` macro syntax instead")]
1157/// Get a value from a type implementing `serde::Serialize`.
1158#[macro_export]
1159macro_rules! as_serde {
1160    ($capture:expr) => {
1161        $crate::kv::Value::from_serde(&$capture)
1162    };
1163}
1164
1165/// Get a value from a type implementing `sval::Value`.
1166#[cfg(feature = "kv_unstable_sval")]
1167#[deprecated(note = "use the `key:sval = value` macro syntax instead")]
1168#[macro_export]
1169macro_rules! as_sval {
1170    ($capture:expr) => {
1171        $crate::kv::Value::from_sval(&$capture)
1172    };
1173}
1174
1175#[cfg(test)]
1176pub(crate) mod tests {
1177    use super::*;
1178
1179    impl<'v> Value<'v> {
1180        pub(crate) fn to_token(&self) -> inner::Token {
1181            self.inner.to_test_token()
1182        }
1183    }
1184
1185    fn unsigned() -> impl Iterator<Item = Value<'static>> {
1186        vec![
1187            Value::from(8u8),
1188            Value::from(16u16),
1189            Value::from(32u32),
1190            Value::from(64u64),
1191            Value::from(1usize),
1192            Value::from(std::num::NonZeroU8::new(8).unwrap()),
1193            Value::from(std::num::NonZeroU16::new(16).unwrap()),
1194            Value::from(std::num::NonZeroU32::new(32).unwrap()),
1195            Value::from(std::num::NonZeroU64::new(64).unwrap()),
1196            Value::from(std::num::NonZeroUsize::new(1).unwrap()),
1197        ]
1198        .into_iter()
1199    }
1200
1201    fn signed() -> impl Iterator<Item = Value<'static>> {
1202        vec![
1203            Value::from(-8i8),
1204            Value::from(-16i16),
1205            Value::from(-32i32),
1206            Value::from(-64i64),
1207            Value::from(-1isize),
1208            Value::from(std::num::NonZeroI8::new(-8).unwrap()),
1209            Value::from(std::num::NonZeroI16::new(-16).unwrap()),
1210            Value::from(std::num::NonZeroI32::new(-32).unwrap()),
1211            Value::from(std::num::NonZeroI64::new(-64).unwrap()),
1212            Value::from(std::num::NonZeroIsize::new(-1).unwrap()),
1213        ]
1214        .into_iter()
1215    }
1216
1217    fn float() -> impl Iterator<Item = Value<'static>> {
1218        vec![Value::from(32.32f32), Value::from(64.64f64)].into_iter()
1219    }
1220
1221    fn bool() -> impl Iterator<Item = Value<'static>> {
1222        vec![Value::from(true), Value::from(false)].into_iter()
1223    }
1224
1225    fn str() -> impl Iterator<Item = Value<'static>> {
1226        vec![Value::from("a string"), Value::from("a loong string")].into_iter()
1227    }
1228
1229    fn char() -> impl Iterator<Item = Value<'static>> {
1230        vec![Value::from('a'), Value::from('⛰')].into_iter()
1231    }
1232
1233    #[test]
1234    fn test_to_value_display() {
1235        assert_eq!(42u64.to_value().to_string(), "42");
1236        assert_eq!(42i64.to_value().to_string(), "42");
1237        assert_eq!(42.01f64.to_value().to_string(), "42.01");
1238        assert_eq!(true.to_value().to_string(), "true");
1239        assert_eq!('a'.to_value().to_string(), "a");
1240        assert_eq!("a loong string".to_value().to_string(), "a loong string");
1241        assert_eq!(Some(true).to_value().to_string(), "true");
1242        assert_eq!(().to_value().to_string(), "None");
1243        assert_eq!(None::<bool>.to_value().to_string(), "None");
1244    }
1245
1246    #[test]
1247    fn test_to_value_structured() {
1248        assert_eq!(42u64.to_value().to_token(), inner::Token::U64(42));
1249        assert_eq!(42i64.to_value().to_token(), inner::Token::I64(42));
1250        assert_eq!(42.01f64.to_value().to_token(), inner::Token::F64(42.01));
1251        assert_eq!(true.to_value().to_token(), inner::Token::Bool(true));
1252        assert_eq!('a'.to_value().to_token(), inner::Token::Char('a'));
1253        assert_eq!(
1254            "a loong string".to_value().to_token(),
1255            inner::Token::Str("a loong string".into())
1256        );
1257        assert_eq!(Some(true).to_value().to_token(), inner::Token::Bool(true));
1258        assert_eq!(().to_value().to_token(), inner::Token::None);
1259        assert_eq!(None::<bool>.to_value().to_token(), inner::Token::None);
1260    }
1261
1262    #[test]
1263    fn test_to_number() {
1264        for v in unsigned() {
1265            assert!(v.to_u64().is_some());
1266            assert!(v.to_i64().is_some());
1267        }
1268
1269        for v in signed() {
1270            assert!(v.to_i64().is_some());
1271        }
1272
1273        for v in unsigned().chain(signed()).chain(float()) {
1274            assert!(v.to_f64().is_some());
1275        }
1276
1277        for v in bool().chain(str()).chain(char()) {
1278            assert!(v.to_u64().is_none());
1279            assert!(v.to_i64().is_none());
1280            assert!(v.to_f64().is_none());
1281        }
1282    }
1283
1284    #[test]
1285    fn test_to_float() {
1286        // Only integers from i32::MIN..=u32::MAX can be converted into floats
1287        assert!(Value::from(i32::MIN).to_f64().is_some());
1288        assert!(Value::from(u32::MAX).to_f64().is_some());
1289
1290        assert!(Value::from((i32::MIN as i64) - 1).to_f64().is_none());
1291        assert!(Value::from((u32::MAX as u64) + 1).to_f64().is_none());
1292    }
1293
1294    #[test]
1295    fn test_to_cow_str() {
1296        for v in str() {
1297            assert!(v.to_borrowed_str().is_some());
1298
1299            #[cfg(feature = "kv_std")]
1300            assert!(v.to_cow_str().is_some());
1301        }
1302
1303        let short_lived = String::from("short lived");
1304        let v = Value::from(&*short_lived);
1305
1306        assert!(v.to_borrowed_str().is_some());
1307
1308        #[cfg(feature = "kv_std")]
1309        assert!(v.to_cow_str().is_some());
1310
1311        for v in unsigned().chain(signed()).chain(float()).chain(bool()) {
1312            assert!(v.to_borrowed_str().is_none());
1313
1314            #[cfg(feature = "kv_std")]
1315            assert!(v.to_cow_str().is_none());
1316        }
1317    }
1318
1319    #[test]
1320    fn test_to_bool() {
1321        for v in bool() {
1322            assert!(v.to_bool().is_some());
1323        }
1324
1325        for v in unsigned()
1326            .chain(signed())
1327            .chain(float())
1328            .chain(str())
1329            .chain(char())
1330        {
1331            assert!(v.to_bool().is_none());
1332        }
1333    }
1334
1335    #[test]
1336    fn test_to_char() {
1337        for v in char() {
1338            assert!(v.to_char().is_some());
1339        }
1340
1341        for v in unsigned()
1342            .chain(signed())
1343            .chain(float())
1344            .chain(str())
1345            .chain(bool())
1346        {
1347            assert!(v.to_char().is_none());
1348        }
1349    }
1350
1351    #[test]
1352    fn test_visit_integer() {
1353        struct Extract(Option<u64>);
1354
1355        impl<'v> VisitValue<'v> for Extract {
1356            fn visit_any(&mut self, value: Value) -> Result<(), Error> {
1357                unimplemented!("unexpected value: {value:?}")
1358            }
1359
1360            fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
1361                self.0 = Some(value);
1362
1363                Ok(())
1364            }
1365        }
1366
1367        let mut extract = Extract(None);
1368        Value::from(42u64).visit(&mut extract).unwrap();
1369
1370        assert_eq!(Some(42), extract.0);
1371    }
1372
1373    #[test]
1374    fn test_visit_borrowed_str() {
1375        struct Extract<'v>(Option<&'v str>);
1376
1377        impl<'v> VisitValue<'v> for Extract<'v> {
1378            fn visit_any(&mut self, value: Value) -> Result<(), Error> {
1379                unimplemented!("unexpected value: {value:?}")
1380            }
1381
1382            fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
1383                self.0 = Some(value);
1384
1385                Ok(())
1386            }
1387        }
1388
1389        let mut extract = Extract(None);
1390
1391        let short_lived = String::from("A short-lived string");
1392        Value::from(&*short_lived).visit(&mut extract).unwrap();
1393
1394        assert_eq!(Some("A short-lived string"), extract.0);
1395    }
1396}