openvpn_mgmt_codec/
redacted.rs1use derive_more::{Debug, Display};
5
6#[derive(Clone, PartialEq, Eq, Debug, Display)]
24#[debug("<redacted>")]
25#[display("<redacted>")]
26pub struct Redacted(String);
27
28impl Redacted {
29 pub fn new(value: impl Into<String>) -> Self {
31 Self(value.into())
32 }
33
34 pub fn expose(&self) -> &str {
40 &self.0
41 }
42
43 pub fn into_inner(self) -> String {
45 self.0
46 }
47}
48
49impl From<String> for Redacted {
50 fn from(s: String) -> Self {
51 Self(s)
52 }
53}
54
55impl From<&str> for Redacted {
56 fn from(s: &str) -> Self {
57 Self(s.to_string())
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn debug_is_redacted() {
67 let r = Redacted::new("secret");
68 assert_eq!(format!("{r:?}"), "<redacted>");
69 }
70
71 #[test]
72 fn display_is_redacted() {
73 let r = Redacted::new("secret");
74 assert_eq!(format!("{r}"), "<redacted>");
75 }
76
77 #[test]
78 fn expose_returns_inner() {
79 let r = Redacted::new("hunter2");
80 assert_eq!(r.expose(), "hunter2");
81 }
82
83 #[test]
84 fn into_inner_returns_owned() {
85 let r = Redacted::new("pass");
86 assert_eq!(r.into_inner(), "pass");
87 }
88
89 #[test]
90 fn from_string() {
91 let r: Redacted = "hello".to_string().into();
92 assert_eq!(r.expose(), "hello");
93 }
94
95 #[test]
96 fn from_str() {
97 let r: Redacted = "hello".into();
98 assert_eq!(r.expose(), "hello");
99 }
100
101 #[test]
102 fn equality() {
103 let a = Redacted::new("same");
104 let b = Redacted::new("same");
105 let c = Redacted::new("different");
106 assert_eq!(a, b);
107 assert_ne!(a, c);
108 }
109}