1use crate::Secret;
2
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5impl<'de, T: Deserialize<'de>> Deserialize<'de> for Secret<T> {
7 #[inline]
8 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
9 T::deserialize(deserializer).map(Self)
10 }
11}
12
13pub trait SerializableSecret<T> {
18 type Exposed<'a>: Serialize
19 where
20 Self: 'a;
21 fn expose_via(&self, expose: impl Fn(&Secret<T>) -> &T) -> Self::Exposed<'_>;
24}
25
26impl<T: Serialize> SerializableSecret<T> for &Secret<T> {
27 type Exposed<'a>
28 = &'a T
29 where
30 T: 'a,
31 Self: 'a;
32
33 fn expose_via(&self, expose: impl Fn(&Secret<T>) -> &T) -> Self::Exposed<'_> {
34 expose(self)
35 }
36}
37
38impl<T: Serialize> SerializableSecret<T> for Secret<T> {
39 type Exposed<'a>
40 = &'a T
41 where
42 T: 'a;
43
44 fn expose_via(&self, expose: impl Fn(&Secret<T>) -> &T) -> Self::Exposed<'_> {
45 expose(self)
46 }
47}
48
49impl<T: Serialize> SerializableSecret<T> for Option<Secret<T>> {
50 type Exposed<'a>
51 = Option<&'a T>
52 where
53 T: 'a;
54
55 fn expose_via(&self, expose: impl Fn(&Secret<T>) -> &T) -> Self::Exposed<'_> {
56 self.as_ref().map(expose)
57 }
58}
59
60#[cfg(feature = "std")]
61impl<T: Serialize> SerializableSecret<T> for Vec<Secret<T>>
62where
63 for<'a> Vec<&'a T>: Serialize,
64{
65 type Exposed<'a>
66 = Vec<&'a T>
67 where
68 T: 'a;
69
70 fn expose_via(&self, expose: impl Fn(&Secret<T>) -> &T) -> Self::Exposed<'_> {
71 self.iter().map(expose).collect()
72 }
73}
74
75#[cfg(feature = "serde")]
83#[inline]
84pub fn expose_secret<S: Serializer, T: Serialize>(
85 secret: &impl SerializableSecret<T>,
86 serializer: S,
87) -> Result<S::Ok, S::Error> {
88 secret
89 .expose_via(Secret::expose_secret)
90 .serialize(serializer)
91}
92
93#[cfg(feature = "serde")]
103#[inline]
104pub fn redact_secret<S: Serializer, T>(
105 secret: &Secret<T>,
106 serializer: S,
107) -> Result<S::Ok, S::Error> {
108 serializer.collect_str(&format_args!("{secret:?}"))
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114 use fake::{Fake, Faker};
115 use serde::{Deserialize, Serialize};
116
117 #[test]
118 fn deserialize_the_serialized() {
119 #[derive(Serialize, Deserialize, fake::Dummy, PartialEq, Debug)]
120 struct Test {
121 #[serde(serialize_with = "expose_secret")]
122 one: Secret<String>,
123 #[serde(serialize_with = "expose_secret")]
124 two: Option<Secret<String>>,
125 #[serde(serialize_with = "expose_secret")]
126 three: Vec<Secret<String>>,
127 }
128
129 let to_serialize: Test = Faker.fake();
130
131 let serialized = serde_json::to_string(&to_serialize).unwrap();
132
133 let deserialized = serde_json::from_str(&serialized).unwrap();
134
135 assert_eq!(to_serialize, deserialized)
136 }
137}