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}