redoubt_alloc/
redoubt_option.rs1use redoubt_zero::{
6 FastZeroizable, RedoubtZero, ZeroizationProbe, ZeroizeMetadata, ZeroizeOnDropSentinel,
7};
8
9use crate::error::RedoubtOptionError;
10
11#[derive(RedoubtZero, Default)]
13pub struct RedoubtOption<T>
14where
15 T: FastZeroizable + ZeroizeMetadata + ZeroizationProbe,
16{
17 inner: Option<T>,
18 __sentinel: ZeroizeOnDropSentinel,
19}
20
21impl<T> RedoubtOption<T>
22where
23 T: FastZeroizable + ZeroizeMetadata + ZeroizationProbe,
24{
25 pub fn as_ref(&self) -> Result<&T, RedoubtOptionError> {
27 self.inner.as_ref().ok_or(RedoubtOptionError::Empty)
28 }
29
30 pub fn as_mut(&mut self) -> Result<&mut T, RedoubtOptionError> {
32 self.inner.as_mut().ok_or(RedoubtOptionError::Empty)
33 }
34
35 pub fn replace(&mut self, value: &mut T)
37 where
38 T: Default,
39 {
40 if let Some(old) = &mut self.inner {
42 old.fast_zeroize();
43 }
44
45 let mut new_value = T::default();
47 unsafe {
48 core::ptr::swap_nonoverlapping(value, &mut new_value, 1);
50 }
51 self.inner = Some(new_value);
52
53 value.fast_zeroize();
55 }
56
57 pub fn take(&mut self) -> Result<T, RedoubtOptionError> {
59 self.inner.take().ok_or(RedoubtOptionError::Empty)
60 }
61
62 pub fn is_some(&self) -> bool {
64 self.inner.is_some()
65 }
66
67 pub fn is_none(&self) -> bool {
69 self.inner.is_none()
70 }
71
72 #[inline(always)]
74 pub fn as_option(&self) -> &Option<T> {
75 &self.inner
76 }
77
78 #[inline(always)]
80 pub fn as_mut_option(&mut self) -> &mut Option<T> {
81 &mut self.inner
82 }
83}