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