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>
8 where
9 for<'de> T: Deserialize<'de> + Zeroize,
10 {
11 serde_json::from_slice(self.ref_sensitive_value())
12 }
13}
14
15impl Serialize for SecretValue {
16 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
17 where
18 S: Serializer,
19 {
20 serializer.serialize_str(
21 String::from_utf8(self.ref_sensitive_value().clone())
22 .map_err(serde::ser::Error::custom)?
23 .as_str(),
24 )
25 }
26}
27
28struct SecretValueVisitor;
29
30impl<'de> Visitor<'de> for SecretValueVisitor {
31 type Value = SecretValue;
32
33 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
34 formatter.write_str("a string expected as a secret value")
35 }
36
37 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
38 where
39 E: de::Error,
40 {
41 Ok(SecretValue::new(value.as_bytes().to_vec()))
42 }
43
44 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
45 where
46 E: de::Error,
47 {
48 Ok(SecretValue::new(value.as_bytes().to_vec()))
49 }
50
51 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
52 where
53 E: de::Error,
54 {
55 Ok(SecretValue::new(value.to_vec()))
56 }
57
58 fn visit_byte_buf<E>(self, value: Vec<u8>) -> Result<Self::Value, E>
59 where
60 E: de::Error,
61 {
62 Ok(SecretValue::new(value))
63 }
64}
65
66impl<'de> Deserialize<'de> for SecretValue {
67 fn deserialize<D>(deserializer: D) -> Result<SecretValue, D::Error>
68 where
69 D: Deserializer<'de>,
70 {
71 deserializer.deserialize_string(SecretValueVisitor)
72 }
73}
74
75#[cfg(test)]
76mod test {
77 use super::*;
78 use proptest::prelude::*;
79
80 proptest! {
81 #[test]
82 fn serialize_as_string(mock_secret in "[a-zA-Z0-9]*") {
83 let mock_secret_vec = mock_secret.as_bytes().to_vec();
84 let secret_value = SecretValue::new(mock_secret_vec);
85 let test_serialized_string = serde_json::to_string(&secret_value).unwrap();
86 assert_eq!(test_serialized_string, format!("\"{}\"",mock_secret));
87 }
88
89 #[test]
90 fn deserialize_from_string(mock_secret in "[a-zA-Z0-9]*") {
91 let mock_secret_quoted = format!("\"{}\"",mock_secret);
92 let secret_value: SecretValue = serde_json::from_str(&mock_secret_quoted).unwrap();
93 assert_eq!(String::from_utf8(secret_value.ref_sensitive_value().clone()).unwrap(), mock_secret);
94 }
95 }
96
97 #[test]
98 fn deserialize_embedded_json() {
99 #[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Zeroize)]
100 struct TestJson {
101 pub test_field: String,
102 }
103 let mock_json_struct = TestJson {
104 test_field: "TestValue".into(),
105 };
106
107 let secret_value: SecretValue = serde_json::to_string(&mock_json_struct).unwrap().into();
108
109 assert_eq!(
110 secret_value.expose_json_value_as::<TestJson>().unwrap(),
111 mock_json_struct
112 );
113 }
114}