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
376#[cfg(feature = "std")]
377macro_rules! impl_to_value_from_display {
378 ($($into_ty:ty,)*) => {
379 $(
380 impl ToValue for $into_ty {
381 fn to_value(&self) -> Value<'_> {
382 Value::from_display(self)
383 }
384 }
385
386 impl<'v> From<&'v $into_ty> for Value<'v> {
387 fn from(value: &'v $into_ty) -> Self {
388 Value::from_display(value)
389 }
390 }
391 )*
392 };
393}
394
395#[cfg(feature = "std")]
396impl_to_value_from_display![
397 std::net::IpAddr,
398 std::net::Ipv4Addr,
399 std::net::Ipv6Addr,
400 std::net::SocketAddr,
401 std::net::SocketAddrV4,
402 std::net::SocketAddrV6,
403];
404
405impl<'v> Value<'v> {
406 #[cfg(feature = "kv_std")]
408 pub fn to_borrowed_error(&self) -> Option<&(dyn std::error::Error + 'static)> {
409 self.inner.to_borrowed_error()
410 }
411
412 pub fn to_borrowed_str(&self) -> Option<&'v str> {
414 self.inner.to_borrowed_str()
415 }
416}
417
418#[cfg(feature = "std")]
419mod std_support {
420 use std::borrow::Cow;
421 use std::rc::Rc;
422 use std::sync::Arc;
423
424 use super::*;
425
426 impl<T> ToValue for Box<T>
427 where
428 T: ToValue + ?Sized,
429 {
430 fn to_value(&self) -> Value<'_> {
431 (**self).to_value()
432 }
433 }
434
435 impl<T> ToValue for Arc<T>
436 where
437 T: ToValue + ?Sized,
438 {
439 fn to_value(&self) -> Value<'_> {
440 (**self).to_value()
441 }
442 }
443
444 impl<T> ToValue for Rc<T>
445 where
446 T: ToValue + ?Sized,
447 {
448 fn to_value(&self) -> Value<'_> {
449 (**self).to_value()
450 }
451 }
452
453 impl ToValue for String {
454 fn to_value(&self) -> Value<'_> {
455 Value::from(&**self)
456 }
457 }
458
459 impl<'v> ToValue for Cow<'v, str> {
460 fn to_value(&self) -> Value<'_> {
461 Value::from(&**self)
462 }
463 }
464
465 #[cfg(feature = "kv_std")]
466 impl<'v> Value<'v> {
467 pub fn to_cow_str(&self) -> Option<Cow<'v, str>> {
469 self.inner.to_str()
470 }
471 }
472
473 impl<'v> From<&'v String> for Value<'v> {
474 fn from(v: &'v String) -> Self {
475 Value::from(&**v)
476 }
477 }
478}
479
480pub trait VisitValue<'v> {
493 fn visit_any(&mut self, value: Value) -> Result<(), Error>;
500
501 fn visit_null(&mut self) -> Result<(), Error> {
503 self.visit_any(Value::null())
504 }
505
506 fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
508 self.visit_any(value.into())
509 }
510
511 fn visit_i64(&mut self, value: i64) -> Result<(), Error> {
513 self.visit_any(value.into())
514 }
515
516 fn visit_u128(&mut self, value: u128) -> Result<(), Error> {
518 self.visit_any((value).into())
519 }
520
521 fn visit_i128(&mut self, value: i128) -> Result<(), Error> {
523 self.visit_any((value).into())
524 }
525
526 fn visit_f64(&mut self, value: f64) -> Result<(), Error> {
528 self.visit_any(value.into())
529 }
530
531 fn visit_bool(&mut self, value: bool) -> Result<(), Error> {
533 self.visit_any(value.into())
534 }
535
536 fn visit_str(&mut self, value: &str) -> Result<(), Error> {
538 self.visit_any(value.into())
539 }
540
541 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
543 self.visit_str(value)
544 }
545
546 fn visit_char(&mut self, value: char) -> Result<(), Error> {
548 let mut b = [0; 4];
549 self.visit_str(&*value.encode_utf8(&mut b))
550 }
551
552 #[cfg(feature = "kv_std")]
554 fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> {
555 self.visit_any(Value::from_dyn_error(err))
556 }
557
558 #[cfg(feature = "kv_std")]
560 fn visit_borrowed_error(
561 &mut self,
562 err: &'v (dyn std::error::Error + 'static),
563 ) -> Result<(), Error> {
564 self.visit_any(Value::from_dyn_error(err))
565 }
566}
567
568#[allow(clippy::needless_lifetimes)] impl<'a, 'v, T: ?Sized> VisitValue<'v> for &'a mut T
570where
571 T: VisitValue<'v>,
572{
573 fn visit_any(&mut self, value: Value) -> Result<(), Error> {
574 (**self).visit_any(value)
575 }
576
577 fn visit_null(&mut self) -> Result<(), Error> {
578 (**self).visit_null()
579 }
580
581 fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
582 (**self).visit_u64(value)
583 }
584
585 fn visit_i64(&mut self, value: i64) -> Result<(), Error> {
586 (**self).visit_i64(value)
587 }
588
589 fn visit_u128(&mut self, value: u128) -> Result<(), Error> {
590 (**self).visit_u128(value)
591 }
592
593 fn visit_i128(&mut self, value: i128) -> Result<(), Error> {
594 (**self).visit_i128(value)
595 }
596
597 fn visit_f64(&mut self, value: f64) -> Result<(), Error> {
598 (**self).visit_f64(value)
599 }
600
601 fn visit_bool(&mut self, value: bool) -> Result<(), Error> {
602 (**self).visit_bool(value)
603 }
604
605 fn visit_str(&mut self, value: &str) -> Result<(), Error> {
606 (**self).visit_str(value)
607 }
608
609 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
610 (**self).visit_borrowed_str(value)
611 }
612
613 fn visit_char(&mut self, value: char) -> Result<(), Error> {
614 (**self).visit_char(value)
615 }
616
617 #[cfg(feature = "kv_std")]
618 fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> {
619 (**self).visit_error(err)
620 }
621
622 #[cfg(feature = "kv_std")]
623 fn visit_borrowed_error(
624 &mut self,
625 err: &'v (dyn std::error::Error + 'static),
626 ) -> Result<(), Error> {
627 (**self).visit_borrowed_error(err)
628 }
629}
630
631#[cfg(feature = "value-bag")]
632pub(in crate::kv) mod inner {
633 use super::*;
641
642 pub use value_bag::ValueBag as Inner;
643
644 pub use value_bag::Error;
645
646 #[cfg(test)]
647 pub use value_bag::test::TestToken as Token;
648
649 pub fn visit<'v>(
650 inner: &Inner<'v>,
651 visitor: impl VisitValue<'v>,
652 ) -> Result<(), crate::kv::Error> {
653 struct InnerVisitValue<V>(V);
654
655 impl<'v, V> value_bag::visit::Visit<'v> for InnerVisitValue<V>
656 where
657 V: VisitValue<'v>,
658 {
659 fn visit_any(&mut self, value: value_bag::ValueBag) -> Result<(), Error> {
660 self.0
661 .visit_any(Value { inner: value })
662 .map_err(crate::kv::Error::into_value)
663 }
664
665 fn visit_empty(&mut self) -> Result<(), Error> {
666 self.0.visit_null().map_err(crate::kv::Error::into_value)
667 }
668
669 fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
670 self.0
671 .visit_u64(value)
672 .map_err(crate::kv::Error::into_value)
673 }
674
675 fn visit_i64(&mut self, value: i64) -> Result<(), Error> {
676 self.0
677 .visit_i64(value)
678 .map_err(crate::kv::Error::into_value)
679 }
680
681 fn visit_u128(&mut self, value: u128) -> Result<(), Error> {
682 self.0
683 .visit_u128(value)
684 .map_err(crate::kv::Error::into_value)
685 }
686
687 fn visit_i128(&mut self, value: i128) -> Result<(), Error> {
688 self.0
689 .visit_i128(value)
690 .map_err(crate::kv::Error::into_value)
691 }
692
693 fn visit_f64(&mut self, value: f64) -> Result<(), Error> {
694 self.0
695 .visit_f64(value)
696 .map_err(crate::kv::Error::into_value)
697 }
698
699 fn visit_bool(&mut self, value: bool) -> Result<(), Error> {
700 self.0
701 .visit_bool(value)
702 .map_err(crate::kv::Error::into_value)
703 }
704
705 fn visit_str(&mut self, value: &str) -> Result<(), Error> {
706 self.0
707 .visit_str(value)
708 .map_err(crate::kv::Error::into_value)
709 }
710
711 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
712 self.0
713 .visit_borrowed_str(value)
714 .map_err(crate::kv::Error::into_value)
715 }
716
717 fn visit_char(&mut self, value: char) -> Result<(), Error> {
718 self.0
719 .visit_char(value)
720 .map_err(crate::kv::Error::into_value)
721 }
722
723 #[cfg(feature = "kv_std")]
724 fn visit_error(
725 &mut self,
726 err: &(dyn std::error::Error + 'static),
727 ) -> Result<(), Error> {
728 self.0
729 .visit_error(err)
730 .map_err(crate::kv::Error::into_value)
731 }
732
733 #[cfg(feature = "kv_std")]
734 fn visit_borrowed_error(
735 &mut self,
736 err: &'v (dyn std::error::Error + 'static),
737 ) -> Result<(), Error> {
738 self.0
739 .visit_borrowed_error(err)
740 .map_err(crate::kv::Error::into_value)
741 }
742 }
743
744 inner
745 .visit(&mut InnerVisitValue(visitor))
746 .map_err(crate::kv::Error::from_value)
747 }
748}
749
750#[cfg(not(feature = "value-bag"))]
751pub(in crate::kv) mod inner {
752 use super::*;
766
767 #[derive(Clone)]
768 pub enum Inner<'v> {
769 None,
771 Bool(bool),
772 Str(&'v str),
773 Char(char),
774 I64(i64),
775 U64(u64),
776 F64(f64),
777 I128(i128),
778 U128(u128),
779 Debug(&'v dyn fmt::Debug),
780 Display(&'v dyn fmt::Display),
781 }
782
783 impl<'v> From<()> for Inner<'v> {
784 fn from(_: ()) -> Self {
785 Inner::None
786 }
787 }
788
789 impl<'v> From<bool> for Inner<'v> {
790 fn from(v: bool) -> Self {
791 Inner::Bool(v)
792 }
793 }
794
795 impl<'v> From<char> for Inner<'v> {
796 fn from(v: char) -> Self {
797 Inner::Char(v)
798 }
799 }
800
801 impl<'v> From<f32> for Inner<'v> {
802 fn from(v: f32) -> Self {
803 Inner::F64(v as f64)
804 }
805 }
806
807 impl<'v> From<f64> for Inner<'v> {
808 fn from(v: f64) -> Self {
809 Inner::F64(v)
810 }
811 }
812
813 impl<'v> From<i8> for Inner<'v> {
814 fn from(v: i8) -> Self {
815 Inner::I64(v as i64)
816 }
817 }
818
819 impl<'v> From<i16> for Inner<'v> {
820 fn from(v: i16) -> Self {
821 Inner::I64(v as i64)
822 }
823 }
824
825 impl<'v> From<i32> for Inner<'v> {
826 fn from(v: i32) -> Self {
827 Inner::I64(v as i64)
828 }
829 }
830
831 impl<'v> From<i64> for Inner<'v> {
832 fn from(v: i64) -> Self {
833 Inner::I64(v as i64)
834 }
835 }
836
837 impl<'v> From<isize> for Inner<'v> {
838 fn from(v: isize) -> Self {
839 Inner::I64(v as i64)
840 }
841 }
842
843 impl<'v> From<u8> for Inner<'v> {
844 fn from(v: u8) -> Self {
845 Inner::U64(v as u64)
846 }
847 }
848
849 impl<'v> From<u16> for Inner<'v> {
850 fn from(v: u16) -> Self {
851 Inner::U64(v as u64)
852 }
853 }
854
855 impl<'v> From<u32> for Inner<'v> {
856 fn from(v: u32) -> Self {
857 Inner::U64(v as u64)
858 }
859 }
860
861 impl<'v> From<u64> for Inner<'v> {
862 fn from(v: u64) -> Self {
863 Inner::U64(v as u64)
864 }
865 }
866
867 impl<'v> From<usize> for Inner<'v> {
868 fn from(v: usize) -> Self {
869 Inner::U64(v as u64)
870 }
871 }
872
873 impl<'v> From<i128> for Inner<'v> {
874 fn from(v: i128) -> Self {
875 Inner::I128(v)
876 }
877 }
878
879 impl<'v> From<u128> for Inner<'v> {
880 fn from(v: u128) -> Self {
881 Inner::U128(v)
882 }
883 }
884
885 impl<'v> From<&'v str> for Inner<'v> {
886 fn from(v: &'v str) -> Self {
887 Inner::Str(v)
888 }
889 }
890
891 impl<'v> fmt::Debug for Inner<'v> {
892 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
893 match self {
894 Inner::None => fmt::Debug::fmt(&None::<()>, f),
895 Inner::Bool(v) => fmt::Debug::fmt(v, f),
896 Inner::Str(v) => fmt::Debug::fmt(v, f),
897 Inner::Char(v) => fmt::Debug::fmt(v, f),
898 Inner::I64(v) => fmt::Debug::fmt(v, f),
899 Inner::U64(v) => fmt::Debug::fmt(v, f),
900 Inner::F64(v) => fmt::Debug::fmt(v, f),
901 Inner::I128(v) => fmt::Debug::fmt(v, f),
902 Inner::U128(v) => fmt::Debug::fmt(v, f),
903 Inner::Debug(v) => fmt::Debug::fmt(v, f),
904 Inner::Display(v) => fmt::Display::fmt(v, f),
905 }
906 }
907 }
908
909 impl<'v> fmt::Display for Inner<'v> {
910 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
911 match self {
912 Inner::None => fmt::Debug::fmt(&None::<()>, f),
913 Inner::Bool(v) => fmt::Display::fmt(v, f),
914 Inner::Str(v) => fmt::Display::fmt(v, f),
915 Inner::Char(v) => fmt::Display::fmt(v, f),
916 Inner::I64(v) => fmt::Display::fmt(v, f),
917 Inner::U64(v) => fmt::Display::fmt(v, f),
918 Inner::F64(v) => fmt::Display::fmt(v, f),
919 Inner::I128(v) => fmt::Display::fmt(v, f),
920 Inner::U128(v) => fmt::Display::fmt(v, f),
921 Inner::Debug(v) => fmt::Debug::fmt(v, f),
922 Inner::Display(v) => fmt::Display::fmt(v, f),
923 }
924 }
925 }
926
927 impl<'v> Inner<'v> {
928 pub fn from_debug<T: fmt::Debug>(value: &'v T) -> Self {
929 Inner::Debug(value)
930 }
931
932 pub fn from_display<T: fmt::Display>(value: &'v T) -> Self {
933 Inner::Display(value)
934 }
935
936 pub fn from_dyn_debug(value: &'v dyn fmt::Debug) -> Self {
937 Inner::Debug(value)
938 }
939
940 pub fn from_dyn_display(value: &'v dyn fmt::Display) -> Self {
941 Inner::Display(value)
942 }
943
944 pub fn empty() -> Self {
945 Inner::None
946 }
947
948 pub fn to_bool(&self) -> Option<bool> {
949 match self {
950 Inner::Bool(v) => Some(*v),
951 _ => None,
952 }
953 }
954
955 pub fn to_char(&self) -> Option<char> {
956 match self {
957 Inner::Char(v) => Some(*v),
958 _ => None,
959 }
960 }
961
962 pub fn to_f64(&self) -> Option<f64> {
963 match self {
964 Inner::F64(v) => Some(*v),
965 Inner::I64(v) => {
966 let v: i32 = (*v).try_into().ok()?;
967 v.try_into().ok()
968 }
969 Inner::U64(v) => {
970 let v: u32 = (*v).try_into().ok()?;
971 v.try_into().ok()
972 }
973 Inner::I128(v) => {
974 let v: i32 = (*v).try_into().ok()?;
975 v.try_into().ok()
976 }
977 Inner::U128(v) => {
978 let v: u32 = (*v).try_into().ok()?;
979 v.try_into().ok()
980 }
981 _ => None,
982 }
983 }
984
985 pub fn to_i64(&self) -> Option<i64> {
986 match self {
987 Inner::I64(v) => Some(*v),
988 Inner::U64(v) => (*v).try_into().ok(),
989 Inner::I128(v) => (*v).try_into().ok(),
990 Inner::U128(v) => (*v).try_into().ok(),
991 _ => None,
992 }
993 }
994
995 pub fn to_u64(&self) -> Option<u64> {
996 match self {
997 Inner::U64(v) => Some(*v),
998 Inner::I64(v) => (*v).try_into().ok(),
999 Inner::I128(v) => (*v).try_into().ok(),
1000 Inner::U128(v) => (*v).try_into().ok(),
1001 _ => None,
1002 }
1003 }
1004
1005 pub fn to_u128(&self) -> Option<u128> {
1006 match self {
1007 Inner::U128(v) => Some(*v),
1008 Inner::I64(v) => (*v).try_into().ok(),
1009 Inner::U64(v) => (*v).try_into().ok(),
1010 Inner::I128(v) => (*v).try_into().ok(),
1011 _ => None,
1012 }
1013 }
1014
1015 pub fn to_i128(&self) -> Option<i128> {
1016 match self {
1017 Inner::I128(v) => Some(*v),
1018 Inner::I64(v) => (*v).try_into().ok(),
1019 Inner::U64(v) => (*v).try_into().ok(),
1020 Inner::U128(v) => (*v).try_into().ok(),
1021 _ => None,
1022 }
1023 }
1024
1025 pub fn to_borrowed_str(&self) -> Option<&'v str> {
1026 match self {
1027 Inner::Str(v) => Some(v),
1028 _ => None,
1029 }
1030 }
1031
1032 #[cfg(test)]
1033 pub fn to_test_token(&self) -> Token<'_> {
1034 match self {
1035 Inner::None => Token::None,
1036 Inner::Bool(v) => Token::Bool(*v),
1037 Inner::Str(v) => Token::Str(*v),
1038 Inner::Char(v) => Token::Char(*v),
1039 Inner::I64(v) => Token::I64(*v),
1040 Inner::U64(v) => Token::U64(*v),
1041 Inner::F64(v) => Token::F64(*v),
1042 Inner::I128(_) => unimplemented!(),
1043 Inner::U128(_) => unimplemented!(),
1044 Inner::Debug(_) => unimplemented!(),
1045 Inner::Display(_) => unimplemented!(),
1046 }
1047 }
1048 }
1049
1050 #[cfg(test)]
1051 #[derive(Debug, PartialEq)]
1052 pub enum Token<'v> {
1053 None,
1054 Bool(bool),
1055 Char(char),
1056 Str(&'v str),
1057 F64(f64),
1058 I64(i64),
1059 U64(u64),
1060 }
1061
1062 pub fn visit<'v>(
1063 inner: &Inner<'v>,
1064 mut visitor: impl VisitValue<'v>,
1065 ) -> Result<(), crate::kv::Error> {
1066 match inner {
1067 Inner::None => visitor.visit_null(),
1068 Inner::Bool(v) => visitor.visit_bool(*v),
1069 Inner::Str(v) => visitor.visit_borrowed_str(*v),
1070 Inner::Char(v) => visitor.visit_char(*v),
1071 Inner::I64(v) => visitor.visit_i64(*v),
1072 Inner::U64(v) => visitor.visit_u64(*v),
1073 Inner::F64(v) => visitor.visit_f64(*v),
1074 Inner::I128(v) => visitor.visit_i128(*v),
1075 Inner::U128(v) => visitor.visit_u128(*v),
1076 Inner::Debug(v) => visitor.visit_any(Value::from_dyn_debug(*v)),
1077 Inner::Display(v) => visitor.visit_any(Value::from_dyn_display(*v)),
1078 }
1079 }
1080}
1081
1082impl<'v> Value<'v> {
1083 #[cfg(feature = "kv_unstable")]
1085 #[deprecated(note = "use `from_debug` instead")]
1086 pub fn capture_debug<T>(value: &'v T) -> Self
1087 where
1088 T: fmt::Debug + 'static,
1089 {
1090 Value::from_debug(value)
1091 }
1092
1093 #[cfg(feature = "kv_unstable")]
1095 #[deprecated(note = "use `from_display` instead")]
1096 pub fn capture_display<T>(value: &'v T) -> Self
1097 where
1098 T: fmt::Display + 'static,
1099 {
1100 Value::from_display(value)
1101 }
1102
1103 #[cfg(feature = "kv_unstable_std")]
1105 #[deprecated(note = "use `from_dyn_error` instead")]
1106 pub fn capture_error<T>(err: &'v T) -> Self
1107 where
1108 T: std::error::Error + 'static,
1109 {
1110 Value::from_dyn_error(err)
1111 }
1112
1113 #[cfg(feature = "kv_unstable_serde")]
1115 #[deprecated(note = "use `from_serde` instead")]
1116 pub fn capture_serde<T>(value: &'v T) -> Self
1117 where
1118 T: serde_core::Serialize + 'static,
1119 {
1120 Value::from_serde(value)
1121 }
1122
1123 #[cfg(feature = "kv_unstable_sval")]
1125 #[deprecated(note = "use `from_sval` instead")]
1126 pub fn capture_sval<T>(value: &'v T) -> Self
1127 where
1128 T: sval::Value + 'static,
1129 {
1130 Value::from_sval(value)
1131 }
1132
1133 #[cfg(feature = "kv_unstable")]
1135 #[deprecated(
1136 note = "downcasting has been removed; log an issue at https://github.com/rust-lang/log/issues if this is something you rely on"
1137 )]
1138 pub fn is<T: 'static>(&self) -> bool {
1139 false
1140 }
1141
1142 #[cfg(feature = "kv_unstable")]
1144 #[deprecated(
1145 note = "downcasting has been removed; log an issue at https://github.com/rust-lang/log/issues if this is something you rely on"
1146 )]
1147 pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
1148 None
1149 }
1150}
1151
1152#[cfg(feature = "kv_unstable")]
1154pub use VisitValue as Visit;
1155
1156#[cfg(feature = "kv_unstable")]
1158#[deprecated(note = "use the `key:? = value` macro syntax instead")]
1159#[macro_export]
1160macro_rules! as_debug {
1161 ($capture:expr) => {
1162 $crate::kv::Value::from_debug(&$capture)
1163 };
1164}
1165
1166#[cfg(feature = "kv_unstable")]
1168#[deprecated(note = "use the `key:% = value` macro syntax instead")]
1169#[macro_export]
1170macro_rules! as_display {
1171 ($capture:expr) => {
1172 $crate::kv::Value::from_display(&$capture)
1173 };
1174}
1175
1176#[cfg(feature = "kv_unstable_std")]
1178#[deprecated(note = "use the `key:err = value` macro syntax instead")]
1179#[macro_export]
1180macro_rules! as_error {
1181 ($capture:expr) => {
1182 $crate::kv::Value::from_dyn_error(&$capture)
1183 };
1184}
1185
1186#[cfg(feature = "kv_unstable_serde")]
1187#[deprecated(note = "use the `key:serde = value` macro syntax instead")]
1188#[macro_export]
1190macro_rules! as_serde {
1191 ($capture:expr) => {
1192 $crate::kv::Value::from_serde(&$capture)
1193 };
1194}
1195
1196#[cfg(feature = "kv_unstable_sval")]
1198#[deprecated(note = "use the `key:sval = value` macro syntax instead")]
1199#[macro_export]
1200macro_rules! as_sval {
1201 ($capture:expr) => {
1202 $crate::kv::Value::from_sval(&$capture)
1203 };
1204}
1205
1206#[cfg(test)]
1207pub(crate) mod tests {
1208 use super::*;
1209
1210 impl<'v> Value<'v> {
1213 #[allow(mismatched_lifetime_syntaxes)]
1214 pub(crate) fn to_token(&self) -> inner::Token {
1215 self.inner.to_test_token()
1216 }
1217 }
1218
1219 fn unsigned() -> impl Iterator<Item = Value<'static>> {
1220 vec![
1221 Value::from(8u8),
1222 Value::from(16u16),
1223 Value::from(32u32),
1224 Value::from(64u64),
1225 Value::from(1usize),
1226 Value::from(std::num::NonZeroU8::new(8).unwrap()),
1227 Value::from(std::num::NonZeroU16::new(16).unwrap()),
1228 Value::from(std::num::NonZeroU32::new(32).unwrap()),
1229 Value::from(std::num::NonZeroU64::new(64).unwrap()),
1230 Value::from(std::num::NonZeroUsize::new(1).unwrap()),
1231 ]
1232 .into_iter()
1233 }
1234
1235 fn signed() -> impl Iterator<Item = Value<'static>> {
1236 vec![
1237 Value::from(-8i8),
1238 Value::from(-16i16),
1239 Value::from(-32i32),
1240 Value::from(-64i64),
1241 Value::from(-1isize),
1242 Value::from(std::num::NonZeroI8::new(-8).unwrap()),
1243 Value::from(std::num::NonZeroI16::new(-16).unwrap()),
1244 Value::from(std::num::NonZeroI32::new(-32).unwrap()),
1245 Value::from(std::num::NonZeroI64::new(-64).unwrap()),
1246 Value::from(std::num::NonZeroIsize::new(-1).unwrap()),
1247 ]
1248 .into_iter()
1249 }
1250
1251 fn float() -> impl Iterator<Item = Value<'static>> {
1252 vec![Value::from(32.32f32), Value::from(64.64f64)].into_iter()
1253 }
1254
1255 fn bool() -> impl Iterator<Item = Value<'static>> {
1256 vec![Value::from(true), Value::from(false)].into_iter()
1257 }
1258
1259 fn str() -> impl Iterator<Item = Value<'static>> {
1260 vec![Value::from("a string"), Value::from("a loong string")].into_iter()
1261 }
1262
1263 fn char() -> impl Iterator<Item = Value<'static>> {
1264 vec![Value::from('a'), Value::from('⛰')].into_iter()
1265 }
1266
1267 #[test]
1268 fn test_to_value_display() {
1269 assert_eq!(42u64.to_value().to_string(), "42");
1270 assert_eq!(42i64.to_value().to_string(), "42");
1271 assert_eq!(42.01f64.to_value().to_string(), "42.01");
1272 assert_eq!(true.to_value().to_string(), "true");
1273 assert_eq!('a'.to_value().to_string(), "a");
1274 assert_eq!("a loong string".to_value().to_string(), "a loong string");
1275 assert_eq!(Some(true).to_value().to_string(), "true");
1276 assert_eq!(().to_value().to_string(), "None");
1277 assert_eq!(None::<bool>.to_value().to_string(), "None");
1278 }
1279
1280 #[test]
1281 #[cfg(feature = "std")]
1282 fn test_net_to_value_display() {
1283 use std::str::FromStr;
1284
1285 assert_eq!(
1286 std::net::Ipv4Addr::new(192, 168, 10, 100)
1287 .to_value()
1288 .to_string(),
1289 "192.168.10.100"
1290 );
1291 assert_eq!(
1292 std::net::Ipv6Addr::from_str("f33c::1")
1293 .unwrap()
1294 .to_value()
1295 .to_string(),
1296 "f33c::1"
1297 );
1298 assert_eq!(
1299 std::net::IpAddr::V4(std::net::Ipv4Addr::new(192, 168, 10, 100))
1300 .to_value()
1301 .to_string(),
1302 "192.168.10.100"
1303 );
1304 assert_eq!(
1305 std::net::IpAddr::V6(std::net::Ipv6Addr::from_str("f33c::1").unwrap())
1306 .to_value()
1307 .to_string(),
1308 "f33c::1"
1309 );
1310 assert_eq!(
1311 std::net::SocketAddrV4::new(std::net::Ipv4Addr::new(192, 168, 10, 100), 12345)
1312 .to_value()
1313 .to_string(),
1314 "192.168.10.100:12345"
1315 );
1316 assert_eq!(
1317 std::net::SocketAddrV6::new(
1318 std::net::Ipv6Addr::from_str("f33c::1").unwrap(),
1319 12345,
1320 0,
1321 0
1322 )
1323 .to_value()
1324 .to_string(),
1325 "[f33c::1]:12345"
1326 );
1327 assert_eq!(
1328 std::net::SocketAddr::V4(std::net::SocketAddrV4::new(
1329 std::net::Ipv4Addr::new(192, 168, 10, 100),
1330 12345
1331 ))
1332 .to_value()
1333 .to_string(),
1334 "192.168.10.100:12345"
1335 );
1336 assert_eq!(
1337 std::net::SocketAddr::V6(std::net::SocketAddrV6::new(
1338 std::net::Ipv6Addr::from_str("f33c::1").unwrap(),
1339 12345,
1340 0,
1341 0
1342 ))
1343 .to_value()
1344 .to_string(),
1345 "[f33c::1]:12345"
1346 );
1347 }
1348
1349 #[test]
1350 fn test_to_value_structured() {
1351 assert_eq!(42u64.to_value().to_token(), inner::Token::U64(42));
1352 assert_eq!(42i64.to_value().to_token(), inner::Token::I64(42));
1353 assert_eq!(42.01f64.to_value().to_token(), inner::Token::F64(42.01));
1354 assert_eq!(true.to_value().to_token(), inner::Token::Bool(true));
1355 assert_eq!('a'.to_value().to_token(), inner::Token::Char('a'));
1356 assert_eq!(
1357 "a loong string".to_value().to_token(),
1358 inner::Token::Str("a loong string".into())
1359 );
1360 assert_eq!(Some(true).to_value().to_token(), inner::Token::Bool(true));
1361 assert_eq!(().to_value().to_token(), inner::Token::None);
1362 assert_eq!(None::<bool>.to_value().to_token(), inner::Token::None);
1363 }
1364
1365 #[test]
1366 fn test_to_number() {
1367 for v in unsigned() {
1368 assert!(v.to_u64().is_some());
1369 assert!(v.to_i64().is_some());
1370 }
1371
1372 for v in signed() {
1373 assert!(v.to_i64().is_some());
1374 }
1375
1376 for v in unsigned().chain(signed()).chain(float()) {
1377 assert!(v.to_f64().is_some());
1378 }
1379
1380 for v in bool().chain(str()).chain(char()) {
1381 assert!(v.to_u64().is_none());
1382 assert!(v.to_i64().is_none());
1383 assert!(v.to_f64().is_none());
1384 }
1385 }
1386
1387 #[test]
1388 fn test_to_float() {
1389 assert!(Value::from(i32::MIN).to_f64().is_some());
1391 assert!(Value::from(u32::MAX).to_f64().is_some());
1392
1393 assert!(Value::from((i32::MIN as i64) - 1).to_f64().is_none());
1394 assert!(Value::from((u32::MAX as u64) + 1).to_f64().is_none());
1395 }
1396
1397 #[test]
1398 fn test_to_cow_str() {
1399 for v in str() {
1400 assert!(v.to_borrowed_str().is_some());
1401
1402 #[cfg(feature = "kv_std")]
1403 assert!(v.to_cow_str().is_some());
1404 }
1405
1406 let short_lived = String::from("short lived");
1407 let v = Value::from(&*short_lived);
1408
1409 assert!(v.to_borrowed_str().is_some());
1410
1411 #[cfg(feature = "kv_std")]
1412 assert!(v.to_cow_str().is_some());
1413
1414 for v in unsigned().chain(signed()).chain(float()).chain(bool()) {
1415 assert!(v.to_borrowed_str().is_none());
1416
1417 #[cfg(feature = "kv_std")]
1418 assert!(v.to_cow_str().is_none());
1419 }
1420 }
1421
1422 #[test]
1423 fn test_to_bool() {
1424 for v in bool() {
1425 assert!(v.to_bool().is_some());
1426 }
1427
1428 for v in unsigned()
1429 .chain(signed())
1430 .chain(float())
1431 .chain(str())
1432 .chain(char())
1433 {
1434 assert!(v.to_bool().is_none());
1435 }
1436 }
1437
1438 #[test]
1439 fn test_to_char() {
1440 for v in char() {
1441 assert!(v.to_char().is_some());
1442 }
1443
1444 for v in unsigned()
1445 .chain(signed())
1446 .chain(float())
1447 .chain(str())
1448 .chain(bool())
1449 {
1450 assert!(v.to_char().is_none());
1451 }
1452 }
1453
1454 #[test]
1455 fn test_visit_integer() {
1456 struct Extract(Option<u64>);
1457
1458 impl<'v> VisitValue<'v> for Extract {
1459 fn visit_any(&mut self, value: Value) -> Result<(), Error> {
1460 unimplemented!("unexpected value: {value:?}")
1461 }
1462
1463 fn visit_u64(&mut self, value: u64) -> Result<(), Error> {
1464 self.0 = Some(value);
1465
1466 Ok(())
1467 }
1468 }
1469
1470 let mut extract = Extract(None);
1471 Value::from(42u64).visit(&mut extract).unwrap();
1472
1473 assert_eq!(Some(42), extract.0);
1474 }
1475
1476 #[test]
1477 fn test_visit_borrowed_str() {
1478 struct Extract<'v>(Option<&'v str>);
1479
1480 impl<'v> VisitValue<'v> for Extract<'v> {
1481 fn visit_any(&mut self, value: Value) -> Result<(), Error> {
1482 unimplemented!("unexpected value: {value:?}")
1483 }
1484
1485 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> {
1486 self.0 = Some(value);
1487
1488 Ok(())
1489 }
1490 }
1491
1492 let mut extract = Extract(None);
1493
1494 let short_lived = String::from("A short-lived string");
1495 Value::from(&*short_lived).visit(&mut extract).unwrap();
1496
1497 assert_eq!(Some("A short-lived string"), extract.0);
1498 }
1499}