|
1 | 1 | //! Collection of helper functions for serializing to and deserializing from BSON using Serde |
2 | 2 |
|
3 | | -use std::{convert::TryFrom, result::Result}; |
| 3 | +use std::{convert::TryFrom, marker::PhantomData, result::Result}; |
4 | 4 |
|
5 | | -use serde::{ser, Serialize, Serializer}; |
| 5 | +use serde::{de::Visitor, ser, Deserialize, Serialize, Serializer}; |
6 | 6 |
|
7 | 7 | use crate::oid::ObjectId; |
8 | 8 |
|
@@ -794,3 +794,44 @@ pub mod timestamp_as_u32 { |
794 | 794 | Ok(Timestamp { time, increment: 0 }) |
795 | 795 | } |
796 | 796 | } |
| 797 | + |
| 798 | +/// Wrapping a type in `HumanReadable` signals to the BSON serde integration that it and all |
| 799 | +/// recursively contained types should be handled as if |
| 800 | +/// [`SerializerOptions::human_readable`](crate::SerializerOptions::human_readable) and |
| 801 | +/// [`DeserializerOptions::human_readable`](crate::DeserializerOptions::human_readable) are |
| 802 | +/// set to `true`. |
| 803 | +#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)] |
| 804 | +pub struct HumanReadable<T>(pub T); |
| 805 | + |
| 806 | +pub(crate) const HUMAN_READABLE_NEWTYPE: &str = "$__bson_private_human_readable"; |
| 807 | + |
| 808 | +impl<T: Serialize> Serialize for HumanReadable<T> { |
| 809 | + fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> |
| 810 | + where |
| 811 | + S: serde::Serializer, |
| 812 | + { |
| 813 | + serializer.serialize_newtype_struct(HUMAN_READABLE_NEWTYPE, &self.0) |
| 814 | + } |
| 815 | +} |
| 816 | + |
| 817 | +impl<'de, T: Deserialize<'de>> Deserialize<'de> for HumanReadable<T> { |
| 818 | + fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error> |
| 819 | + where |
| 820 | + D: serde::Deserializer<'de>, |
| 821 | + { |
| 822 | + struct V<T>(PhantomData<fn() -> T>); |
| 823 | + impl<'de, T: Deserialize<'de>> Visitor<'de> for V<T> { |
| 824 | + type Value = HumanReadable<T>; |
| 825 | + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { |
| 826 | + formatter.write_str("HumanReadable wrapper") |
| 827 | + } |
| 828 | + fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error> |
| 829 | + where |
| 830 | + D: serde::Deserializer<'de>, |
| 831 | + { |
| 832 | + T::deserialize(deserializer).map(HumanReadable) |
| 833 | + } |
| 834 | + } |
| 835 | + deserializer.deserialize_newtype_struct(HUMAN_READABLE_NEWTYPE, V(PhantomData)) |
| 836 | + } |
| 837 | +} |
0 commit comments