diff --git a/src/serde_helpers.rs b/src/serde_helpers.rs index 04917f1c..a8877bdf 100644 --- a/src/serde_helpers.rs +++ b/src/serde_helpers.rs @@ -1,6 +1,11 @@ //! Collection of helper functions for serializing to and deserializing from BSON using Serde -use std::{convert::TryFrom, marker::PhantomData, result::Result}; +use std::{ + convert::TryFrom, + marker::PhantomData, + ops::{Deref, DerefMut}, + result::Result, +}; use serde::{de::Visitor, ser, Deserialize, Serialize, Serializer}; @@ -718,7 +723,8 @@ pub mod timestamp_as_u32 { /// Wrapping a type in `HumanReadable` signals to the BSON serde integration that it and all /// recursively contained types should be serialized to and deserialized from their human-readable /// formats. -#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)] +#[repr(transparent)] pub struct HumanReadable(pub T); pub(crate) const HUMAN_READABLE_NEWTYPE: &str = "$__bson_private_human_readable"; @@ -754,6 +760,56 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for HumanReadable { } } +impl std::fmt::Display for HumanReadable { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl From for HumanReadable { + fn from(value: T) -> Self { + Self(value) + } +} + +impl Deref for HumanReadable { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for HumanReadable { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl AsRef for HumanReadable +where + R: ?Sized, + as Deref>::Target: AsRef, +{ + fn as_ref(&self) -> &R { + self.deref().as_ref() + } +} + +impl AsMut for HumanReadable +where + as Deref>::Target: AsMut, +{ + fn as_mut(&mut self) -> &mut R { + self.deref_mut().as_mut() + } +} + +// One could imagine passthrough Borrow impls; however, it turns out that can't be made to work +// because of the existing base library impl of Borrow for T will conflict despite that not +// actually being possible to construct (https://github.com/rust-lang/rust/issues/50237). So, +// sadly, Borrow impls for HumanReadable are deliberately omitted :( + /// Wrapper type for deserializing BSON bytes with invalid UTF-8 sequences. /// /// Any invalid UTF-8 strings contained in the wrapped type will be replaced with the Unicode