secure_gate/
expose.rs

1// src/expose.rs
2// Zero-cost views into secrets — no unsafe, ever
3
4use alloc::string::String;
5use core::ops::{Deref, DerefMut};
6
7/// Immutable view into a secret value
8pub struct Expose<'a, T: ?Sized>(pub &'a T);
9
10/// Mutable view into a secret value
11pub struct ExposeMut<'a, T: ?Sized>(pub &'a mut T);
12
13impl<'a, T: ?Sized> Deref for Expose<'a, T> {
14    type Target = T;
15    #[inline(always)]
16    fn deref(&self) -> &T {
17        self.0
18    }
19}
20
21impl<'a, T: ?Sized> Deref for ExposeMut<'a, T> {
22    type Target = T;
23    #[inline(always)]
24    fn deref(&self) -> &T {
25        self.0
26    }
27}
28
29impl<'a, T: ?Sized> DerefMut for ExposeMut<'a, T> {
30    #[inline(always)]
31    fn deref_mut(&mut self) -> &mut T {
32        self.0
33    }
34}
35
36// === String views ===
37
38impl<'a> Expose<'a, String> {
39    #[inline(always)]
40    pub fn as_string(&self) -> &String {
41        self.0
42    }
43    #[inline(always)]
44    pub fn as_str(&self) -> &str {
45        self.0.as_str()
46    }
47    #[inline(always)]
48    pub fn as_bytes(&self) -> &[u8] {
49        self.0.as_bytes()
50    }
51}
52
53impl<'a> ExposeMut<'a, String> {
54    #[inline(always)]
55    pub fn as_string(&mut self) -> &mut String {
56        self.0
57    }
58    #[inline(always)]
59    pub fn as_str_mut(&mut self) -> &mut str {
60        self.0.as_mut_str()
61    }
62}
63
64// === str views (immutable only) ===
65
66impl<'a> Expose<'a, str> {
67    #[inline(always)]
68    pub fn as_str(&self) -> &str {
69        self.0
70    }
71    #[inline(always)]
72    pub fn as_bytes(&self) -> &[u8] {
73        self.0.as_bytes()
74    }
75}
76
77// === Vec<u8> views ===
78
79impl<'a> Expose<'a, Vec<u8>> {
80    #[inline(always)]
81    pub fn as_slice(&self) -> &[u8] {
82        self.0.as_slice()
83    }
84}
85
86impl<'a> ExposeMut<'a, Vec<u8>> {
87    #[inline(always)]
88    pub fn as_vec(&mut self) -> &mut Vec<u8> {
89        self.0
90    }
91    #[inline(always)]
92    pub fn as_slice_mut(&mut self) -> &mut [u8] {
93        self.0.as_mut_slice()
94    }
95}
96
97// === [u8] slice views (immutable only) ===
98
99impl<'a> Expose<'a, [u8]> {
100    #[inline(always)]
101    pub fn as_slice(&self) -> &[u8] {
102        self.0
103    }
104}
105
106// === AsRef / AsMut ===
107
108impl<'a, T: ?Sized> AsRef<T> for Expose<'a, T> {
109    #[inline(always)]
110    fn as_ref(&self) -> &T {
111        self.0
112    }
113}
114
115impl<'a, T: ?Sized> AsRef<T> for ExposeMut<'a, T> {
116    #[inline(always)]
117    fn as_ref(&self) -> &T {
118        self.0
119    }
120}
121
122impl<'a, T: ?Sized> AsMut<T> for ExposeMut<'a, T> {
123    #[inline(always)]
124    fn as_mut(&mut self) -> &mut T {
125        self.0
126    }
127}