use serde::de::{Deserialize, DeserializeOwned, Deserializer};
use std::fmt::{self, Debug};
use util::Clear;
#[derive(Clone)]
pub struct Secret<T>(T)
where
T: Clear + Clone + DebugSecret + DeserializeOwned + Sized;
impl<T> BorrowSecret<T> for Secret<T>
where
T: Clear + Clone + DebugSecret + DeserializeOwned + Sized,
{
fn borrow_secret(&self) -> &T {
&self.0
}
}
impl<T> Debug for Secret<T>
where
T: Clear + Clone + DebugSecret + DeserializeOwned + Sized,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Secret({})", self.0.debug_secret())
}
}
impl<'de, T> Deserialize<'de> for Secret<T>
where
T: Clear + Clone + DebugSecret + DeserializeOwned + Sized,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(Secret)
}
}
impl<T> Drop for Secret<T>
where
T: Clear + Clone + DebugSecret + DeserializeOwned + Sized,
{
fn drop(&mut self) {
self.0.clear();
}
}
pub trait BorrowSecret<BorrowedSecret> {
fn borrow_secret(&self) -> &BorrowedSecret;
}
pub trait DebugSecret {
fn debug_secret(&self) -> &'static str;
}