Skip to main content

nexus_sdk/types/
secret_value.rs

1//! String wrapper for type safety around our secret strings. Also implements
2//! custom display that avoids leaking the secret in logs.
3
4use {
5    serde::{Deserialize, Serialize},
6    zeroize::{Zeroize, ZeroizeOnDrop},
7};
8
9#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Zeroize, ZeroizeOnDrop)]
10pub struct SecretValue(String);
11
12impl From<String> for SecretValue {
13    fn from(s: String) -> Self {
14        SecretValue(s)
15    }
16}
17
18impl From<&str> for SecretValue {
19    fn from(s: &str) -> Self {
20        SecretValue(s.to_string())
21    }
22}
23
24impl SecretValue {
25    pub fn peek(&self) -> &str {
26        &self.0
27    }
28}
29
30impl std::fmt::Debug for SecretValue {
31    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32        write!(f, "SecretValue([Redacted: *****])",)
33    }
34}
35
36impl std::fmt::Display for SecretValue {
37    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38        write!(f, "[Redacted: *****]")
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::SecretValue;
45
46    #[test]
47    fn test_secret_value_from_string_and_str() {
48        let s = "supersecret";
49        let sv1 = SecretValue::from(s.to_string());
50        let sv2 = SecretValue::from(s);
51
52        assert_eq!(sv1.peek(), s);
53        assert_eq!(sv2.peek(), s);
54        assert_eq!(sv1, sv2);
55    }
56
57    #[test]
58    fn test_secret_value_debug_and_display_redacted() {
59        let secret = "averylongsupersecretvalue";
60        let sv = SecretValue::from(secret);
61        let debug_str = format!("{sv:?}");
62        let display_str = format!("{sv}");
63
64        assert_eq!(debug_str, "SecretValue([Redacted: *****])");
65        assert_eq!(display_str, "[Redacted: *****]");
66    }
67
68    #[test]
69    fn test_secret_value_debug_and_display_short_secret() {
70        let secret = "tiny";
71        let sv = SecretValue::from(secret);
72        let debug_str = format!("{sv:?}");
73        let display_str = format!("{sv}");
74
75        assert_eq!(debug_str, "SecretValue([Redacted: *****])");
76        assert_eq!(display_str, "[Redacted: *****]");
77    }
78}