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}