Skip to content

Commit

Permalink
Make SingletonMap public
Browse files Browse the repository at this point in the history
It can be used in cases where #[serde(with = "singleton_map")] is too
restrictive, for example where custom `with` modules are required.

Fixes #1

Signed-off-by: Alan Somers <[email protected]>
  • Loading branch information
asomers committed May 24, 2024
1 parent bc4172a commit 119b276
Showing 1 changed file with 63 additions and 16 deletions.
79 changes: 63 additions & 16 deletions src/with.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,7 @@ pub mod singleton_map {
T: Serialize,
S: Serializer,
{
value.serialize(SingletonMap {
delegate: serializer,
})
value.serialize(SingletonMap::new(serializer))
}

#[allow(missing_docs)]
Expand All @@ -100,15 +98,66 @@ pub mod singleton_map {
T: Deserialize<'de>,
D: Deserializer<'de>,
{
T::deserialize(SingletonMap {
delegate: deserializer,
})
T::deserialize(SingletonMap::new(deserializer))
}

struct SingletonMap<D> {
/// Can be used for serialing/deserializing an enum using a YAML map containing one entry in
/// which the key identifies the variant name.
///
/// Unlike [`#[serde(with = "singleton_map")`](crate::with::singleton_map) this struct can be
/// used from within a custom `Serialize` implementation or from within another `with` module.
///
/// # Example
/// ```
/// use std::sync::Mutex;
/// use serde_derive::{Deserialize, Serialize};
/// use serde::{Deserialize, Serialize};
/// use serde_yaml_ng::with::singleton_map::SingletonMap;
///
/// #[derive(Serialize, Deserialize)]
/// enum Bar {
/// A(u32),
/// B(f32)
/// }
/// #[derive(Serialize, Deserialize)]
/// struct Foo {
/// #[serde(with = "bar_serializer")]
/// // Because it has a Mutex, we can't simply derive Serialize/Deserialize here, nor can
/// // we use `#[serde(with = "serde_yaml_ng::with::singleton_map")]`. We need a custom
/// // `with` module to deal with the Mutex.
/// bar: Mutex<Bar>
/// }
///
/// mod bar_serializer {
/// use serde::{de::Deserializer, Serializer};
/// use super::*;
///
/// pub fn deserialize<'de, D>(deserializer: D) -> Result<Mutex<Bar>, D::Error>
/// where D: Deserializer<'de>
/// {
/// Bar::deserialize(SingletonMap::new(deserializer))
/// .map(Mutex::new)
/// }
/// pub fn serialize<S>(bar: &Mutex<Bar>, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer
/// {
/// let guard = bar.try_lock().unwrap();
/// (*guard).serialize(SingletonMap::new(serializer))
/// }
/// }
/// # fn main() {}
/// ```
pub struct SingletonMap<D> {
delegate: D,
}

impl<D> SingletonMap<D> {
/// Create a new `SingletonMap`, wrapping either a `Serializer` or a `Deserializer`.
pub fn new(delegate: D) -> Self {
SingletonMap {delegate}
}
}

impl<D> Serialize for SingletonMap<D>
where
D: Serialize,
Expand All @@ -117,9 +166,7 @@ pub mod singleton_map {
where
S: Serializer,
{
self.delegate.serialize(SingletonMap {
delegate: serializer,
})
self.delegate.serialize(SingletonMap::new(serializer))
}
}

Expand Down Expand Up @@ -255,7 +302,7 @@ pub mod singleton_map {
V: ?Sized + Serialize,
{
self.delegate
.serialize_some(&SingletonMap { delegate: value })
.serialize_some(&SingletonMap::new(value))
}

fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
Expand Down Expand Up @@ -324,7 +371,8 @@ pub mod singleton_map {
}
}

struct SerializeTupleVariantAsSingletonMap<M> {
#[doc(hidden)]
pub struct SerializeTupleVariantAsSingletonMap<M> {
map: M,
sequence: Sequence,
}
Expand Down Expand Up @@ -353,7 +401,8 @@ pub mod singleton_map {
}
}

struct SerializeStructVariantAsSingletonMap<M> {
#[doc(hidden)]
pub struct SerializeStructVariantAsSingletonMap<M> {
map: M,
mapping: Mapping,
}
Expand Down Expand Up @@ -688,9 +737,7 @@ pub mod singleton_map {
where
D: Deserializer<'de>,
{
self.delegate.visit_some(SingletonMap {
delegate: deserializer,
})
self.delegate.visit_some(SingletonMap::new(deserializer))
}

fn visit_unit<E>(self) -> Result<Self::Value, E>
Expand Down

0 comments on commit 119b276

Please sign in to comment.