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}