redoubt_alloc/
redoubt_array.rs1use alloc::boxed::Box;
6use core::ops::{Deref, DerefMut};
7
8use redoubt_zero::{
9 FastZeroizable, RedoubtZero, ZeroizationProbe, ZeroizeMetadata, ZeroizeOnDropSentinel,
10};
11
12#[derive(RedoubtZero)]
31pub struct RedoubtArray<T, const N: usize>
32where
33 T: FastZeroizable + ZeroizeMetadata + ZeroizationProbe,
34{
35 inner: Box<[T; N]>,
36 __sentinel: ZeroizeOnDropSentinel,
37}
38
39#[cfg(any(test, feature = "test-utils"))]
40impl<T: FastZeroizable + ZeroizeMetadata + ZeroizationProbe + PartialEq, const N: usize> PartialEq
41 for RedoubtArray<T, N>
42{
43 fn eq(&self, other: &Self) -> bool {
44 self.inner == other.inner
46 }
47}
48
49#[cfg(any(test, feature = "test-utils"))]
50impl<T: FastZeroizable + ZeroizeMetadata + Eq + ZeroizationProbe, const N: usize> Eq
51 for RedoubtArray<T, N>
52{
53}
54
55impl<T, const N: usize> core::fmt::Debug for RedoubtArray<T, N>
56where
57 T: FastZeroizable + ZeroizeMetadata + ZeroizationProbe,
58{
59 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
60 f.debug_struct("RedoubtArray")
61 .field("data", &"REDACTED")
62 .field("len", &N)
63 .finish()
64 }
65}
66
67impl<T, const N: usize> RedoubtArray<T, N>
68where
69 T: FastZeroizable + ZeroizeMetadata + ZeroizationProbe,
70{
71 pub fn new() -> Self
73 where
74 T: Default,
75 {
76 Self {
77 inner: Box::new(core::array::from_fn(|_| T::default())),
78 __sentinel: ZeroizeOnDropSentinel::default(),
79 }
80 }
81
82 pub fn from_mut_array(src: &mut [T; N]) -> Self
84 where
85 T: Default,
86 {
87 let mut arr = Self::new();
88 arr.replace_from_mut_array(src);
89 arr
90 }
91
92 #[inline]
94 pub const fn len(&self) -> usize {
95 N
96 }
97
98 #[inline]
100 pub const fn is_empty(&self) -> bool {
101 N == 0
102 }
103
104 pub fn replace_from_mut_array(&mut self, src: &mut [T; N]) {
111 self.fast_zeroize();
112
113 unsafe {
114 core::ptr::swap_nonoverlapping(src.as_mut_ptr(), self.inner.as_mut_ptr(), N);
117 }
118
119 src.fast_zeroize();
121 }
122
123 #[inline]
125 pub fn as_slice(&self) -> &[T] {
126 self.inner.as_ref()
127 }
128
129 #[inline]
131 pub fn as_mut_slice(&mut self) -> &mut [T] {
132 self.inner.as_mut()
133 }
134
135 #[inline]
137 pub fn as_array(&self) -> &[T; N] {
138 &self.inner
139 }
140
141 #[inline]
143 pub fn as_mut_array(&mut self) -> &mut [T; N] {
144 &mut self.inner
145 }
146}
147
148impl<T, const N: usize> Default for RedoubtArray<T, N>
149where
150 T: FastZeroizable + ZeroizeMetadata + ZeroizationProbe + Default,
151{
152 fn default() -> Self {
153 Self::new()
154 }
155}
156
157impl<T, const N: usize> Deref for RedoubtArray<T, N>
158where
159 T: FastZeroizable + ZeroizeMetadata + ZeroizationProbe,
160{
161 type Target = [T];
162
163 fn deref(&self) -> &Self::Target {
164 &*self.inner
165 }
166}
167
168impl<T, const N: usize> DerefMut for RedoubtArray<T, N>
169where
170 T: FastZeroizable + ZeroizeMetadata + ZeroizationProbe,
171{
172 fn deref_mut(&mut self) -> &mut Self::Target {
173 &mut *self.inner
174 }
175}