1use crate::callsite;
113use crate::stdlib::{
114    borrow::Borrow,
115    fmt::{self, Write},
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    fn record_bytes(&mut self, field: &Field, value: &[u8]) {
313        self.record_debug(field, &HexBytes(value))
314    }
315
316    #[cfg(feature = "std")]
325    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
326    fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) {
327        self.record_debug(field, &DisplayValue(value))
328    }
329
330    fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug);
332}
333
334pub trait Value: crate::sealed::Sealed {
342    fn record(&self, key: &Field, visitor: &mut dyn Visit);
344}
345
346#[derive(Clone)]
351pub struct DisplayValue<T: fmt::Display>(T);
352
353#[derive(Clone)]
355pub struct DebugValue<T: fmt::Debug>(T);
356
357pub fn display<T>(t: T) -> DisplayValue<T>
360where
361    T: fmt::Display,
362{
363    DisplayValue(t)
364}
365
366pub fn debug<T>(t: T) -> DebugValue<T>
369where
370    T: fmt::Debug,
371{
372    DebugValue(t)
373}
374
375#[cfg(all(tracing_unstable, feature = "valuable"))]
380#[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
381pub fn valuable<T>(t: &T) -> valuable::Value<'_>
382where
383    T: valuable::Valuable,
384{
385    t.as_value()
386}
387
388struct HexBytes<'a>(&'a [u8]);
389
390impl fmt::Debug for HexBytes<'_> {
391    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
392        f.write_char('[')?;
393
394        let mut bytes = self.0.iter();
395
396        if let Some(byte) = bytes.next() {
397            f.write_fmt(format_args!("{byte:02x}"))?;
398        }
399
400        for byte in bytes {
401            f.write_fmt(format_args!(" {byte:02x}"))?;
402        }
403
404        f.write_char(']')
405    }
406}
407
408impl Visit for fmt::DebugStruct<'_, '_> {
411    fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
412        self.field(field.name(), value);
413    }
414}
415
416impl Visit for fmt::DebugMap<'_, '_> {
417    fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
418        self.entry(&format_args!("{}", field), value);
419    }
420}
421
422impl<F> Visit for F
423where
424    F: FnMut(&Field, &dyn fmt::Debug),
425{
426    fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
427        (self)(field, value)
428    }
429}
430
431macro_rules! impl_values {
434    ( $( $record:ident( $( $whatever:tt)+ ) ),+ ) => {
435        $(
436            impl_value!{ $record( $( $whatever )+ ) }
437        )+
438    }
439}
440
441macro_rules! ty_to_nonzero {
442    (u8) => {
443        NonZeroU8
444    };
445    (u16) => {
446        NonZeroU16
447    };
448    (u32) => {
449        NonZeroU32
450    };
451    (u64) => {
452        NonZeroU64
453    };
454    (u128) => {
455        NonZeroU128
456    };
457    (usize) => {
458        NonZeroUsize
459    };
460    (i8) => {
461        NonZeroI8
462    };
463    (i16) => {
464        NonZeroI16
465    };
466    (i32) => {
467        NonZeroI32
468    };
469    (i64) => {
470        NonZeroI64
471    };
472    (i128) => {
473        NonZeroI128
474    };
475    (isize) => {
476        NonZeroIsize
477    };
478}
479
480macro_rules! impl_one_value {
481    (f32, $op:expr, $record:ident) => {
482        impl_one_value!(normal, f32, $op, $record);
483    };
484    (f64, $op:expr, $record:ident) => {
485        impl_one_value!(normal, f64, $op, $record);
486    };
487    (bool, $op:expr, $record:ident) => {
488        impl_one_value!(normal, bool, $op, $record);
489    };
490    ($value_ty:tt, $op:expr, $record:ident) => {
491        impl_one_value!(normal, $value_ty, $op, $record);
492        impl_one_value!(nonzero, $value_ty, $op, $record);
493    };
494    (normal, $value_ty:tt, $op:expr, $record:ident) => {
495        impl $crate::sealed::Sealed for $value_ty {}
496        impl $crate::field::Value for $value_ty {
497            fn record(&self, key: &$crate::field::Field, visitor: &mut dyn $crate::field::Visit) {
498                #[allow(clippy::redundant_closure_call)]
502                visitor.$record(key, $op(*self))
503            }
504        }
505    };
506    (nonzero, $value_ty:tt, $op:expr, $record:ident) => {
507        #[allow(clippy::useless_attribute, unused)]
513        use num::*;
514        impl $crate::sealed::Sealed for ty_to_nonzero!($value_ty) {}
515        impl $crate::field::Value for ty_to_nonzero!($value_ty) {
516            fn record(&self, key: &$crate::field::Field, visitor: &mut dyn $crate::field::Visit) {
517                #[allow(clippy::redundant_closure_call)]
521                visitor.$record(key, $op(self.get()))
522            }
523        }
524    };
525}
526
527macro_rules! impl_value {
528    ( $record:ident( $( $value_ty:tt ),+ ) ) => {
529        $(
530            impl_one_value!($value_ty, |this: $value_ty| this, $record);
531        )+
532    };
533    ( $record:ident( $( $value_ty:tt ),+ as $as_ty:ty) ) => {
534        $(
535            impl_one_value!($value_ty, |this: $value_ty| this as $as_ty, $record);
536        )+
537    };
538}
539
540impl_values! {
543    record_u64(u64),
544    record_u64(usize, u32, u16, u8 as u64),
545    record_i64(i64),
546    record_i64(isize, i32, i16, i8 as i64),
547    record_u128(u128),
548    record_i128(i128),
549    record_bool(bool),
550    record_f64(f64, f32 as f64)
551}
552
553impl<T: crate::sealed::Sealed> crate::sealed::Sealed for Wrapping<T> {}
554impl<T: crate::field::Value> crate::field::Value for Wrapping<T> {
555    fn record(&self, key: &crate::field::Field, visitor: &mut dyn crate::field::Visit) {
556        self.0.record(key, visitor)
557    }
558}
559
560impl crate::sealed::Sealed for str {}
561
562impl Value for str {
563    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
564        visitor.record_str(key, self)
565    }
566}
567
568impl crate::sealed::Sealed for [u8] {}
569
570impl Value for [u8] {
571    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
572        visitor.record_bytes(key, self)
573    }
574}
575
576#[cfg(feature = "std")]
577impl crate::sealed::Sealed for dyn std::error::Error + 'static {}
578
579#[cfg(feature = "std")]
580#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
581impl Value for dyn std::error::Error + 'static {
582    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
583        visitor.record_error(key, self)
584    }
585}
586
587#[cfg(feature = "std")]
588impl crate::sealed::Sealed for dyn std::error::Error + Send + 'static {}
589
590#[cfg(feature = "std")]
591#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
592impl Value for dyn std::error::Error + Send + 'static {
593    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
594        (self as &dyn std::error::Error).record(key, visitor)
595    }
596}
597
598#[cfg(feature = "std")]
599impl crate::sealed::Sealed for dyn std::error::Error + Sync + 'static {}
600
601#[cfg(feature = "std")]
602#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
603impl Value for dyn std::error::Error + Sync + 'static {
604    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
605        (self as &dyn std::error::Error).record(key, visitor)
606    }
607}
608
609#[cfg(feature = "std")]
610impl crate::sealed::Sealed for dyn std::error::Error + Send + Sync + 'static {}
611
612#[cfg(feature = "std")]
613#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
614impl Value for dyn std::error::Error + Send + Sync + 'static {
615    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
616        (self as &dyn std::error::Error).record(key, visitor)
617    }
618}
619
620impl<'a, T: ?Sized> crate::sealed::Sealed for &'a T where T: Value + crate::sealed::Sealed + 'a {}
621
622impl<'a, T: ?Sized> Value for &'a T
623where
624    T: Value + 'a,
625{
626    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
627        (*self).record(key, visitor)
628    }
629}
630
631impl<'a, T: ?Sized> crate::sealed::Sealed for &'a mut T where T: Value + crate::sealed::Sealed + 'a {}
632
633impl<'a, T: ?Sized> Value for &'a mut T
634where
635    T: Value + 'a,
636{
637    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
638        T::record(self, key, visitor)
641    }
642}
643
644impl crate::sealed::Sealed for fmt::Arguments<'_> {}
645
646impl Value for fmt::Arguments<'_> {
647    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
648        visitor.record_debug(key, self)
649    }
650}
651
652impl<T: ?Sized> crate::sealed::Sealed for crate::stdlib::boxed::Box<T> where T: Value {}
653
654impl<T: ?Sized> Value for crate::stdlib::boxed::Box<T>
655where
656    T: Value,
657{
658    #[inline]
659    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
660        self.as_ref().record(key, visitor)
661    }
662}
663
664impl crate::sealed::Sealed for String {}
665impl Value for String {
666    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
667        visitor.record_str(key, self.as_str())
668    }
669}
670
671impl fmt::Debug for dyn Value {
672    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
673        struct NullCallsite;
676        static NULL_CALLSITE: NullCallsite = NullCallsite;
677        impl crate::callsite::Callsite for NullCallsite {
678            fn set_interest(&self, _: crate::subscriber::Interest) {
679                unreachable!("you somehow managed to register the null callsite?")
680            }
681
682            fn metadata(&self) -> &crate::Metadata<'_> {
683                unreachable!("you somehow managed to access the null callsite?")
684            }
685        }
686
687        static FIELD: Field = Field {
688            i: 0,
689            fields: FieldSet::new(&[], crate::identify_callsite!(&NULL_CALLSITE)),
690        };
691
692        let mut res = Ok(());
693        self.record(&FIELD, &mut |_: &Field, val: &dyn fmt::Debug| {
694            res = write!(f, "{:?}", val);
695        });
696        res
697    }
698}
699
700impl fmt::Display for dyn Value {
701    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
702        fmt::Debug::fmt(self, f)
703    }
704}
705
706impl<T: fmt::Display> crate::sealed::Sealed for DisplayValue<T> {}
709
710impl<T> Value for DisplayValue<T>
711where
712    T: fmt::Display,
713{
714    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
715        visitor.record_debug(key, self)
716    }
717}
718
719impl<T: fmt::Display> fmt::Debug for DisplayValue<T> {
720    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
721        fmt::Display::fmt(self, f)
722    }
723}
724
725impl<T: fmt::Display> fmt::Display for DisplayValue<T> {
726    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
727        self.0.fmt(f)
728    }
729}
730
731impl<T: fmt::Debug> crate::sealed::Sealed for DebugValue<T> {}
734
735impl<T> Value for DebugValue<T>
736where
737    T: fmt::Debug,
738{
739    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
740        visitor.record_debug(key, &self.0)
741    }
742}
743
744impl<T: fmt::Debug> fmt::Debug for DebugValue<T> {
745    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
746        self.0.fmt(f)
747    }
748}
749
750#[cfg(all(tracing_unstable, feature = "valuable"))]
753impl crate::sealed::Sealed for valuable::Value<'_> {}
754
755#[cfg(all(tracing_unstable, feature = "valuable"))]
756#[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
757impl Value for valuable::Value<'_> {
758    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
759        visitor.record_value(key, *self)
760    }
761}
762
763#[cfg(all(tracing_unstable, feature = "valuable"))]
764impl crate::sealed::Sealed for &'_ dyn valuable::Valuable {}
765
766#[cfg(all(tracing_unstable, feature = "valuable"))]
767#[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
768impl Value for &'_ dyn valuable::Valuable {
769    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
770        visitor.record_value(key, self.as_value())
771    }
772}
773
774impl crate::sealed::Sealed for Empty {}
775impl Value for Empty {
776    #[inline]
777    fn record(&self, _: &Field, _: &mut dyn Visit) {}
778}
779
780impl<T: Value> crate::sealed::Sealed for Option<T> {}
781
782impl<T: Value> Value for Option<T> {
783    fn record(&self, key: &Field, visitor: &mut dyn Visit) {
784        if let Some(v) = &self {
785            v.record(key, visitor)
786        }
787    }
788}
789
790impl Field {
793    #[inline]
799    pub fn callsite(&self) -> callsite::Identifier {
800        self.fields.callsite()
801    }
802
803    pub fn name(&self) -> &'static str {
805        self.fields.names[self.i]
806    }
807
808    pub fn index(&self) -> usize {
810        self.i
811    }
812}
813
814impl fmt::Display for Field {
815    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
816        f.pad(self.name())
817    }
818}
819
820impl AsRef<str> for Field {
821    fn as_ref(&self) -> &str {
822        self.name()
823    }
824}
825
826impl PartialEq for Field {
827    fn eq(&self, other: &Self) -> bool {
828        self.callsite() == other.callsite() && self.i == other.i
829    }
830}
831
832impl Eq for Field {}
833
834impl Hash for Field {
835    fn hash<H>(&self, state: &mut H)
836    where
837        H: Hasher,
838    {
839        self.callsite().hash(state);
840        self.i.hash(state);
841    }
842}
843
844impl Clone for Field {
845    fn clone(&self) -> Self {
846        Field {
847            i: self.i,
848            fields: FieldSet {
849                names: self.fields.names,
850                callsite: self.fields.callsite(),
851            },
852        }
853    }
854}
855
856impl FieldSet {
859    pub const fn new(names: &'static [&'static str], callsite: callsite::Identifier) -> Self {
861        Self { names, callsite }
862    }
863
864    #[inline]
870    pub(crate) fn callsite(&self) -> callsite::Identifier {
871        callsite::Identifier(self.callsite.0)
872    }
873
874    pub fn field<Q: Borrow<str> + ?Sized>(&self, name: &Q) -> Option<Field> {
878        let name = &name.borrow();
879        self.names.iter().position(|f| f == name).map(|i| Field {
880            i,
881            fields: FieldSet {
882                names: self.names,
883                callsite: self.callsite(),
884            },
885        })
886    }
887
888    pub fn contains(&self, field: &Field) -> bool {
900        field.callsite() == self.callsite() && field.i <= self.len()
901    }
902
903    #[inline]
905    pub fn iter(&self) -> Iter {
906        let idxs = 0..self.len();
907        Iter {
908            idxs,
909            fields: FieldSet {
910                names: self.names,
911                callsite: self.callsite(),
912            },
913        }
914    }
915
916    #[doc(hidden)]
918    pub fn value_set<'v, V>(&'v self, values: &'v V) -> ValueSet<'v>
919    where
920        V: ValidLen<'v>,
921    {
922        ValueSet {
923            fields: self,
924            values: values.borrow(),
925        }
926    }
927
928    #[inline]
930    pub fn len(&self) -> usize {
931        self.names.len()
932    }
933
934    #[inline]
936    pub fn is_empty(&self) -> bool {
937        self.names.is_empty()
938    }
939}
940
941impl IntoIterator for &FieldSet {
942    type IntoIter = Iter;
943    type Item = Field;
944    #[inline]
945    fn into_iter(self) -> Self::IntoIter {
946        self.iter()
947    }
948}
949
950impl fmt::Debug for FieldSet {
951    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
952        f.debug_struct("FieldSet")
953            .field("names", &self.names)
954            .field("callsite", &self.callsite)
955            .finish()
956    }
957}
958
959impl fmt::Display for FieldSet {
960    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
961        f.debug_set()
962            .entries(self.names.iter().map(display))
963            .finish()
964    }
965}
966
967impl Eq for FieldSet {}
968
969impl PartialEq for FieldSet {
970    fn eq(&self, other: &Self) -> bool {
971        if core::ptr::eq(&self, &other) {
972            true
973        } else if cfg!(not(debug_assertions)) {
974            self.callsite == other.callsite
977        } else {
978            let Self {
985                names: lhs_names,
986                callsite: lhs_callsite,
987            } = self;
988
989            let Self {
990                names: rhs_names,
991                callsite: rhs_callsite,
992            } = &other;
993
994            lhs_callsite == rhs_callsite && lhs_names == rhs_names
997        }
998    }
999}
1000
1001impl Iterator for Iter {
1004    type Item = Field;
1005    #[inline]
1006    fn next(&mut self) -> Option<Field> {
1007        let i = self.idxs.next()?;
1008        Some(Field {
1009            i,
1010            fields: FieldSet {
1011                names: self.fields.names,
1012                callsite: self.fields.callsite(),
1013            },
1014        })
1015    }
1016}
1017
1018impl ValueSet<'_> {
1021    #[inline]
1027    pub fn callsite(&self) -> callsite::Identifier {
1028        self.fields.callsite()
1029    }
1030
1031    pub fn record(&self, visitor: &mut dyn Visit) {
1035        let my_callsite = self.callsite();
1036        for (field, value) in self.values {
1037            if field.callsite() != my_callsite {
1038                continue;
1039            }
1040            if let Some(value) = value {
1041                value.record(field, visitor);
1042            }
1043        }
1044    }
1045
1046    pub fn len(&self) -> usize {
1052        let my_callsite = self.callsite();
1053        self.values
1054            .iter()
1055            .filter(|(field, _)| field.callsite() == my_callsite)
1056            .count()
1057    }
1058
1059    pub(crate) fn contains(&self, field: &Field) -> bool {
1061        field.callsite() == self.callsite()
1062            && self
1063                .values
1064                .iter()
1065                .any(|(key, val)| *key == field && val.is_some())
1066    }
1067
1068    pub fn is_empty(&self) -> bool {
1070        let my_callsite = self.callsite();
1071        self.values
1072            .iter()
1073            .all(|(key, val)| val.is_none() || key.callsite() != my_callsite)
1074    }
1075
1076    pub(crate) fn field_set(&self) -> &FieldSet {
1077        self.fields
1078    }
1079}
1080
1081impl fmt::Debug for ValueSet<'_> {
1082    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1083        self.values
1084            .iter()
1085            .fold(&mut f.debug_struct("ValueSet"), |dbg, (key, v)| {
1086                if let Some(val) = v {
1087                    val.record(key, dbg);
1088                }
1089                dbg
1090            })
1091            .field("callsite", &self.callsite())
1092            .finish()
1093    }
1094}
1095
1096impl fmt::Display for ValueSet<'_> {
1097    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1098        self.values
1099            .iter()
1100            .fold(&mut f.debug_map(), |dbg, (key, v)| {
1101                if let Some(val) = v {
1102                    val.record(key, dbg);
1103                }
1104                dbg
1105            })
1106            .finish()
1107    }
1108}
1109
1110mod private {
1113    use super::*;
1114
1115    pub trait ValidLen<'a>: Borrow<[(&'a Field, Option<&'a (dyn Value + 'a)>)]> {}
1117
1118    impl<'a, const N: usize> ValidLen<'a> for [(&'a Field, Option<&'a (dyn Value + 'a)>); N] {}
1119}
1120
1121#[cfg(test)]
1122mod test {
1123    use super::*;
1124    use crate::metadata::{Kind, Level, Metadata};
1125    use crate::stdlib::{borrow::ToOwned, string::String};
1126
1127    struct TestCallsite1();
1129    static TEST_CALLSITE_1: TestCallsite1 = TestCallsite1();
1130    static TEST_META_1: Metadata<'static> = metadata! {
1131        name: "field_test1",
1132        target: module_path!(),
1133        level: Level::INFO,
1134        fields: &["foo", "bar", "baz"],
1135        callsite: &TEST_CALLSITE_1,
1136        kind: Kind::SPAN,
1137    };
1138
1139    impl crate::callsite::Callsite for TestCallsite1 {
1140        fn set_interest(&self, _: crate::subscriber::Interest) {
1141            unimplemented!()
1142        }
1143
1144        fn metadata(&self) -> &Metadata<'_> {
1145            &TEST_META_1
1146        }
1147    }
1148
1149    struct TestCallsite2();
1150    static TEST_CALLSITE_2: TestCallsite2 = TestCallsite2();
1151    static TEST_META_2: Metadata<'static> = metadata! {
1152        name: "field_test2",
1153        target: module_path!(),
1154        level: Level::INFO,
1155        fields: &["foo", "bar", "baz"],
1156        callsite: &TEST_CALLSITE_2,
1157        kind: Kind::SPAN,
1158    };
1159
1160    impl crate::callsite::Callsite for TestCallsite2 {
1161        fn set_interest(&self, _: crate::subscriber::Interest) {
1162            unimplemented!()
1163        }
1164
1165        fn metadata(&self) -> &Metadata<'_> {
1166            &TEST_META_2
1167        }
1168    }
1169
1170    #[test]
1171    fn value_set_with_no_values_is_empty() {
1172        let fields = TEST_META_1.fields();
1173        let values = &[
1174            (&fields.field("foo").unwrap(), None),
1175            (&fields.field("bar").unwrap(), None),
1176            (&fields.field("baz").unwrap(), None),
1177        ];
1178        let valueset = fields.value_set(values);
1179        assert!(valueset.is_empty());
1180    }
1181
1182    #[test]
1183    fn index_of_field_in_fieldset_is_correct() {
1184        let fields = TEST_META_1.fields();
1185        let foo = fields.field("foo").unwrap();
1186        assert_eq!(foo.index(), 0);
1187        let bar = fields.field("bar").unwrap();
1188        assert_eq!(bar.index(), 1);
1189        let baz = fields.field("baz").unwrap();
1190        assert_eq!(baz.index(), 2);
1191    }
1192
1193    #[test]
1194    fn empty_value_set_is_empty() {
1195        let fields = TEST_META_1.fields();
1196        let valueset = fields.value_set(&[]);
1197        assert!(valueset.is_empty());
1198    }
1199
1200    #[test]
1201    fn value_sets_with_fields_from_other_callsites_are_empty() {
1202        let fields = TEST_META_1.fields();
1203        let values = &[
1204            (&fields.field("foo").unwrap(), Some(&1 as &dyn Value)),
1205            (&fields.field("bar").unwrap(), Some(&2 as &dyn Value)),
1206            (&fields.field("baz").unwrap(), Some(&3 as &dyn Value)),
1207        ];
1208        let valueset = TEST_META_2.fields().value_set(values);
1209        assert!(valueset.is_empty())
1210    }
1211
1212    #[test]
1213    fn sparse_value_sets_are_not_empty() {
1214        let fields = TEST_META_1.fields();
1215        let values = &[
1216            (&fields.field("foo").unwrap(), None),
1217            (&fields.field("bar").unwrap(), Some(&57 as &dyn Value)),
1218            (&fields.field("baz").unwrap(), None),
1219        ];
1220        let valueset = fields.value_set(values);
1221        assert!(!valueset.is_empty());
1222    }
1223
1224    #[test]
1225    fn fields_from_other_callsets_are_skipped() {
1226        let fields = TEST_META_1.fields();
1227        let values = &[
1228            (&fields.field("foo").unwrap(), None),
1229            (
1230                &TEST_META_2.fields().field("bar").unwrap(),
1231                Some(&57 as &dyn Value),
1232            ),
1233            (&fields.field("baz").unwrap(), None),
1234        ];
1235
1236        struct MyVisitor;
1237        impl Visit for MyVisitor {
1238            fn record_debug(&mut self, field: &Field, _: &dyn (crate::stdlib::fmt::Debug)) {
1239                assert_eq!(field.callsite(), TEST_META_1.callsite())
1240            }
1241        }
1242        let valueset = fields.value_set(values);
1243        valueset.record(&mut MyVisitor);
1244    }
1245
1246    #[test]
1247    fn empty_fields_are_skipped() {
1248        let fields = TEST_META_1.fields();
1249        let values = &[
1250            (&fields.field("foo").unwrap(), Some(&Empty as &dyn Value)),
1251            (&fields.field("bar").unwrap(), Some(&57 as &dyn Value)),
1252            (&fields.field("baz").unwrap(), Some(&Empty as &dyn Value)),
1253        ];
1254
1255        struct MyVisitor;
1256        impl Visit for MyVisitor {
1257            fn record_debug(&mut self, field: &Field, _: &dyn (crate::stdlib::fmt::Debug)) {
1258                assert_eq!(field.name(), "bar")
1259            }
1260        }
1261        let valueset = fields.value_set(values);
1262        valueset.record(&mut MyVisitor);
1263    }
1264
1265    #[test]
1266    fn record_debug_fn() {
1267        let fields = TEST_META_1.fields();
1268        let values = &[
1269            (&fields.field("foo").unwrap(), Some(&1 as &dyn Value)),
1270            (&fields.field("bar").unwrap(), Some(&2 as &dyn Value)),
1271            (&fields.field("baz").unwrap(), Some(&3 as &dyn Value)),
1272        ];
1273        let valueset = fields.value_set(values);
1274        let mut result = String::new();
1275        valueset.record(&mut |_: &Field, value: &dyn fmt::Debug| {
1276            use crate::stdlib::fmt::Write;
1277            write!(&mut result, "{:?}", value).unwrap();
1278        });
1279        assert_eq!(result, "123".to_owned());
1280    }
1281
1282    #[test]
1283    #[cfg(feature = "std")]
1284    fn record_error() {
1285        let fields = TEST_META_1.fields();
1286        let err: Box<dyn std::error::Error + Send + Sync + 'static> =
1287            std::io::Error::new(std::io::ErrorKind::Other, "lol").into();
1288        let values = &[
1289            (&fields.field("foo").unwrap(), Some(&err as &dyn Value)),
1290            (&fields.field("bar").unwrap(), Some(&Empty as &dyn Value)),
1291            (&fields.field("baz").unwrap(), Some(&Empty as &dyn Value)),
1292        ];
1293        let valueset = fields.value_set(values);
1294        let mut result = String::new();
1295        valueset.record(&mut |_: &Field, value: &dyn fmt::Debug| {
1296            use core::fmt::Write;
1297            write!(&mut result, "{:?}", value).unwrap();
1298        });
1299        assert_eq!(result, format!("{}", err));
1300    }
1301
1302    #[test]
1303    fn record_bytes() {
1304        let fields = TEST_META_1.fields();
1305        let first = &b"abc"[..];
1306        let second: &[u8] = &[192, 255, 238];
1307        let values = &[
1308            (&fields.field("foo").unwrap(), Some(&first as &dyn Value)),
1309            (&fields.field("bar").unwrap(), Some(&" " as &dyn Value)),
1310            (&fields.field("baz").unwrap(), Some(&second as &dyn Value)),
1311        ];
1312        let valueset = fields.value_set(values);
1313        let mut result = String::new();
1314        valueset.record(&mut |_: &Field, value: &dyn fmt::Debug| {
1315            use core::fmt::Write;
1316            write!(&mut result, "{:?}", value).unwrap();
1317        });
1318        assert_eq!(result, format!("{}", r#"[61 62 63]" "[c0 ff ee]"#));
1319    }
1320}