1use std::fmt;
7
8pub use crate::kv::Error;
9
10pub trait ToValue {
12 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#[derive(Clone)]
119pub struct Value<'v> {
120 inner: inner::Inner<'v>,
121}
122
123impl<'v> Value<'v> {
124 pub fn from_any<T>(value: &'v T) -> Self
126 where
127 T: ToValue,
128 {
129 value.to_value()
130 }
131
132 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 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 #[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 #[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 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 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 #[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 pub fn null() -> Self {
198 Value {
199 inner: inner::Inner::empty(),
200 }
201 }
202
203 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 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 #[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 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 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
450pub trait VisitValue<'v> {
463 fn visit_any(&mut self, value: Value) -> Result<(), Error>;
470
471 fn visit_null(&mut self) -> Result<(), Error> {
473 self.visit_any(Value::null())
474 }
475
476 fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
478 self.visit_any(value.into())
479 }
480
481 fn visit_i64(&mut self, value: i64) -> Result<(), Error> {
483 self.visit_any(value.into())
484 }
485
486 fn visit_u128(&mut self, value: u128) -> Result<(), Error> {
488 self.visit_any((value).into())
489 }
490
491 fn visit_i128(&mut self, value: i128) -> Result<(), Error> {
493 self.visit_any((value).into())
494 }
495
496 fn visit_f64(&mut self, value: f64) -> Result<(), Error> {
498 self.visit_any(value.into())
499 }
500
501 fn visit_bool(&mut self, value: bool) -> Result<(), Error> {
503 self.visit_any(value.into())
504 }
505
506 fn visit_str(&mut self, value: &str) -> Result<(), Error> {
508 self.visit_any(value.into())
509 }
510
511 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
513 self.visit_str(value)
514 }
515
516 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 #[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 #[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)] impl<'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 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 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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#[cfg(feature = "kv_unstable")]
1123pub use VisitValue as Visit;
1124
1125#[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#[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#[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#[macro_export]
1159macro_rules! as_serde {
1160 ($capture:expr) => {
1161 $crate::kv::Value::from_serde(&$capture)
1162 };
1163}
1164
1165#[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 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}