use std::fmt;
use std::ops::Deref;
use serde::{Deserialize, Serialize};
#[derive(Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Secret<T> {
inner: T,
}
impl<T> Secret<T> {
pub fn expose(self) -> T {
self.inner
}
pub fn as_deref(&self) -> Secret<&<T as Deref>::Target>
where
T: Deref,
{
Secret::from(self.inner.deref())
}
pub fn as_ref(&self) -> Secret<&T> {
Secret::from(&self.inner)
}
pub fn map<U, F>(self, f: F) -> Secret<U>
where
F: FnOnce(T) -> U,
{
Secret::from(f(self.inner))
}
}
impl<T: ToOwned + ?Sized> Secret<&T> {
pub fn to_owned(&self) -> Secret<<T as ToOwned>::Owned> {
Secret::from(self.inner.to_owned())
}
}
impl<T, E> Secret<Result<T, E>> {
pub fn transpose(self) -> Result<Secret<T>, E> {
self.inner.map(|v| Secret::from(v))
}
}
impl<T: AsRef<str>> Secret<T> {
pub fn is_empty(&self) -> bool {
self.inner.as_ref().is_empty()
}
}
impl<T> From<T> for Secret<T> {
fn from(inner: T) -> Self {
Self { inner }
}
}
impl<T> fmt::Debug for Secret<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Secret")
.field("inner", &"REDACTED")
.finish()
}
}