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