opaque_debug/
lib.rs

1//! Macro for opaque [`Debug`] trait implementation.
2//!
3//! In many cases it's convenient to have `Debug` implementation for all crate types,
4//! e.g. to allow deriving of `Debug` in user-defined structs. But at the same time, using
5//! the default derive macro can be a security hazard since it cause leaking of sensitive
6//! information, for example, through uncareful logging.
7//!
8//! This crate introduces the [`implement!`] macro which creates an opaque [`Debug`]
9//! implementation, which does not expose any internal type data.
10//!
11//! # Examples
12//! ```
13//! pub struct CryptoStuff {
14//!     key: [u8; 16],
15//! }
16//!
17//! opaque_debug::implement!(CryptoStuff);
18//!
19//! let val = CryptoStuff { key: [42; 16] };
20//! assert_eq!(format!("{:?}", val), "CryptoStuff { ... }")
21//! ```
22//!
23//! The macro also support generic paramters:
24//! ```
25//! pub struct GenricCryptoStuff<K> {
26//!     key: K,
27//! }
28//!
29//! opaque_debug::implement!(GenricCryptoStuff<K>);
30//!
31//! let val = GenricCryptoStuff { key: [42u8; 16] };
32//! assert_eq!(format!("{:?}", val), "GenricCryptoStuff<[u8; 16]> { ... }")
33//! ```
34#![no_std]
35#![doc(
36    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
37    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
38)]
39
40#[doc(hidden)]
41pub extern crate core as __core;
42
43#[macro_export]
44#[doc(hidden)]
45macro_rules! format_params {
46    ($single:ident) => {
47        "{}"
48    };
49    ($first:ident, $($rest:ident),+) => {
50        concat!("{}", ", ", $crate::format_params!($($rest),+))
51    };
52}
53
54/// Macro for implementing an opaque `Debug` implementation.
55#[macro_export]
56macro_rules! implement {
57    ($struct:ident <$($params:ident),+>) => {
58        impl <$($params),+> $crate::__core::fmt::Debug for $struct <$($params),+> {
59            fn fmt(
60                &self,
61                f: &mut $crate::__core::fmt::Formatter,
62            ) -> Result<(), $crate::__core::fmt::Error> {
63                write!(
64                    f,
65                    concat!(stringify!($struct), "<", $crate::format_params!($($params),+), "> {{ ... }}"),
66                    $($crate::__core::any::type_name::<$params>()),+
67                )
68            }
69        }
70    };
71    ($struct:ty) => {
72        impl $crate::__core::fmt::Debug for $struct {
73            fn fmt(
74                &self,
75                f: &mut $crate::__core::fmt::Formatter,
76            ) -> Result<(), $crate::__core::fmt::Error> {
77                write!(f, concat!(stringify!($struct), " {{ ... }}"))
78            }
79        }
80    };
81}