#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
use std::{
collections::{HashMap, HashSet},
ops::Deref,
};
pub use expunge_derive::*;
pub mod primitives;
pub mod utils;
#[cfg(feature = "zeroize")]
#[doc(hidden)]
pub use ::zeroize;
#[cfg(feature = "zeroize")]
use secrecy::Secret;
#[cfg(feature = "zeroize")]
use zeroize::{DefaultIsZeroes, Zeroize};
#[cfg(feature = "zeroize")]
#[doc(hidden)]
pub use ::secrecy;
#[cfg(feature = "serde")]
#[doc(hidden)]
pub use ::serde;
pub trait Expunge {
fn expunge(self) -> Self
where
Self: Sized;
}
impl<T> Expunge for Option<T>
where
T: Expunge,
{
fn expunge(self) -> Self
where
Self: Sized,
{
self.map(Expunge::expunge)
}
}
impl<R, E> Expunge for Result<R, E>
where
R: Expunge,
E: Expunge,
{
fn expunge(self) -> Self
where
Self: Sized,
{
match self {
Ok(v) => Ok(v.expunge()),
Err(e) => Err(e.expunge()),
}
}
}
pub struct Expunged<T>(T);
impl<T> From<T> for Expunged<T>
where
T: Expunge,
{
fn from(value: T) -> Self {
Expunged(value.expunge())
}
}
#[allow(dead_code)]
impl<T> Expunged<T> {
fn into_inner(self) -> T {
self.0
}
}
impl<T> Deref for Expunged<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> std::fmt::Display for Expunged<T>
where
T: std::fmt::Display,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl<T> std::fmt::Debug for Expunged<T>
where
T: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl<T> Expunge for Vec<T>
where
T: Expunge,
{
fn expunge(self) -> Self
where
Self: Sized,
{
self.into_iter().map(Expunge::expunge).collect()
}
}
impl<K, V> Expunge for HashMap<K, V>
where
K: std::hash::Hash + std::cmp::Eq,
V: Expunge,
{
fn expunge(self) -> Self
where
Self: Sized,
{
self.into_iter().map(|(k, v)| (k, v.expunge())).collect()
}
}
impl<T> Expunge for HashSet<T>
where
T: Expunge + std::hash::Hash + std::cmp::Eq,
{
fn expunge(self) -> Self
where
Self: Sized,
{
self.into_iter().map(Expunge::expunge).collect()
}
}
impl<T> Expunge for Box<T>
where
T: Expunge,
{
fn expunge(self) -> Self
where
Self: Sized,
{
Box::new((*self).expunge())
}
}
#[cfg(feature = "zeroize")]
impl<T> Expunge for Secret<T>
where
T: DefaultIsZeroes,
T: Zeroize,
{
fn expunge(self) -> Self
where
Self: Sized,
{
self
}
}