1#![feature(specialization)]
2
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5pub trait MaybeSer {
13 const IMPL_SERIALIZE: bool;
15
16 fn maybe_serialize<S>(&self, serializer: S) -> Option<Result<S::Ok, S::Error>>
17 where
18 S: Serializer;
19}
20
21pub trait MaybeDe<'de>: Sized {
29 const IMPL_DESERIALIZE: bool;
31
32 fn maybe_deserialize<D>(deserializer: D) -> Option<Result<Self, D::Error>>
33 where
34 D: Deserializer<'de>;
35}
36
37impl<T> MaybeSer for T {
39
40 default const IMPL_SERIALIZE: bool = false;
42
43 default fn maybe_serialize<S>(
44 &self,
45 _serializer: S,
46 ) -> Option<Result<<S as Serializer>::Ok, <S as Serializer>::Error>>
47 where
48 S: Serializer,
49 {
50 None
51 }
52}
53
54impl<'de, T> MaybeDe<'de> for T {
56 default const IMPL_DESERIALIZE: bool = false;
58
59 default fn maybe_deserialize<D>(
60 _deserializer: D,
61 ) -> Option<Result<Self, <D as Deserializer<'de>>::Error>>
62 where
63 D: Deserializer<'de>,
64 {
65 None
66 }
67}
68
69impl<T> MaybeSer for T
71where
72 T: Serialize,
73{
74 const IMPL_SERIALIZE: bool = true;
76
77 fn maybe_serialize<S>(
78 &self,
79 serializer: S,
80 ) -> Option<Result<<S as Serializer>::Ok, <S as Serializer>::Error>>
81 where
82 S: Serializer,
83 {
84 Some(self.serialize(serializer))
85 }
86}
87
88impl<'de, T> MaybeDe<'de> for T
90where
91 T: Deserialize<'de>,
92{
93 const IMPL_DESERIALIZE: bool = true;
95
96 fn maybe_deserialize<D>(
97 deserializer: D,
98 ) -> Option<Result<Self, <D as Deserializer<'de>>::Error>>
99 where
100 D: Deserializer<'de>,
101 {
102 Some(T::deserialize(deserializer))
103 }
104}
105
106pub struct MaybeSerde<T>(pub Option<T>);
126
127impl<T> Into<Option<T>> for MaybeSerde<T> {
128 fn into(self) -> Option<T> { self.0 }
129}
130
131impl<T: MaybeSer> Serialize for MaybeSerde<T> {
132 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where
133 S: Serializer {
134
135 if T::IMPL_SERIALIZE {
136 match &self.0 {
137 Some(dat) => dat.maybe_serialize(serializer).unwrap(),
138 None => serializer.serialize_none(),
139 }
140 } else {
141 serializer.serialize_none()
142 }
143 }
144}
145
146impl<'de, T: MaybeDe<'de>> Deserialize<'de> for MaybeSerde<T> {
147 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where
148 D: Deserializer<'de> {
149
150 if T::IMPL_DESERIALIZE {
151 Ok(MaybeSerde(Some(T::maybe_deserialize(deserializer).unwrap()?)))
152 } else {
153 Ok(MaybeSerde(None))
154 }
155 }
156}
157
158#[cfg(test)]
159mod tests {
160 use super::{MaybeDe, MaybeSer, MaybeSerde};
161 use serde_derive::{Deserialize, Serialize};
162 use serde_json::{de::StrRead, Deserializer, Result, Serializer, to_string, from_str};
163
164 fn ser_fn<V>(val: &V) -> Option<Result<()>>
165 where
166 V: MaybeSer,
167 {
168 let mut buf = Vec::new();
169 val.maybe_serialize(&mut Serializer::new(&mut buf))
170 }
171
172 fn de_fn<'de, V>(text: &'de str) -> Option<Result<V>>
173 where
174 V: MaybeDe<'de>,
175 {
176 V::maybe_deserialize(&mut Deserializer::new(StrRead::new(text)))
177 }
178
179 struct NoneSerde(i32);
180
181 #[derive(Serialize, Deserialize)]
182 struct SomeSerde(i32);
183
184 #[test]
185 fn serde_none() {
186 struct NoneSerde(i32);
187
188 assert!(ser_fn(&NoneSerde(123)).is_none());
189 assert!(de_fn::<NoneSerde>("123").is_none());
190 }
191
192 #[test]
193 fn serde_some() {
194
195 assert!(ser_fn(&SomeSerde(123)).is_some());
196 assert_eq!(de_fn::<SomeSerde>("123").unwrap().unwrap().0, 123);
197 }
198
199 #[test]
200 fn serde_none_maybe_serde() {
201 let maybe_serde = MaybeSerde(Some(NoneSerde(123)));
202
203 assert!(to_string(&maybe_serde).is_ok());
204 assert!(from_str::<MaybeSerde<NoneSerde>>("").unwrap().0.is_none());
205 }
206
207 #[test]
208 fn serde_some_maybe_serde() {
209 let maybe_serde = MaybeSerde(Some(SomeSerde(123)));
210
211 assert_eq!(to_string(&maybe_serde).unwrap(), "123");
212 assert_eq!(from_str::<MaybeSerde<SomeSerde>>("123").unwrap().0.unwrap().0, 123);
213 }
214}