Skip to main content

secure_gate/macros/
fixed_alias.rs

1/// Creates a type alias for [`Fixed<[u8; N]>`](crate::Fixed).
2///
3/// Generates a named, optionally-documented type alias with a compile-time zero-size guard.
4/// The generated type inherits all `Fixed<[u8; N]>` methods including `expose_secret()`,
5/// `with_secret()`, `to_hex()`, etc.
6///
7/// # Syntax
8///
9/// ```text
10/// fixed_alias!(pub Name, N);                // public, auto-generated doc
11/// fixed_alias!(pub(crate) Name, N);         // crate-visible
12/// fixed_alias!(Name, N);                    // private
13/// fixed_alias!(pub Name, N, "doc string");  // with custom doc
14/// ```
15///
16/// # Examples
17///
18/// All three visibility forms:
19///
20/// ```rust
21/// use secure_gate::{fixed_alias, RevealSecret};
22///
23/// fixed_alias!(pub Aes256Key, 32);           // public
24/// fixed_alias!(pub(crate) HmacKey, 32);      // crate-visible
25/// fixed_alias!(private_nonce, 12);           // private (no modifier)
26///
27/// let key: Aes256Key = [42u8; 32].into();
28/// key.with_secret(|b| assert_eq!(b.len(), 32));
29/// ```
30///
31/// With a custom doc string:
32///
33/// ```rust
34/// use secure_gate::{fixed_alias, RevealSecret};
35///
36/// fixed_alias!(pub ApiKey, 32, "32-byte API authentication key.");
37/// let key: ApiKey = [0u8; 32].into();
38/// assert_eq!(key.expose_secret(), &[0u8; 32]);
39/// ```
40///
41/// Zero-size is a **compile error** (caught by the zero-size guard):
42///
43/// ```rust,compile_fail
44/// use secure_gate::fixed_alias;
45/// fixed_alias!(pub Bad, 0); // compile-time error: index out of bounds
46/// ```
47///
48/// # Implementation Notes
49///
50/// Each expansion emits `const _: () = { let _ = [(); N][0]; };` — a zero-cost
51/// compile-time guard that rejects `N = 0` with a const-evaluation panic.
52/// This is the **only** size check performed at compile time; there are no
53/// runtime checks for other size constraints. Validate expected sizes in unit tests:
54///
55/// ```rust
56/// use secure_gate::{fixed_alias, RevealSecret};
57///
58/// fixed_alias!(pub ChaChaKey, 32);
59/// // In your tests:
60/// assert_eq!(core::mem::size_of::<ChaChaKey>(), 32);
61/// ```
62#[macro_export]
63macro_rules! fixed_alias {
64    ($vis:vis $name:ident, $size:literal, $doc:literal) => {
65        #[doc = $doc]
66        const _: () = { let _ = [(); $size][0]; };
67        $vis type $name = $crate::Fixed<[u8; $size]>;
68    };
69    ($vis:vis $name:ident, $size:literal) => {
70        #[doc = concat!("Fixed-size secure secret (", stringify!($size), " bytes)")]
71        const _: () = { let _ = [(); $size][0]; };
72        $vis type $name = $crate::Fixed<[u8; $size]>;
73    };
74    ($name:ident, $size:literal, $doc:literal) => {
75        #[doc = $doc]
76        const _: () = { let _ = [(); $size][0]; };
77        type $name = $crate::Fixed<[u8; $size]>;
78    };
79    ($name:ident, $size:literal) => {
80        #[doc = concat!("Fixed-size secure secret (", stringify!($size), " bytes)")]
81        const _: () = { let _ = [(); $size][0]; };
82        type $name = $crate::Fixed<[u8; $size]>;
83    };
84}