pub struct Fixed<T>(/* private fields */);Expand description
Stack-allocated secure secret wrapper.
This is a zero-cost wrapper for fixed-size secrets like byte arrays or primitives. The inner field is private, forcing all access through explicit methods.
Security invariants:
- No
DereforAsRef— prevents silent access or borrowing. - No implicit
Copy— even for[u8; N], duplication must be explicit via.clone(). Debugis always redacted.
§Examples
Basic usage:
use secure_gate::Fixed;
let secret = Fixed::new(42u32);
assert_eq!(*secret.expose_secret(), 42);For byte arrays (most common):
use secure_gate::{Fixed, fixed_alias};
fixed_alias!(pub Aes256Key, 32); // Visibility required
let key_bytes = [0x42u8; 32];
let key: Aes256Key = Fixed::from(key_bytes);
assert_eq!(key.len(), 32);
assert_eq!(key.expose_secret()[0], 0x42);With zeroize feature (automatic wipe on drop):
use secure_gate::Fixed;
let mut secret = Fixed::new([1u8, 2, 3]);
drop(secret); // memory wiped automaticallyImplementations§
Source§impl<T> Fixed<T>
impl<T> Fixed<T>
Sourcepub const fn new(value: T) -> Self
pub const fn new(value: T) -> Self
Wrap a value in a Fixed secret.
This is zero-cost and const-friendly.
§Example
use secure_gate::Fixed;
const SECRET: Fixed<u32> = Fixed::new(42);Sourcepub const fn expose_secret(&self) -> &T
pub const fn expose_secret(&self) -> &T
Expose the inner value for read-only access.
This is the only way to read the secret — loud and auditable.
§Example
use secure_gate::Fixed;
let secret = Fixed::new("hunter2");
assert_eq!(secret.expose_secret(), &"hunter2");Sourcepub fn expose_secret_mut(&mut self) -> &mut T
pub fn expose_secret_mut(&mut self) -> &mut T
Expose the inner value for mutable access.
This is the only way to mutate the secret — loud and auditable.
§Example
use secure_gate::Fixed;
let mut secret = Fixed::new([1u8, 2, 3]);
secret.expose_secret_mut()[0] = 42;
assert_eq!(secret.expose_secret()[0], 42);Sourcepub fn no_clone(self) -> FixedNoClone<T>
pub fn no_clone(self) -> FixedNoClone<T>
Convert to a non-cloneable variant.
This prevents accidental cloning of the secret.
§Example
use secure_gate::Fixed;
let secret = Fixed::new([1u8; 32]);
let no_clone = secret.no_clone();
// no_clone cannot be clonedSource§impl<T: Zeroize> Fixed<T>
impl<T: Zeroize> Fixed<T>
Sourcepub fn zeroize_now(&mut self)
pub fn zeroize_now(&mut self)
Explicitly zeroize the secret immediately.
This is useful when you want to wipe memory before the value goes out of scope, or when you want to make the zeroization intent explicit in the code.
§Example
use secure_gate::Fixed;
let mut key = Fixed::new([42u8; 32]);
// ... use key ...
key.zeroize_now(); // Explicit wipe - makes intent clearSource§impl<const N: usize> Fixed<[u8; N]>
impl<const N: usize> Fixed<[u8; N]>
Sourcepub const fn len(&self) -> usize
pub const fn len(&self) -> usize
Returns the fixed length in bytes.
This is safe public metadata — does not expose the secret.
Sourcepub const fn is_empty(&self) -> bool
pub const fn is_empty(&self) -> bool
Returns true if the fixed secret is empty (zero-length).
This is safe public metadata — does not expose the secret.
Sourcepub fn from_slice(bytes: &[u8]) -> Self
pub fn from_slice(bytes: &[u8]) -> Self
Create from a byte slice of exactly N bytes.
Panics if the slice length does not match N.
§Example
use secure_gate::Fixed;
let bytes: &[u8] = &[1, 2, 3];
let secret = Fixed::<[u8; 3]>::from_slice(bytes);
assert_eq!(secret.expose_secret(), &[1, 2, 3]);Trait Implementations§
impl<T: Zeroize> ZeroizeOnDrop for Fixed<T>
zeroize only.