secret_vault_value/
value_serde.rs1use crate::*;
2use serde::de::{self, Visitor};
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use zeroize::Zeroize;
5
6impl SecretValue {
7 pub fn expose_json_value_as<T>(&self) -> serde_json::Result<T>
34 where
35 for<'de> T: Deserialize<'de> + Zeroize,
36 {
37 serde_json::from_slice(self.ref_sensitive_value())
38 }
39}
40
41impl Serialize for SecretValue {
45 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
46 where
47 S: Serializer,
48 {
49 serializer.serialize_str(
50 String::from_utf8(self.ref_sensitive_value().clone())
51 .map_err(serde::ser::Error::custom)?
52 .as_str(),
53 )
54 }
55}
56
57struct SecretValueVisitor;
58
59#[allow(clippy::needless_lifetimes)]
60impl<'de> Visitor<'de> for SecretValueVisitor {
61 type Value = SecretValue;
62
63 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
64 formatter.write_str("a string expected as a secret value")
65 }
66
67 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
68 where
69 E: de::Error,
70 {
71 Ok(SecretValue::new(value.as_bytes().to_vec()))
72 }
73
74 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
75 where
76 E: de::Error,
77 {
78 Ok(SecretValue::new(value.into_bytes()))
79 }
80
81 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
82 where
83 E: de::Error,
84 {
85 Ok(SecretValue::new(value.to_vec()))
86 }
87
88 fn visit_byte_buf<E>(self, value: Vec<u8>) -> Result<Self::Value, E>
89 where
90 E: de::Error,
91 {
92 Ok(SecretValue::new(value))
93 }
94}
95
96impl<'de> Deserialize<'de> for SecretValue {
98 fn deserialize<D>(deserializer: D) -> Result<SecretValue, D::Error>
99 where
100 D: Deserializer<'de>,
101 {
102 deserializer.deserialize_string(SecretValueVisitor)
103 }
104}
105
106#[cfg(test)]
107mod test {
108 use super::*;
109 use proptest::prelude::*;
110
111 proptest! {
112 #[test]
113 fn serialize_as_string(mock_secret in "[a-zA-Z0-9]*") {
114 let mock_secret_vec = mock_secret.as_bytes().to_vec();
115 let secret_value = SecretValue::new(mock_secret_vec);
116 let test_serialized_string = serde_json::to_string(&secret_value).unwrap();
117 assert_eq!(test_serialized_string, format!("\"{}\"",mock_secret));
118 }
119
120 #[test]
121 fn deserialize_from_string(mock_secret in "[a-zA-Z0-9]*") {
122 let mock_secret_quoted = format!("\"{}\"",mock_secret);
123 let secret_value: SecretValue = serde_json::from_str(&mock_secret_quoted).unwrap();
124 assert_eq!(String::from_utf8(secret_value.ref_sensitive_value().clone()).unwrap(), mock_secret);
125 }
126 }
127
128 #[test]
129 fn deserialize_embedded_json() {
130 #[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Zeroize)]
131 struct TestJson {
132 pub test_field: String,
133 }
134 let mock_json_struct = TestJson {
135 test_field: "TestValue".into(),
136 };
137
138 let secret_value: SecretValue = serde_json::to_string(&mock_json_struct).unwrap().into();
139
140 assert_eq!(
141 secret_value.expose_json_value_as::<TestJson>().unwrap(),
142 mock_json_struct
143 );
144 }
145}