use serde::Deserialize; #[derive(Deserialize)] #[serde(untagged)] enum MaybeHelper { Some(T), None(serde::de::IgnoredAny), } /// Something that may be an `T`. /// /// Unlike `Option`, this places no restriction on whether something /// can't be something else entirely. /// /// Can only be used with self-describing formats, like JSON. #[derive(Deserialize)] #[serde(from = "Option>")] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct MayBe(pub Option); impl Default for MayBe { fn default() -> Self { Self(Default::default()) } } impl std::ops::Deref for MayBe { type Target = Option; fn deref(&self) -> &Self::Target { &self.0 } } impl std::ops::DerefMut for MayBe { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl From> for Option { fn from(thing: MayBe) -> Option { thing.0 } } impl From> for MayBe { fn from(thing: Option) -> MayBe { Self(thing) } } impl From>> for MayBe { fn from(thing: Option>) -> MayBe { Self(match thing { Some(MaybeHelper::Some(v)) => Some(v), _ => None, }) } }