secure_gate/
dynamic.rs

1// src/dynamic.rs
2use alloc::boxed::Box;
3use core::ops::{Deref, DerefMut};
4
5use 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    pub fn view(&self) -> Expose<'_, T> {
47        Expose(&self.0)
48    }
49
50    pub fn view_mut(&mut self) -> ExposeMut<'_, T> {
51        ExposeMut(&mut self.0)
52    }
53}
54
55impl<T: ?Sized> Dynamic<T> {
56    pub fn into_inner(self) -> Box<T> {
57        self.0
58    }
59}
60
61// Clone — conditional on feature to avoid double-boxing
62#[cfg(not(feature = "zeroize"))]
63impl<T: Clone> Clone for Dynamic<T>
64where
65    T: ?Sized,
66{
67    fn clone(&self) -> Self {
68        Dynamic(self.0.clone())
69    }
70}
71
72#[cfg(feature = "zeroize")]
73impl<T: Clone + zeroize::Zeroize> Clone for Dynamic<T> {
74    fn clone(&self) -> Self {
75        // Direct clone of SecretBox<T> — no new_boxed
76        Dynamic(self.0.clone())
77    }
78}
79
80// finish_mut
81impl Dynamic<String> {
82    pub fn finish_mut(&mut self) -> &mut String {
83        let s = &mut **self;
84        s.shrink_to_fit();
85        s
86    }
87}
88impl Dynamic<Vec<u8>> {
89    pub fn finish_mut(&mut self) -> &mut Vec<u8> {
90        let v = &mut **self;
91        v.shrink_to_fit();
92        v
93    }
94}