secure_gate/
fixed.rs

1// src/fixed.rs
2use core::convert::From;
3use core::ops::{Deref, DerefMut};
4
5use crate::{Expose, ExposeMut};
6
7pub struct Fixed<T>(pub T); // ← pub field
8
9impl<T> Fixed<T> {
10    pub fn new(value: T) -> Self {
11        Fixed(value)
12    }
13}
14
15impl<T> Deref for Fixed<T> {
16    type Target = T;
17    #[inline(always)]
18    fn deref(&self) -> &T {
19        &self.0
20    }
21}
22
23impl<T> DerefMut for Fixed<T> {
24    #[inline(always)]
25    fn deref_mut(&mut self) -> &mut T {
26        &mut self.0
27    }
28}
29
30impl<const N: usize> AsRef<[u8]> for Fixed<[u8; N]> {
31    #[inline(always)]
32    fn as_ref(&self) -> &[u8] {
33        &self.0
34    }
35}
36
37impl<const N: usize> AsMut<[u8]> for Fixed<[u8; N]> {
38    #[inline(always)]
39    fn as_mut(&mut self) -> &mut [u8] {
40        &mut self.0
41    }
42}
43
44impl<T> core::fmt::Debug for Fixed<T> {
45    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
46        f.write_str("[REDACTED]")
47    }
48}
49
50impl<T> Fixed<T> {
51    pub fn view(&self) -> Expose<'_, T> {
52        Expose(&self.0)
53    }
54
55    pub fn view_mut(&mut self) -> ExposeMut<'_, T> {
56        ExposeMut(&mut self.0)
57    }
58}
59
60impl<T> Fixed<T> {
61    pub fn into_inner(self) -> T {
62        self.0
63    }
64}
65
66impl<const N: usize> Fixed<[u8; N]> {
67    /// Create from a slice. Panics if the slice has the wrong length.
68    #[inline]
69    pub fn from_slice(bytes: &[u8]) -> Self {
70        assert_eq!(bytes.len(), N, "slice length mismatch");
71        let mut arr = [0u8; N];
72        arr.copy_from_slice(&bytes[..N]);
73        Self::new(arr)
74    }
75}
76
77impl<const N: usize> From<[u8; N]> for Fixed<[u8; N]> {
78    #[inline]
79    fn from(arr: [u8; N]) -> Self {
80        Self::new(arr)
81    }
82}