diff --git a/opaque-debug/src/lib.rs b/opaque-debug/src/lib.rs index 3b48b071..62f84a49 100644 --- a/opaque-debug/src/lib.rs +++ b/opaque-debug/src/lib.rs @@ -8,6 +8,17 @@ #[doc(hidden)] pub extern crate core as __core; +#[macro_export] +#[doc(hidden)] +macro_rules! format_params { + ($single:ident) => { + "{}" + }; + ($first:ident, $($rest:ident),+) => { + concat!("{}", ", ", $crate::format_params!($($rest),+)) + }; +} + /// Macro for defining opaque `Debug` implementation. /// /// It will use the following format: "StructName { ... }". While it's @@ -16,6 +27,20 @@ pub extern crate core as __core; /// uncareful logging. #[macro_export] macro_rules! implement { + ($struct:ident <$($params:ident),+>) => { + impl <$($params),+> $crate::__core::fmt::Debug for $struct <$($params),+> { + fn fmt( + &self, + f: &mut $crate::__core::fmt::Formatter, + ) -> Result<(), $crate::__core::fmt::Error> { + write!( + f, + concat!(stringify!($struct), "<", $crate::format_params!($($params),+), "> {{ ... }}"), + $($crate::__core::any::type_name::<$params>()),+ + ) + } + } + }; ($struct:ty) => { impl $crate::__core::fmt::Debug for $struct { fn fmt( diff --git a/opaque-debug/tests/mod.rs b/opaque-debug/tests/mod.rs index bcd57576..9def4c93 100644 --- a/opaque-debug/tests/mod.rs +++ b/opaque-debug/tests/mod.rs @@ -6,8 +6,50 @@ struct Foo { opaque_debug::implement!(Foo); +struct FooGeneric { + secret: u64, + generic: T, +} + +opaque_debug::implement!(FooGeneric); + +struct FooManyGenerics { + secret: u64, + generic1: T, + generic2: U, + generic3: V, +} + +opaque_debug::implement!(FooManyGenerics); + #[test] fn debug_formatting() { let s = format!("{:?}", Foo { secret: 42 }); assert_eq!(s, "Foo { ... }"); } + +#[test] +fn debug_formatting_generic() { + let s = format!( + "{:?}", + FooGeneric::<()> { + secret: 42, + generic: () + } + ); + assert_eq!(s, "FooGeneric<()> { ... }"); +} + +#[test] +fn debug_formatting_many_generics() { + let s = format!( + "{:?}", + FooManyGenerics::<(), u8, &str> { + secret: 42, + generic1: (), + generic2: 0u8, + generic3: "hello", + } + ); + assert_eq!(s, "FooManyGenerics<(), u8, &str> { ... }"); +}