secret_value/
lib.rs

1use std::{fmt, ops};
2
3#[repr(transparent)]
4#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Default)]
5pub struct Secret<T>(T);
6
7impl<T> From<T> for Secret<T> {
8    fn from(t: T) -> Self {
9        Self(t)
10    }
11}
12
13impl<T> Secret<T> {
14    pub fn inner(self) -> T {
15        self.0
16    }
17}
18
19impl<T> ops::Deref for Secret<T> {
20    type Target = T;
21
22    fn deref(&self) -> &Self::Target {
23        &self.0
24    }
25}
26
27impl<T> ops::DerefMut for Secret<T> {
28    fn deref_mut(&mut self) -> &mut Self::Target {
29        &mut self.0
30    }
31}
32
33impl<T> fmt::Debug for Secret<T> {
34    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35        write!(f, "<hidden>")
36    }
37}
38
39impl<T> fmt::Display for Secret<T> {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        write!(f, "<hidden>")
42    }
43}
44
45#[cfg(feature = "serde")]
46mod serde {
47    use serde::{Deserialize, Deserializer, Serialize, Serializer};
48
49    use super::Secret;
50
51    impl<'de, T: Deserialize<'de>> Deserialize<'de> for Secret<T> {
52        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
53        where
54            D: Deserializer<'de>,
55        {
56            T::deserialize(deserializer).map(Self)
57        }
58    }
59
60    impl<T: Serialize> Serialize for super::Secret<T> {
61        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
62        where
63            S: Serializer,
64        {
65            serializer.serialize_str("<hidden>")
66        }
67    }
68
69    pub fn insecure_serialize<T: Serialize, S>(x: &Secret<T>, s: S) -> Result<S::Ok, S::Error>
70    where
71        S: Serializer,
72    {
73        x.0.serialize(s)
74    }
75}
76
77#[cfg(feature = "serde")]
78pub use self::serde::insecure_serialize;
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[cfg(feature = "serde")]
85    #[test]
86    fn test_insecure_serialize() {
87        use serde_test::{assert_tokens, Token};
88        #[derive(::serde::Serialize, ::serde::Deserialize, PartialEq, Debug)]
89        struct X {
90            #[serde(serialize_with = "insecure_serialize")]
91            y: Secret<u32>,
92        }
93        let x = X { y: Secret(1) };
94        assert_tokens(
95            &x,
96            &[
97                Token::Struct { name: "X", len: 1 },
98                Token::Str("y"),
99                Token::U32(1),
100                Token::StructEnd,
101            ],
102        );
103    }
104
105    #[cfg(feature = "serde")]
106    #[test]
107    fn test_secure_serialize() {
108        use serde_test::{assert_de_tokens, assert_ser_tokens, Token};
109        #[derive(::serde::Serialize, ::serde::Deserialize, PartialEq, Debug)]
110        struct X {
111            z: Secret<u32>,
112        }
113        let x = X { z: Secret(1) };
114        assert_ser_tokens(
115            &x,
116            &[
117                Token::Struct { name: "X", len: 1 },
118                Token::Str("z"),
119                Token::Str("<hidden>"),
120                Token::StructEnd,
121            ],
122        );
123        assert_de_tokens(
124            &x,
125            &[
126                Token::Struct { name: "X", len: 1 },
127                Token::Str("z"),
128                Token::U32(1),
129                Token::StructEnd,
130            ],
131        );
132    }
133}