@@ -96,10 +96,14 @@ use syn::{
9696/// the function is called.
9797///
9898/// Unless overriden, a span with `info` level will be generated.
99- /// The generated span's name will be the name of the function. Any arguments
100- /// to that function will be recorded as fields using [`fmt::Debug`] except to
101- /// primitive types including `bool`, `u8`, `i8`, `u16`, `i16`, `u32`, `i32`,
102- /// `u64`, `i64`, `usize`, and `isize`.
99+ /// The generated span's name will be the name of the function.
100+ /// By default, all arguments to the function are included as fields on the
101+ /// span. Arguments that are `tracing` [primitive types] implementing the
102+ /// [`Value` trait] will be recorded as fields of that type. Types which do
103+ /// not implement `Value` will be recorded using [`std::fmt::Debug`].
104+ ///
105+ /// [primitive types]: https://docs.rs/tracing/latest/tracing/field/trait.Value.html#foreign-impls
106+ /// [`Value` trait]: https://docs.rs/tracing/latest/tracing/field/trait.Value.html
103107///
104108/// To skip recording a function's or method's argument, pass the argument's name
105109/// to the `skip` argument on the `#[instrument]` macro. For example,
@@ -864,18 +868,40 @@ impl Parse for Level {
864868 }
865869}
866870
867- /// A enum indicates the field should be recorded as `Value` or `Debug`.
871+ /// Indicates whether a field should be recorded as `Value` or `Debug`.
868872enum RecordType {
869- /// Represents the field should be recorded as it is .
873+ /// The field should be recorded using its `Value` implementation .
870874 Value ,
871- /// Represents the field should be recorded as `tracing::field::debug()`.
875+ /// The field should be recorded using `tracing::field::debug()`.
872876 Debug ,
873877}
874878
875879impl RecordType {
876880 /// Array of primitive types which should be recorded as [RecordType::Value].
877- const TYPES_FOR_VALUE : [ & ' static str ; 11 ] = [
878- "bool" , "u8" , "i8" , "u16" , "i16" , "u32" , "i32" , "u64" , "i64" , "usize" , "isize" ,
881+ const TYPES_FOR_VALUE : [ & ' static str ; 23 ] = [
882+ "bool" ,
883+ "str" ,
884+ "u8" ,
885+ "i8" ,
886+ "u16" ,
887+ "i16" ,
888+ "u32" ,
889+ "i32" ,
890+ "u64" ,
891+ "i64" ,
892+ "usize" ,
893+ "isize" ,
894+ "NonZeroU8" ,
895+ "NonZeroI8" ,
896+ "NonZeroU16" ,
897+ "NonZeroI16" ,
898+ "NonZeroU32" ,
899+ "NonZeroI32" ,
900+ "NonZeroU64" ,
901+ "NonZeroI64" ,
902+ "NonZeroUsize" ,
903+ "NonZeroIsize" ,
904+ "Wrapping" ,
879905 ] ;
880906
881907 /// Parse `RecordType` from [syn::Type] by looking up
@@ -887,11 +913,11 @@ impl RecordType {
887913 . segments
888914 . iter ( )
889915 . last ( )
890- . filter ( |path_segment| {
916+ . map ( |path_segment| {
891917 let ident = path_segment. ident . to_string ( ) ;
892918 Self :: TYPES_FOR_VALUE . iter ( ) . any ( |& t| t == ident)
893919 } )
894- . is_some ( ) =>
920+ . unwrap_or ( false ) =>
895921 {
896922 RecordType :: Value
897923 }
@@ -907,6 +933,10 @@ fn param_names(pat: Pat, record_type: RecordType) -> Box<dyn Iterator<Item = (Id
907933 match pat {
908934 Pat :: Ident ( PatIdent { ident, .. } ) => Box :: new ( iter:: once ( ( ident, record_type) ) ) ,
909935 Pat :: Reference ( PatReference { pat, .. } ) => param_names ( * pat, record_type) ,
936+ // We can't get the concrete type of fields in the struct/tuple
937+ // patterns by using `syn`. e.g. `fn foo(Foo { x, y }: Foo) {}`.
938+ // Therefore, the struct/tuple patterns in the arguments will just
939+ // always be recorded as `RecordType::Debug`.
910940 Pat :: Struct ( PatStruct { fields, .. } ) => Box :: new (
911941 fields
912942 . into_iter ( )
0 commit comments