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}