use serde::{ser::Error, Deserialize, Deserializer, Serialize, Serializer}; #[derive(Clone, Debug, PartialEq, Eq)] pub enum OptionSerializer { Some(T), None, Skip, } impl OptionSerializer { pub fn none() -> Self { Self::None } pub fn skip() -> Self { Self::Skip } pub fn should_skip(&self) -> bool { matches!(self, Self::Skip) } pub fn or_skip(option: Option) -> Self { match option { Option::Some(item) => Self::Some(item), Option::None => Self::Skip, } } pub fn as_ref(&self) -> OptionSerializer<&T> { match self { OptionSerializer::Some(item) => OptionSerializer::Some(item), OptionSerializer::None => OptionSerializer::None, OptionSerializer::Skip => OptionSerializer::Skip, } } } impl From> for OptionSerializer { fn from(option: Option) -> Self { match option { Option::Some(item) => Self::Some(item), Option::None => Self::None, } } } impl From> for Option { fn from(option: OptionSerializer) -> Self { match option { OptionSerializer::Some(item) => Self::Some(item), _ => Self::None, } } } impl Serialize for OptionSerializer { fn serialize(&self, serializer: S) -> Result where S: Serializer, { match self { Self::Some(item) => item.serialize(serializer), Self::None => serializer.serialize_none(), Self::Skip => Err(Error::custom("Skip variants should not be serialized")), } } } impl<'de, T: Deserialize<'de>> Deserialize<'de> for OptionSerializer { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { Option::deserialize(deserializer).map(Into::into) } }