secure_gate/
dynamic.rs

1// src/dynamic.rs
2use alloc::boxed::Box;
3use core::ops::{Deref, DerefMut};
4
5// use crate::{Expose, ExposeMut};
6
7pub struct Dynamic<T: ?Sized>(pub Box<T>); // ← pub field
8
9impl<T: ?Sized> Dynamic<T> {
10    #[inline(always)]
11    pub fn new_boxed(value: Box<T>) -> Self {
12        Dynamic(value)
13    }
14
15    #[inline(always)]
16    pub fn new<U>(value: U) -> Self
17    where
18        U: Into<Box<T>>,
19    {
20        Dynamic(value.into())
21    }
22}
23
24impl<T: ?Sized> Deref for Dynamic<T> {
25    type Target = T;
26    #[inline(always)]
27    fn deref(&self) -> &T {
28        &self.0
29    }
30}
31
32impl<T: ?Sized> DerefMut for Dynamic<T> {
33    #[inline(always)]
34    fn deref_mut(&mut self) -> &mut T {
35        &mut self.0
36    }
37}
38
39impl<T: ?Sized> core::fmt::Debug for Dynamic<T> {
40    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
41        f.write_str("[REDACTED]")
42    }
43}
44
45impl<T: ?Sized> Dynamic<T> {
46    #[inline(always)]
47    pub fn expose_secret(&self) -> &T {
48        &self.0
49    }
50
51    #[inline(always)]
52    pub fn expose_secret_mut(&mut self) -> &mut T {
53        &mut self.0
54    }
55
56    // Legacy → redirect to the new names
57    #[deprecated(since = "0.5.5", note = "use `expose_secret` instead")]
58    #[doc(hidden)]
59    #[inline(always)]
60    pub fn view(&self) -> &T {
61        self.expose_secret()
62    }
63
64    #[deprecated(since = "0.5.5", note = "use `expose_secret_mut` instead")]
65    #[doc(hidden)]
66    #[inline(always)]
67    pub fn view_mut(&mut self) -> &mut T {
68        self.expose_secret_mut()
69    }
70}
71
72impl<T: ?Sized> Dynamic<T> {
73    pub fn into_inner(self) -> Box<T> {
74        self.0
75    }
76}
77
78// Clone — conditional on feature to avoid double-boxing
79#[cfg(not(feature = "zeroize"))]
80impl<T: Clone> Clone for Dynamic<T>
81where
82    T: ?Sized,
83{
84    fn clone(&self) -> Self {
85        Dynamic(self.0.clone())
86    }
87}
88
89#[cfg(feature = "zeroize")]
90impl<T: Clone + zeroize::Zeroize> Clone for Dynamic<T> {
91    fn clone(&self) -> Self {
92        // Direct clone of SecretBox<T> — no new_boxed
93        Dynamic(self.0.clone())
94    }
95}
96
97// finish_mut
98impl Dynamic<String> {
99    pub fn finish_mut(&mut self) -> &mut String {
100        let s = &mut **self;
101        s.shrink_to_fit();
102        s
103    }
104}
105impl Dynamic<Vec<u8>> {
106    pub fn finish_mut(&mut self) -> &mut Vec<u8> {
107        let v = &mut **self;
108        v.shrink_to_fit();
109        v
110    }
111}