1#[cfg(feature = "zeroize")]
34use zeroize::{DefaultIsZeroes, Zeroize, ZeroizeOnDrop, Zeroizing};
35
36#[cfg(feature = "zeroize")]
37use secrecy::{ExposeSecret, SecretBox};
38
39#[cfg(feature = "zeroize")]
40pub type FixedZeroizing<T> = Zeroizing<T>;
44
45#[cfg(feature = "zeroize")]
46pub struct DynamicZeroizing<T: ?Sized + Zeroize>(SecretBox<T>);
51
52#[cfg(feature = "zeroize")]
53impl<T: ?Sized + Zeroize> DynamicZeroizing<T> {
54 #[inline(always)]
58 pub fn new(value: Box<T>) -> Self {
59 Self(SecretBox::new(value))
60 }
61}
62
63#[cfg(feature = "zeroize")]
64impl<T: ?Sized + Zeroize> core::fmt::Debug for DynamicZeroizing<T> {
65 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
66 f.write_str("[REDACTED]")
67 }
68}
69
70#[cfg(feature = "zeroize")]
71impl<S: ?Sized + Zeroize> ExposeSecret<S> for DynamicZeroizing<S> {
72 #[inline(always)]
73 fn expose_secret(&self) -> &S {
74 self.0.expose_secret()
75 }
76}
77
78#[cfg(feature = "zeroize")]
79impl<T: Zeroize + DefaultIsZeroes> Zeroize for DynamicZeroizing<T> {
80 fn zeroize(&mut self) {
81 self.0.zeroize();
82 }
83}
84
85#[cfg(feature = "zeroize")]
86impl<T: ?Sized + Zeroize> ZeroizeOnDrop for DynamicZeroizing<T> {}
87
88#[cfg(feature = "zeroize")]
90impl<T: Zeroize> From<crate::Fixed<T>> for FixedZeroizing<T> {
91 #[inline(always)]
92 fn from(fixed: crate::Fixed<T>) -> Self {
93 Zeroizing::new(fixed.0)
94 }
95}
96
97#[cfg(feature = "zeroize")]
98impl<T: ?Sized + Zeroize> From<crate::Dynamic<T>> for DynamicZeroizing<T> {
99 #[inline(always)]
100 fn from(dynamic: crate::Dynamic<T>) -> Self {
101 Self(SecretBox::new(dynamic.0))
102 }
103}
104
105#[cfg(feature = "zeroize")]
107impl<T: Zeroize> Zeroize for crate::Fixed<T> {
108 fn zeroize(&mut self) {
109 self.0.zeroize();
110 }
111}
112
113#[cfg(feature = "zeroize")]
114impl<T: Zeroize + DefaultIsZeroes> Zeroize for crate::Dynamic<T> {
115 fn zeroize(&mut self) {
116 self.0.zeroize();
117 }
118}
119
120#[cfg(feature = "zeroize")]
121impl<T: Zeroize> ZeroizeOnDrop for crate::Fixed<T> {}
122
123#[cfg(feature = "zeroize")]
124impl<T: ?Sized + Zeroize> ZeroizeOnDrop for crate::Dynamic<T> {}
125
126#[cfg(feature = "zeroize")]
128impl<T: Zeroize + Send + 'static> From<T> for DynamicZeroizing<T> {
129 #[inline(always)]
130 fn from(value: T) -> Self {
131 Self::new(Box::new(value))
132 }
133}
134
135#[cfg(feature = "zeroize")]
136impl<T: Zeroize + DefaultIsZeroes + Send + 'static> From<Box<T>> for DynamicZeroizing<T> {
137 #[inline(always)]
138 fn from(boxed: Box<T>) -> Self {
139 Self::new(boxed)
140 }
141}
142
143#[cfg(feature = "zeroize")]
144impl From<&str> for DynamicZeroizing<String> {
145 #[inline(always)]
146 fn from(s: &str) -> Self {
147 Self::new(Box::new(s.to_string()))
148 }
149}