vgi_forge_github/
secret.rs1use std::fmt;
4
5use zeroize::Zeroizing;
6
7pub struct Secret(Zeroizing<String>);
14
15impl Secret {
16 pub fn new(value: impl Into<String>) -> Self {
18 Secret(Zeroizing::new(value.into()))
19 }
20
21 pub fn expose(&self) -> &str {
23 &self.0
24 }
25}
26
27impl fmt::Debug for Secret {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 f.write_str("Secret(<redacted>)")
30 }
31}
32
33impl From<String> for Secret {
34 fn from(value: String) -> Self {
35 Secret::new(value)
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn debug_never_shows_the_value() {
45 let s = Secret::new("ghs_supersecret");
46 assert_eq!(format!("{s:?}"), "Secret(<redacted>)");
47 assert_eq!(s.expose(), "ghs_supersecret");
48 }
49}