Skip to main content

synapto_interface/
secrets.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4/// A wrapper that redacts its contents in Debug logs and Serialization (UI/API),
5/// requiring explicit method calls to access the underlying value.
6#[derive(Clone, Default, Deserialize)]
7#[serde(transparent)]
8pub struct Secret<T>(T);
9
10impl<T> Secret<T> {
11    /// Creates a new Secret.
12    pub fn new(value: T) -> Self {
13        Self(value)
14    }
15
16    /// Explicitly exposes the secret by reference.
17    #[inline]
18    pub fn expose_secret(&self) -> &T {
19        &self.0
20    }
21
22    /// Consumes the wrapper and returns the raw secret.
23    #[inline]
24    pub fn expose_owned_secret(self) -> T {
25        self.0
26    }
27
28    #[inline]
29    pub fn into_secret<U>(self) -> Secret<U>
30    where
31        T: Into<U>,
32    {
33        Secret(self.0.into())
34    }
35}
36
37impl<T> fmt::Debug for Secret<T> {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        write!(f, "[REDACTED]")
40    }
41}
42
43impl<T> Serialize for Secret<T> {
44    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
45    where
46        S: serde::Serializer,
47    {
48        // Always serializes as a generic string, regardless of inner type T
49        serializer.serialize_str("[REDACTED]")
50    }
51}