1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
use std::fmt::{Debug, Formatter};

/// String with hidden debug implementation
#[derive(serde::Deserialize, PartialEq, PartialOrd, Eq, Ord, Clone)]
#[repr(transparent)]
#[serde(transparent)]
pub struct SecretString(pub String);

impl Debug for SecretString {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let type_name = std::any::type_name::<Self>()
            .rsplit_once("::")
            .map_or(std::any::type_name::<Self>(), |(_, i)| i);
        f.debug_struct(type_name).finish_non_exhaustive()
    }
}

impl From<String> for SecretString {
    fn from(value: String) -> Self {
        Self(value)
    }
}

impl From<SecretString> for String {
    fn from(value: SecretString) -> Self {
        value.0
    }
}