use serde::{Serialize, Serializer};
use std::fmt;
#[derive(Clone)]
pub struct Secret<T>(pub T);
impl<T> fmt::Debug for Secret<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("[REDACTED]")
}
}
impl<T> fmt::Display for Secret<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("••••••")
}
}
impl<T> Serialize for Secret<T> {
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
unreachable!("Secret should never be serialized")
}
}
impl<T> Secret<T> {
pub fn new(value: T) -> Self {
Secret(value)
}
pub fn inner(&self) -> &T {
&self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_secret_debug() {
let secret = Secret("api-key-123");
assert_eq!(format!("{:?}", secret), "[REDACTED]");
}
#[test]
fn test_secret_display() {
let secret = Secret("api-key-123");
assert_eq!(format!("{}", secret), "••••••");
}
#[test]
fn test_secret_inner() {
let secret = Secret("api-key-123");
assert_eq!(secret.inner(), &"api-key-123");
}
}