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