secure_gate/
macros.rs

1// src/macros.rs
2//! Ergonomic macros for creating and aliasing secrets.
3//!
4//! These macros provide concise syntax for instantiating [`Fixed`], [`Dynamic`],
5//! and their zeroizing variants, as well as defining type aliases for common
6//! secret types.
7//!
8//! # Examples
9//!
10//! ```
11//! use secure_gate::{dynamic_alias, fixed_alias, secure};
12//!
13//! fixed_alias!(Aes256Key, 32);
14//! dynamic_alias!(Password, String);
15//!
16//! let key = secure!([u8; 32], [42u8; 32]);
17//! let pw = secure!(String, "hunter2".to_string());
18//! ```
19
20/// Creates a secret wrapper around the given value.
21///
22/// Supports fixed-size byte arrays and heap-allocated types like `String` and `Vec<u8>`.
23///
24/// # Examples
25///
26/// ```
27/// use secure_gate::secure;
28///
29/// // Fixed-size secret
30/// let key = secure!([u8; 32], [42u8; 32]);
31/// assert_eq!(key.expose_secret(), &[42u8; 32]);
32///
33/// // Heap-allocated secret
34/// let pw = secure!(String, "hunter2".to_string());
35/// assert_eq!(pw.expose_secret(), "hunter2");
36///
37/// // Alternative heap syntax
38/// let data: secure_gate::Dynamic<Vec<u8>> = secure!(heap Vec<u8>, vec![1u8, 2u8, 3u8]);
39/// assert_eq!(data.as_slice(), &[1u8, 2u8, 3u8]);
40/// ```
41#[macro_export]
42macro_rules! secure {
43    ([u8; $N:literal], $expr:expr $(,)?) => {
44        $crate::Fixed::new($expr)
45    };
46    ($ty:ty, $expr:expr $(,)?) => {
47        $crate::Fixed::<$ty>::new($expr)
48    };
49    (String, $expr:expr $(,)?) => {
50        $crate::Dynamic::new($expr)
51    };
52    (Vec<u8>, $expr:expr $(,)?) => {
53        $crate::Dynamic::new($expr)
54    };
55    (heap $ty:ty, $expr:expr $(,)?) => {
56        $crate::Dynamic::new($expr)
57    };
58}
59
60/// Creates a zeroizing secret that automatically wipes itself on drop.
61///
62/// Requires the `zeroize` feature.
63///
64/// # Examples
65///
66/// ```
67/// use secure_gate::secure_zeroizing;
68///
69/// #[cfg(feature = "zeroize")]
70/// {
71///     use zeroize::Zeroizing;
72///     use secrecy::ExposeSecret;
73///
74///     // Fixed-size zeroizing secret (uses zeroize::Zeroizing directly)
75///     let key: Zeroizing<[u8; 32]> = secure_zeroizing!([u8; 32], [42u8; 32]);
76///     assert_eq!(key[..], [42u8; 32]);
77///
78///     // Heap-allocated zeroizing secret
79///     let pw = secure_zeroizing!(heap String, "hunter2".to_string().into_boxed_str());
80///     assert_eq!(pw.expose_secret(), "hunter2");
81/// }
82/// ```
83#[macro_export]
84macro_rules! secure_zeroizing {
85    ($ty:ty, $expr:expr $(,)?) => {
86        $crate::FixedZeroizing::new($expr)
87    };
88    (heap $ty:ty, $expr:expr $(,)?) => {
89        $crate::DynamicZeroizing::new($expr)
90    };
91}
92
93/// Defines a type alias for a fixed-size byte secret.
94///
95/// The resulting type inherits all methods from [`Fixed<[u8; N]>`], including
96/// constructors like `from_slice` and `From<[u8; N]>`.
97///
98/// # Examples
99///
100/// ```
101/// use secure_gate::fixed_alias;
102///
103/// fixed_alias!(Aes256Key, 32);
104///
105/// let key: Aes256Key = [42u8; 32].into();
106/// assert_eq!(key.expose_secret(), &[42u8; 32]);
107/// ```
108#[macro_export]
109macro_rules! fixed_alias {
110    ($name:ident, $size:literal) => {
111        /// Fixed-size secret of exactly `$size` bytes.
112        pub type $name = $crate::Fixed<[u8; $size]>;
113    };
114}
115
116/// Defines a type alias for a dynamic (heap-allocated) secret.
117///
118/// The resulting type inherits all methods and conversions from [`Dynamic<T>`].
119///
120/// # Examples
121///
122/// ```
123/// use secure_gate::dynamic_alias;
124///
125/// dynamic_alias!(Password, String);
126///
127/// let pw: Password = "hunter2".into();
128/// assert_eq!(pw.expose_secret(), "hunter2");
129/// ```
130#[macro_export]
131macro_rules! dynamic_alias {
132    ($name:ident, $ty:ty) => {
133        pub type $name = $crate::Dynamic<$ty>;
134    };
135}
136
137#[macro_export]
138macro_rules! random_alias {
139    ($name:ident, $size:literal) => {
140        pub type $name = $crate::RandomBytes<$size>;
141    };
142}