use std::fmt;
use serde::Deserialize;
use zeroize::Zeroizing;
#[derive(Deserialize)]
#[serde(transparent)]
pub struct Secret(Zeroizing<String>);
impl Secret {
pub fn new(s: impl Into<String>) -> Self {
Self(Zeroizing::new(s.into()))
}
#[must_use]
pub fn expose(&self) -> &str {
self.0.as_str()
}
}
impl fmt::Debug for Secret {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("[REDACTED]")
}
}
impl fmt::Display for Secret {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("[REDACTED]")
}
}
#[derive(Debug, thiserror::Error)]
pub enum VaultError {
#[error("secret not found: {0}")]
NotFound(String),
#[error("vault backend error: {0}")]
Backend(String),
#[error("vault I/O error: {0}")]
Io(#[from] std::io::Error),
}