1use crate::callsite;
113use crate::stdlib::{
114    borrow::Borrow,
115    fmt,
116    hash::{Hash, Hasher},
117    num,
118    ops::Range,
119    string::String,
120};
121
122use self::private::ValidLen;
123
124#[derive(Debug)]
133pub struct Field {
134    i: usize,
135    fields: FieldSet,
136}
137
138#[derive(Debug, Eq, PartialEq)]
145pub struct Empty;
146
147pub struct FieldSet {
159    names: &'static [&'static str],
161    callsite: callsite::Identifier,
163}
164
165pub struct ValueSet<'a> {
167    values: &'a [(&'a Field, Option<&'a (dyn Value + 'a)>)],
168    fields: &'a FieldSet,
169}
170
171#[derive(Debug)]
173pub struct Iter {
174    idxs: Range<usize>,
175    fields: FieldSet,
176}
177
178pub trait Visit {
267    #[cfg(all(tracing_unstable, feature = "valuable"))]
271    #[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
272    fn record_value(&mut self, field: &Field, value: valuable::Value<'_>) {
273        self.record_debug(field, &value)
274    }
275
276    fn record_f64(&mut self, field: &Field, value: f64) {
278        self.record_debug(field, &value)
279    }
280
281    fn record_i64(&mut self, field: &Field, value: i64) {
283        self.record_debug(field, &value)
284    }
285
286    fn record_u64(&mut self, field: &Field, value: u64) {
288        self.record_debug(field, &value)
289    }
290
291    fn record_i128(&mut self, field: &Field, value: i128) {
293        self.record_debug(field, &value)
294    }
295
296    fn record_u128(&mut self, field: &Field, value: u128) {
298        self.record_debug(field, &value)
299    }
300
301    fn record_bool(&mut self, field: &Field, value: bool) {
303        self.record_debug(field, &value)
304    }
305
306    fn record_str(&mut self, field: &Field, value: &str) {
308        self.record_debug(field, &value)
309    }
310
311    #[cfg(feature = "std")]
320    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
321    fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) {
322        self.record_debug(field, &DisplayValue(value))
323    }
324
325    fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug);
327}
328
329pub trait Value: crate::sealed::Sealed {
337    fn record(&self, key: &Field, visitor: &mut dyn Visit);
339}
340
341#[derive(Clone)]
346pub struct DisplayValue<T: fmt::Display>(T);
347
348#[derive(Clone)]
350pub struct DebugValue<T: fmt::Debug>(T);
351
352pub fn display<T>(t: T) -> DisplayValue<T>
355where
356    T: fmt::Display,
357{
358    DisplayValue(t)
359}
360
361pub fn debug<T>(t: T) -> DebugValue<T>
364where
365    T: fmt::Debug,
366{
367    DebugValue(t)
368}
369
370#[cfg(all(tracing_unstable, feature = "valuable"))]
375#[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
376pub fn valuable<T>(t: &T) -> valuable::Value<'_>
377where
378    T: valuable::Valuable,
379{
380    t.as_value()
381}
382
383impl<'a, 'b> Visit for fmt::DebugStruct<'a, 'b> {
386    fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
387        self.field(field.name(), value);
388    }
389}
390
391impl<'a, 'b> Visit for fmt::DebugMap<'a, 'b> {
392    fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
393        self.entry(&format_args!("{}", field), value);
394    }
395}
396
397impl<F> Visit for F
398where
399    F: FnMut(&Field, &dyn fmt::Debug),
400{
401    fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
402        (self)(field, value)
403    }
404}
405
406macro_rules! impl_values {
409    ( $( $record:ident( $( $whatever:tt)+ ) ),+ ) => {
410        $(
411            impl_value!{ $record( $( $whatever )+ ) }
412        )+
413    }
414}
415
416macro_rules! ty_to_nonzero {
417    (u8) => {
418        NonZeroU8
419    };
420    (u16) => {
421        NonZeroU16
422    };
423    (u32) => {
424        NonZeroU32
425    };
426    (u64) => {
427        NonZeroU64
428    };
429    (u128) => {
430        NonZeroU128
431    };
432    (usize) => {
433        NonZeroUsize
434    };
435    (i8) => {
436        NonZeroI8
437    };
438    (i16) => {
439        NonZeroI16
440    };
441    (i32) => {
442        NonZeroI32
443    };
444    (i64) => {
445        NonZeroI64
446    };
447    (i128) => {
448        NonZeroI128
449    };
450    (isize) => {
451        NonZeroIsize
452    };
453}
454
455macro_rules! impl_one_value {
456    (f32, $op:expr, $record:ident) => {
457        impl_one_value!(normal, f32, $op, $record);
458    };
459    (f64, $op:expr, $record:ident) => {
460        impl_one_value!(normal, f64, $op, $record);
461    };
462    (bool, $op:expr, $record:ident) => {
463        impl_one_value!(normal, bool, $op, $record);
464    };
465    ($value_ty:tt, $op:expr, $record:ident) => {
466        impl_one_value!(normal, $value_ty, $op, $record);
467        impl_one_value!(nonzero, $value_ty, $op, $record);
468    };
469    (normal, $value_ty:tt, $op:expr, $record:ident) => {
470        impl $crate::sealed::Sealed for $value_ty {}
471        impl $crate::field::Value for $value_ty {
472            fn record(&self, key: &$crate::field::Field, visitor: &mut dyn $crate::field::Visit) {
473                #[allow(clippy::redundant_closure_call)]
477                visitor.$record(key, $op(*self))
478            }
479        }
480    };
481    (nonzero, $value_ty:tt, $op:expr, $record:ident) => {
482        #[allow(clippy::useless_attribute, unused)]
488        use num::*;
489        impl $crate::sealed::Sealed for ty_to_nonzero!($value_ty) {}
490        impl $crate::field::Value for ty_to_nonzero!($value_ty) {
491            fn record(&self, key: &$crate::field::Field, visitor: &mut dyn $crate::field::Visit) {
492                #[allow(clippy::redundant_closure_call)]
496                visitor.$record(key, $op(self.get()))
497            }
498        }
499    };
500}
501
502macro_rules! impl_value {
503    ( $record:ident( $( $value_ty:tt ),+ ) ) => {
504        $(
505            impl_one_value!($value_ty, |this: $value_ty| this, $record);
506        )+
507    };
508    ( $record:ident( $( $value_ty:tt ),+ as $as_ty:ty) ) => {
509        $(
510            impl_one_value!($value_ty, |this: $value_ty| this as $as_ty, $record);
511        )+
512    };
513}
514
515impl_values! {
518    record_u64(u64),
519    record_u64(usize, u32, u16, u8 as u64),
520    record_i64(i64),
521    record_i64(isize, i32, i16, i8 as i64),
522    record_u128(u128),
523    record_i128(i128),
524    record_bool(bool),
525    record_f64(f64, f32 as f64)
526}
527
528impl<T: crate::sealed::Sealed> crate::sealed::Sealed for Wrapping<T> {}
529impl<T: crate::field::Value> crate::field::Value for Wrapping<T> {
530    fn record(&self, key: &crate::field::Field, visitor: &mut dyn crate::field::Visit) {
531        self.0.record(key, visitor)
532    }
533}
534
535impl crate::sealed::Sealed for str {}
536
537impl Value for str {
538    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
539        visitor.record_str(key, self)
540    }
541}
542
543#[cfg(feature = "std")]
544impl crate::sealed::Sealed for dyn std::error::Error + 'static {}
545
546#[cfg(feature = "std")]
547#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
548impl Value for dyn std::error::Error + 'static {
549    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
550        visitor.record_error(key, self)
551    }
552}
553
554#[cfg(feature = "std")]
555impl crate::sealed::Sealed for dyn std::error::Error + Send + 'static {}
556
557#[cfg(feature = "std")]
558#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
559impl Value for dyn std::error::Error + Send + 'static {
560    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
561        (self as &dyn std::error::Error).record(key, visitor)
562    }
563}
564
565#[cfg(feature = "std")]
566impl crate::sealed::Sealed for dyn std::error::Error + Sync + 'static {}
567
568#[cfg(feature = "std")]
569#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
570impl Value for dyn std::error::Error + Sync + 'static {
571    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
572        (self as &dyn std::error::Error).record(key, visitor)
573    }
574}
575
576#[cfg(feature = "std")]
577impl crate::sealed::Sealed for dyn std::error::Error + Send + Sync + 'static {}
578
579#[cfg(feature = "std")]
580#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
581impl Value for dyn std::error::Error + Send + Sync + 'static {
582    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
583        (self as &dyn std::error::Error).record(key, visitor)
584    }
585}
586
587impl<'a, T: ?Sized> crate::sealed::Sealed for &'a T where T: Value + crate::sealed::Sealed + 'a {}
588
589impl<'a, T: ?Sized> Value for &'a T
590where
591    T: Value + 'a,
592{
593    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
594        (*self).record(key, visitor)
595    }
596}
597
598impl<'a, T: ?Sized> crate::sealed::Sealed for &'a mut T where T: Value + crate::sealed::Sealed + 'a {}
599
600impl<'a, T: ?Sized> Value for &'a mut T
601where
602    T: Value + 'a,
603{
604    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
605        T::record(self, key, visitor)
608    }
609}
610
611impl<'a> crate::sealed::Sealed for fmt::Arguments<'a> {}
612
613impl<'a> Value for fmt::Arguments<'a> {
614    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
615        visitor.record_debug(key, self)
616    }
617}
618
619impl<T: ?Sized> crate::sealed::Sealed for crate::stdlib::boxed::Box<T> where T: Value {}
620
621impl<T: ?Sized> Value for crate::stdlib::boxed::Box<T>
622where
623    T: Value,
624{
625    #[inline]
626    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
627        self.as_ref().record(key, visitor)
628    }
629}
630
631impl crate::sealed::Sealed for String {}
632impl Value for String {
633    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
634        visitor.record_str(key, self.as_str())
635    }
636}
637
638impl fmt::Debug for dyn Value {
639    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
640        struct NullCallsite;
643        static NULL_CALLSITE: NullCallsite = NullCallsite;
644        impl crate::callsite::Callsite for NullCallsite {
645            fn set_interest(&self, _: crate::subscriber::Interest) {
646                unreachable!("you somehow managed to register the null callsite?")
647            }
648
649            fn metadata(&self) -> &crate::Metadata<'_> {
650                unreachable!("you somehow managed to access the null callsite?")
651            }
652        }
653
654        static FIELD: Field = Field {
655            i: 0,
656            fields: FieldSet::new(&[], crate::identify_callsite!(&NULL_CALLSITE)),
657        };
658
659        let mut res = Ok(());
660        self.record(&FIELD, &mut |_: &Field, val: &dyn fmt::Debug| {
661            res = write!(f, "{:?}", val);
662        });
663        res
664    }
665}
666
667impl fmt::Display for dyn Value {
668    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
669        fmt::Debug::fmt(self, f)
670    }
671}
672
673impl<T: fmt::Display> crate::sealed::Sealed for DisplayValue<T> {}
676
677impl<T> Value for DisplayValue<T>
678where
679    T: fmt::Display,
680{
681    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
682        visitor.record_debug(key, self)
683    }
684}
685
686impl<T: fmt::Display> fmt::Debug for DisplayValue<T> {
687    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
688        fmt::Display::fmt(self, f)
689    }
690}
691
692impl<T: fmt::Display> fmt::Display for DisplayValue<T> {
693    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
694        self.0.fmt(f)
695    }
696}
697
698impl<T: fmt::Debug> crate::sealed::Sealed for DebugValue<T> {}
701
702impl<T> Value for DebugValue<T>
703where
704    T: fmt::Debug,
705{
706    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
707        visitor.record_debug(key, &self.0)
708    }
709}
710
711impl<T: fmt::Debug> fmt::Debug for DebugValue<T> {
712    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
713        self.0.fmt(f)
714    }
715}
716
717#[cfg(all(tracing_unstable, feature = "valuable"))]
720impl crate::sealed::Sealed for valuable::Value<'_> {}
721
722#[cfg(all(tracing_unstable, feature = "valuable"))]
723#[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
724impl Value for valuable::Value<'_> {
725    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
726        visitor.record_value(key, *self)
727    }
728}
729
730#[cfg(all(tracing_unstable, feature = "valuable"))]
731impl crate::sealed::Sealed for &'_ dyn valuable::Valuable {}
732
733#[cfg(all(tracing_unstable, feature = "valuable"))]
734#[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
735impl Value for &'_ dyn valuable::Valuable {
736    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
737        visitor.record_value(key, self.as_value())
738    }
739}
740
741impl crate::sealed::Sealed for Empty {}
742impl Value for Empty {
743    #[inline]
744    fn record(&self, _: &Field, _: &mut dyn Visit) {}
745}
746
747impl<T: Value> crate::sealed::Sealed for Option<T> {}
748
749impl<T: Value> Value for Option<T> {
750    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
751        if let Some(v) = &self {
752            v.record(key, visitor)
753        }
754    }
755}
756
757impl Field {
760    #[inline]
766    pub fn callsite(&self) -> callsite::Identifier {
767        self.fields.callsite()
768    }
769
770    pub fn name(&self) -> &'static str {
772        self.fields.names[self.i]
773    }
774}
775
776impl fmt::Display for Field {
777    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
778        f.pad(self.name())
779    }
780}
781
782impl AsRef<str> for Field {
783    fn as_ref(&self) -> &str {
784        self.name()
785    }
786}
787
788impl PartialEq for Field {
789    fn eq(&self, other: &Self) -> bool {
790        self.callsite() == other.callsite() && self.i == other.i
791    }
792}
793
794impl Eq for Field {}
795
796impl Hash for Field {
797    fn hash<H>(&self, state: &mut H)
798    where
799        H: Hasher,
800    {
801        self.callsite().hash(state);
802        self.i.hash(state);
803    }
804}
805
806impl Clone for Field {
807    fn clone(&self) -> Self {
808        Field {
809            i: self.i,
810            fields: FieldSet {
811                names: self.fields.names,
812                callsite: self.fields.callsite(),
813            },
814        }
815    }
816}
817
818impl FieldSet {
821    pub const fn new(names: &'static [&'static str], callsite: callsite::Identifier) -> Self {
823        Self { names, callsite }
824    }
825
826    #[inline]
832    pub(crate) fn callsite(&self) -> callsite::Identifier {
833        callsite::Identifier(self.callsite.0)
834    }
835
836    pub fn field<Q: ?Sized>(&self, name: &Q) -> Option<Field>
840    where
841        Q: Borrow<str>,
842    {
843        let name = &name.borrow();
844        self.names.iter().position(|f| f == name).map(|i| Field {
845            i,
846            fields: FieldSet {
847                names: self.names,
848                callsite: self.callsite(),
849            },
850        })
851    }
852
853    pub fn contains(&self, field: &Field) -> bool {
865        field.callsite() == self.callsite() && field.i <= self.len()
866    }
867
868    #[inline]
870    pub fn iter(&self) -> Iter {
871        let idxs = 0..self.len();
872        Iter {
873            idxs,
874            fields: FieldSet {
875                names: self.names,
876                callsite: self.callsite(),
877            },
878        }
879    }
880
881    #[doc(hidden)]
883    pub fn value_set<'v, V>(&'v self, values: &'v V) -> ValueSet<'v>
884    where
885        V: ValidLen<'v>,
886    {
887        ValueSet {
888            fields: self,
889            values: values.borrow(),
890        }
891    }
892
893    #[inline]
895    pub fn len(&self) -> usize {
896        self.names.len()
897    }
898
899    #[inline]
901    pub fn is_empty(&self) -> bool {
902        self.names.is_empty()
903    }
904}
905
906impl<'a> IntoIterator for &'a FieldSet {
907    type IntoIter = Iter;
908    type Item = Field;
909    #[inline]
910    fn into_iter(self) -> Self::IntoIter {
911        self.iter()
912    }
913}
914
915impl fmt::Debug for FieldSet {
916    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
917        f.debug_struct("FieldSet")
918            .field("names", &self.names)
919            .field("callsite", &self.callsite)
920            .finish()
921    }
922}
923
924impl fmt::Display for FieldSet {
925    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
926        f.debug_set()
927            .entries(self.names.iter().map(display))
928            .finish()
929    }
930}
931
932impl Eq for FieldSet {}
933
934impl PartialEq for FieldSet {
935    fn eq(&self, other: &Self) -> bool {
936        if core::ptr::eq(&self, &other) {
937            true
938        } else if cfg!(not(debug_assertions)) {
939            self.callsite == other.callsite
942        } else {
943            let Self {
950                names: lhs_names,
951                callsite: lhs_callsite,
952            } = self;
953
954            let Self {
955                names: rhs_names,
956                callsite: rhs_callsite,
957            } = &other;
958
959            lhs_callsite == rhs_callsite && lhs_names == rhs_names
962        }
963    }
964}
965
966impl Iterator for Iter {
969    type Item = Field;
970    #[inline]
971    fn next(&mut self) -> Option<Field> {
972        let i = self.idxs.next()?;
973        Some(Field {
974            i,
975            fields: FieldSet {
976                names: self.fields.names,
977                callsite: self.fields.callsite(),
978            },
979        })
980    }
981}
982
983impl<'a> ValueSet<'a> {
986    #[inline]
992    pub fn callsite(&self) -> callsite::Identifier {
993        self.fields.callsite()
994    }
995
996    pub fn record(&self, visitor: &mut dyn Visit) {
1000        let my_callsite = self.callsite();
1001        for (field, value) in self.values {
1002            if field.callsite() != my_callsite {
1003                continue;
1004            }
1005            if let Some(value) = value {
1006                value.record(field, visitor);
1007            }
1008        }
1009    }
1010
1011    pub fn len(&self) -> usize {
1017        let my_callsite = self.callsite();
1018        self.values
1019            .iter()
1020            .filter(|(field, _)| field.callsite() == my_callsite)
1021            .count()
1022    }
1023
1024    pub(crate) fn contains(&self, field: &Field) -> bool {
1026        field.callsite() == self.callsite()
1027            && self
1028                .values
1029                .iter()
1030                .any(|(key, val)| *key == field && val.is_some())
1031    }
1032
1033    pub fn is_empty(&self) -> bool {
1035        let my_callsite = self.callsite();
1036        self.values
1037            .iter()
1038            .all(|(key, val)| val.is_none() || key.callsite() != my_callsite)
1039    }
1040
1041    pub(crate) fn field_set(&self) -> &FieldSet {
1042        self.fields
1043    }
1044}
1045
1046impl<'a> fmt::Debug for ValueSet<'a> {
1047    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1048        self.values
1049            .iter()
1050            .fold(&mut f.debug_struct("ValueSet"), |dbg, (key, v)| {
1051                if let Some(val) = v {
1052                    val.record(key, dbg);
1053                }
1054                dbg
1055            })
1056            .field("callsite", &self.callsite())
1057            .finish()
1058    }
1059}
1060
1061impl<'a> fmt::Display for ValueSet<'a> {
1062    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1063        self.values
1064            .iter()
1065            .fold(&mut f.debug_map(), |dbg, (key, v)| {
1066                if let Some(val) = v {
1067                    val.record(key, dbg);
1068                }
1069                dbg
1070            })
1071            .finish()
1072    }
1073}
1074
1075mod private {
1078    use super::*;
1079
1080    pub trait ValidLen<'a>: Borrow<[(&'a Field, Option<&'a (dyn Value + 'a)>)]> {}
1082
1083    impl<'a, const N: usize> ValidLen<'a> for [(&'a Field, Option<&'a (dyn Value + 'a)>); N] {}
1084}
1085
1086#[cfg(test)]
1087mod test {
1088    use super::*;
1089    use crate::metadata::{Kind, Level, Metadata};
1090    use crate::stdlib::{borrow::ToOwned, string::String};
1091
1092    struct TestCallsite1(u8);
1094    static TEST_CALLSITE_1: TestCallsite1 = TestCallsite1(0);
1095    static TEST_META_1: Metadata<'static> = metadata! {
1096        name: "field_test1",
1097        target: module_path!(),
1098        level: Level::INFO,
1099        fields: &["foo", "bar", "baz"],
1100        callsite: &TEST_CALLSITE_1,
1101        kind: Kind::SPAN,
1102    };
1103
1104    impl crate::callsite::Callsite for TestCallsite1 {
1105        fn set_interest(&self, _: crate::subscriber::Interest) {
1106            unimplemented!()
1107        }
1108
1109        fn metadata(&self) -> &Metadata<'_> {
1110            &TEST_META_1
1111        }
1112    }
1113
1114    struct TestCallsite2(u8);
1115    static TEST_CALLSITE_2: TestCallsite2 = TestCallsite2(0);
1116    static TEST_META_2: Metadata<'static> = metadata! {
1117        name: "field_test2",
1118        target: module_path!(),
1119        level: Level::INFO,
1120        fields: &["foo", "bar", "baz"],
1121        callsite: &TEST_CALLSITE_2,
1122        kind: Kind::SPAN,
1123    };
1124
1125    impl crate::callsite::Callsite for TestCallsite2 {
1126        fn set_interest(&self, _: crate::subscriber::Interest) {
1127            unimplemented!()
1128        }
1129
1130        fn metadata(&self) -> &Metadata<'_> {
1131            &TEST_META_2
1132        }
1133    }
1134
1135    #[test]
1136    fn value_set_with_no_values_is_empty() {
1137        let fields = TEST_META_1.fields();
1138        let values = &[
1139            (&fields.field("foo").unwrap(), None),
1140            (&fields.field("bar").unwrap(), None),
1141            (&fields.field("baz").unwrap(), None),
1142        ];
1143        let valueset = fields.value_set(values);
1144        assert!(valueset.is_empty());
1145    }
1146
1147    #[test]
1148    fn empty_value_set_is_empty() {
1149        let fields = TEST_META_1.fields();
1150        let valueset = fields.value_set(&[]);
1151        assert!(valueset.is_empty());
1152    }
1153
1154    #[test]
1155    fn value_sets_with_fields_from_other_callsites_are_empty() {
1156        let fields = TEST_META_1.fields();
1157        let values = &[
1158            (&fields.field("foo").unwrap(), Some(&1 as &dyn Value)),
1159            (&fields.field("bar").unwrap(), Some(&2 as &dyn Value)),
1160            (&fields.field("baz").unwrap(), Some(&3 as &dyn Value)),
1161        ];
1162        let valueset = TEST_META_2.fields().value_set(values);
1163        assert!(valueset.is_empty())
1164    }
1165
1166    #[test]
1167    fn sparse_value_sets_are_not_empty() {
1168        let fields = TEST_META_1.fields();
1169        let values = &[
1170            (&fields.field("foo").unwrap(), None),
1171            (&fields.field("bar").unwrap(), Some(&57 as &dyn Value)),
1172            (&fields.field("baz").unwrap(), None),
1173        ];
1174        let valueset = fields.value_set(values);
1175        assert!(!valueset.is_empty());
1176    }
1177
1178    #[test]
1179    fn fields_from_other_callsets_are_skipped() {
1180        let fields = TEST_META_1.fields();
1181        let values = &[
1182            (&fields.field("foo").unwrap(), None),
1183            (
1184                &TEST_META_2.fields().field("bar").unwrap(),
1185                Some(&57 as &dyn Value),
1186            ),
1187            (&fields.field("baz").unwrap(), None),
1188        ];
1189
1190        struct MyVisitor;
1191        impl Visit for MyVisitor {
1192            fn record_debug(&mut self, field: &Field, _: &dyn (crate::stdlib::fmt::Debug)) {
1193                assert_eq!(field.callsite(), TEST_META_1.callsite())
1194            }
1195        }
1196        let valueset = fields.value_set(values);
1197        valueset.record(&mut MyVisitor);
1198    }
1199
1200    #[test]
1201    fn empty_fields_are_skipped() {
1202        let fields = TEST_META_1.fields();
1203        let values = &[
1204            (&fields.field("foo").unwrap(), Some(&Empty as &dyn Value)),
1205            (&fields.field("bar").unwrap(), Some(&57 as &dyn Value)),
1206            (&fields.field("baz").unwrap(), Some(&Empty as &dyn Value)),
1207        ];
1208
1209        struct MyVisitor;
1210        impl Visit for MyVisitor {
1211            fn record_debug(&mut self, field: &Field, _: &dyn (crate::stdlib::fmt::Debug)) {
1212                assert_eq!(field.name(), "bar")
1213            }
1214        }
1215        let valueset = fields.value_set(values);
1216        valueset.record(&mut MyVisitor);
1217    }
1218
1219    #[test]
1220    fn record_debug_fn() {
1221        let fields = TEST_META_1.fields();
1222        let values = &[
1223            (&fields.field("foo").unwrap(), Some(&1 as &dyn Value)),
1224            (&fields.field("bar").unwrap(), Some(&2 as &dyn Value)),
1225            (&fields.field("baz").unwrap(), Some(&3 as &dyn Value)),
1226        ];
1227        let valueset = fields.value_set(values);
1228        let mut result = String::new();
1229        valueset.record(&mut |_: &Field, value: &dyn fmt::Debug| {
1230            use crate::stdlib::fmt::Write;
1231            write!(&mut result, "{:?}", value).unwrap();
1232        });
1233        assert_eq!(result, "123".to_owned());
1234    }
1235
1236    #[test]
1237    #[cfg(feature = "std")]
1238    fn record_error() {
1239        let fields = TEST_META_1.fields();
1240        let err: Box<dyn std::error::Error + Send + Sync + 'static> =
1241            std::io::Error::new(std::io::ErrorKind::Other, "lol").into();
1242        let values = &[
1243            (&fields.field("foo").unwrap(), Some(&err as &dyn Value)),
1244            (&fields.field("bar").unwrap(), Some(&Empty as &dyn Value)),
1245            (&fields.field("baz").unwrap(), Some(&Empty as &dyn Value)),
1246        ];
1247        let valueset = fields.value_set(values);
1248        let mut result = String::new();
1249        valueset.record(&mut |_: &Field, value: &dyn fmt::Debug| {
1250            use core::fmt::Write;
1251            write!(&mut result, "{:?}", value).unwrap();
1252        });
1253        assert_eq!(result, format!("{}", err));
1254    }
1255}