1use core::{fmt, str::FromStr};
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6use zeroize::Zeroize;
7
8#[derive(Clone)]
11#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
12#[cfg_attr(feature = "serde", serde(from = "String", into = "PasswordHelper"))]
13pub struct Password(String);
14
15impl Password {
16 pub fn as_str(&self) -> &str {
17 self.0.as_str()
18 }
19}
20
21impl From<String> for Password {
22 fn from(s: String) -> Self {
23 Self(s)
24 }
25}
26
27impl From<&str> for Password {
28 fn from(s: &str) -> Self {
29 Self(s.to_owned())
30 }
31}
32
33impl FromStr for Password {
34 type Err = std::convert::Infallible; fn from_str(s: &str) -> Result<Self, Self::Err> {
36 Ok(Self(s.to_owned()))
37 }
38}
39
40impl AsRef<str> for Password {
41 fn as_ref(&self) -> &str {
42 self.0.as_ref()
43 }
44}
45
46impl fmt::Display for Password {
47 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
48 write!(f, "***password***")
49 }
50}
51
52impl fmt::Debug for Password {
53 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
54 write!(f, "***password***")
55 }
56}
57
58impl Drop for Password {
59 fn drop(&mut self) {
60 unsafe { self.0.as_mut_vec().zeroize() }
61 }
62}
63
64#[cfg(feature = "serde")]
68#[derive(Serialize)]
69#[serde(transparent)]
70struct PasswordHelper(String);
71
72#[cfg(feature = "serde")]
73impl From<Password> for PasswordHelper {
74 fn from(src: Password) -> PasswordHelper {
75 PasswordHelper(src.to_string())
76 }
77}