use std::fmt::{Debug, Display, Formatter}; use std::ops::{Deref, DerefMut}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use sqlx::{Database, Encode, Type}; use sqlx::database::HasArguments; use sqlx::encode::IsNull; #[repr(transparent)] pub struct Redacted(T); impl Redacted { pub fn new(t: T) -> Self { Self(t) } pub fn into_inner(self) -> T { self.0 } pub fn as_inner(&self) -> &T { &self.0 } } impl Display for Redacted { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "[redacted]") } } impl Debug for Redacted { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "[redacted]") } } impl Deref for Redacted { type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for Redacted { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl Clone for Redacted { fn clone(&self) -> Self { Redacted(self.0.clone()) } } impl Copy for Redacted {} impl From for Redacted { fn from(t: T) -> Self { Self(t) } } impl Serialize for Redacted { fn serialize(&self, serializer: S) -> Result where S: Serializer { self.0.serialize(serializer) } } impl<'de, T: Deserialize<'de>> Deserialize<'de> for Redacted { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { T::deserialize(deserializer).map(Redacted) } } impl serde_bytes::Serialize for Redacted { fn serialize(&self, serializer: S) -> Result where S: Serializer { serde_bytes::Serialize::serialize(&self.0, serializer) } } impl<'de, T: serde_bytes::Deserialize<'de>> serde_bytes::Deserialize<'de> for Redacted { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { serde_bytes::Deserialize::deserialize(deserializer).map(Redacted) } } impl<'q, DB: Database, T: Encode<'q, DB>> Encode<'q, DB> for Redacted { fn encode(self, buf: &mut >::ArgumentBuffer) -> IsNull where Self: Sized { self.0.encode(buf) } fn encode_by_ref(&self, buf: &mut >::ArgumentBuffer) -> IsNull { self.0.encode_by_ref(buf) } fn produces(&self) -> Option { self.0.produces() } fn size_hint(&self) -> usize { self.0.size_hint() } } impl> Type for Redacted { fn type_info() -> DB::TypeInfo { T::type_info() } fn compatible(ty: &DB::TypeInfo) -> bool { T::compatible(ty) } }