Skip to main content

secure_gate/macros/
dynamic_alias.rs

1/// Creates a type alias for [`Dynamic<T>`](crate::Dynamic).
2///
3/// Generates a named, optionally-documented type alias. The generated type inherits
4/// all `Dynamic<T>` methods including `expose_secret()`, `with_secret()`, `to_hex()`, etc.
5///
6/// *Requires feature `alloc`.*
7///
8/// # Syntax
9///
10/// ```text
11/// dynamic_alias!(pub Name, T);                // public, auto-generated doc
12/// dynamic_alias!(pub(crate) Name, T);         // crate-visible
13/// dynamic_alias!(Name, T);                    // private
14/// dynamic_alias!(pub Name, T, "doc string");  // with custom doc
15/// ```
16///
17/// # Examples
18///
19/// All three visibility forms:
20///
21/// ```rust
22/// use secure_gate::{dynamic_alias, RevealSecret};
23///
24/// dynamic_alias!(pub Password, String);            // public
25/// dynamic_alias!(pub(crate) SessionToken, Vec<u8>); // crate-visible
26/// dynamic_alias!(private_key_bytes, Vec<u8>);      // private
27///
28/// let pw: Password = "hunter2".into();
29/// pw.with_secret(|s| assert!(!s.is_empty()));
30/// ```
31///
32/// With a custom doc string:
33///
34/// ```rust
35/// use secure_gate::{dynamic_alias, RevealSecret};
36///
37/// dynamic_alias!(pub Token, Vec<u8>, "OAuth 2.0 bearer token.");
38/// let token: Token = vec![1u8, 2, 3].into();
39/// assert_eq!(token.expose_secret(), &[1, 2, 3]);
40/// ```
41///
42/// # Implementation Notes
43///
44/// `dynamic_alias!` has **no zero-size or type-level guard** — any `T` is accepted.
45/// Macro-generated aliases lack runtime size checks beyond what `Dynamic<T>` itself provides.
46/// Note that unlike `fixed_alias!`, this macro (and the generic dynamic variant) allows zero-sized or empty inner types with no compile-time rejection.
47/// Validate expected inner types and sizes in unit tests:
48///
49/// ```rust
50/// use secure_gate::dynamic_alias;
51///
52/// dynamic_alias!(pub ApiToken, Vec<u8>);
53/// // In your tests: assert!(token.len() > 0);
54/// ```
55///
56/// # Security
57///
58/// Generated aliases inherit all [`Dynamic`](crate::Dynamic) security guarantees: zeroize
59/// on drop (including spare capacity), redacted `Debug`, explicit access only.
60///
61/// # See also
62///
63/// - [`dynamic_generic_alias!`](crate::dynamic_generic_alias) — when the inner type varies
64/// - [`fixed_alias!`](crate::fixed_alias) — stack-allocated alternative
65#[cfg(feature = "alloc")]
66#[macro_export]
67macro_rules! dynamic_alias {
68    ($vis:vis $name:ident, $inner:ty, $doc:literal) => {
69        #[doc = $doc]
70        $vis type $name = $crate::Dynamic<$inner>;
71    };
72    ($vis:vis $name:ident, $inner:ty) => {
73        #[doc = concat!("Secure heap-allocated ", stringify!($inner))]
74        $vis type $name = $crate::Dynamic<$inner>;
75    };
76    ($name:ident, $inner:ty, $doc:literal) => {
77        #[doc = $doc]
78        type $name = $crate::Dynamic<$inner>;
79    };
80    ($name:ident, $inner:ty) => {
81        #[doc = concat!("Secure heap-allocated ", stringify!($inner))]
82        type $name = $crate::Dynamic<$inner>;
83    };
84}