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