1use serde::{
2 ser::{self, Serialize},
3 Deserialize,
4};
5
6#[derive(Clone, Deserialize, Serialize)]
8#[serde(untagged)]
9pub enum Term {
10 Boolean(bool),
12
13 PositiveNumber(u64),
15
16 NegativeNumber(i64),
18
19 Float32(f32),
21
22 Float64(f64),
24
25 String(String),
27}
28
29impl std::fmt::Debug for Term {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 match self {
32 Self::Boolean(term) => term.fmt(f),
33 Self::PositiveNumber(term) => term.fmt(f),
34 Self::NegativeNumber(term) => term.fmt(f),
35 Self::Float32(term) => term.fmt(f),
36 Self::Float64(term) => term.fmt(f),
37 Self::String(term) => term.fmt(f),
38 }
39 }
40}
41
42impl PartialEq for Term {
43 fn eq(&self, other: &Self) -> bool {
44 match (self, other) {
45 (Self::Boolean(l0), Self::Boolean(r0)) => l0 == r0,
46 (Self::PositiveNumber(l0), Self::PositiveNumber(r0)) => l0 == r0,
47 (Self::NegativeNumber(l0), Self::NegativeNumber(r0)) => l0 == r0,
48 (Self::Float32(l0), Self::Float32(r0)) => l0 == r0,
49 (Self::Float64(l0), Self::Float64(r0)) => l0 == r0,
50 (Self::Float32(l0), Self::Float64(r0)) => l0 == &(*r0 as f32),
51 (Self::Float64(l0), Self::Float32(r0)) => &(*l0 as f32) == r0,
52 (Self::String(l0), Self::String(r0)) => l0 == r0,
53 _ => false,
54 }
55 }
56}
57
58impl Term {
59 pub fn new<T>(term: T) -> Option<Self>
61 where
62 T: Serialize,
63 {
64 let term = term.serialize(Serializer);
65
66 debug_assert!(term.is_ok() || term == Err(TermSerializeError::NoTerm));
67
68 term.ok()
69 }
70}
71
72struct Serializer;
73
74impl ser::Serializer for Serializer {
75 type Error = TermSerializeError;
76 type Ok = Term;
77 type SerializeMap = Self;
78 type SerializeSeq = Self;
79 type SerializeStruct = Self;
80 type SerializeStructVariant = Self;
81 type SerializeTuple = Self;
82 type SerializeTupleStruct = Self;
83 type SerializeTupleVariant = Self;
84
85 fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
86 Ok(Term::Boolean(v))
87 }
88
89 fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
90 self.serialize_i64(v as i64)
91 }
92
93 fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
94 self.serialize_i64(v as i64)
95 }
96
97 fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
98 self.serialize_i64(v as i64)
99 }
100
101 fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
102 if v < 0 {
103 Ok(Term::NegativeNumber(v))
104 } else {
105 Ok(Term::PositiveNumber(v as u64))
106 }
107 }
108
109 fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
110 self.serialize_u64(v as u64)
111 }
112
113 fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
114 self.serialize_u64(v as u64)
115 }
116
117 fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
118 self.serialize_u64(v as u64)
119 }
120
121 fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
122 Ok(Term::PositiveNumber(v))
123 }
124
125 fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
126 Ok(Term::Float32(v))
127 }
128
129 fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
130 Ok(Term::Float64(v))
131 }
132
133 fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
134 let v = String::from(v);
135
136 if v.is_empty() {
137 Err(TermSerializeError::NoTerm)
138 } else {
139 Ok(Term::String(v))
140 }
141 }
142
143 fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
144 let v = String::from(v);
145
146 if v.is_empty() {
147 Err(TermSerializeError::NoTerm)
148 } else {
149 Ok(Term::String(v))
150 }
151 }
152
153 fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
154 Err(TermSerializeError::NotTerm)
155 }
156
157 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
158 Err(TermSerializeError::NoTerm)
159 }
160
161 fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
162 where
163 T: Serialize,
164 {
165 value.serialize(self)
166 }
167
168 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
169 Err(TermSerializeError::NotTerm)
170 }
171
172 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
173 Err(TermSerializeError::NotTerm)
174 }
175
176 fn serialize_unit_variant(
177 self,
178 _name: &'static str,
179 _variant_index: u32,
180 variant: &'static str,
181 ) -> Result<Self::Ok, Self::Error> {
182 self.serialize_str(variant)
183 }
184
185 fn serialize_newtype_struct<T: ?Sized>(
186 self,
187 _name: &'static str,
188 value: &T,
189 ) -> Result<Self::Ok, Self::Error>
190 where
191 T: Serialize,
192 {
193 value.serialize(self)
194 }
195
196 fn serialize_newtype_variant<T: ?Sized>(
197 self,
198 _name: &'static str,
199 _variant_index: u32,
200 _variant: &'static str,
201 _value: &T,
202 ) -> Result<Self::Ok, Self::Error>
203 where
204 T: Serialize,
205 {
206 Err(TermSerializeError::NotTerm)
207 }
208
209 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
210 Err(TermSerializeError::NotTerm)
211 }
212
213 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
214 Err(TermSerializeError::NotTerm)
215 }
216
217 fn serialize_tuple_struct(
218 self,
219 _name: &'static str,
220 _len: usize,
221 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
222 Err(TermSerializeError::NotTerm)
223 }
224
225 fn serialize_tuple_variant(
226 self,
227 _name: &'static str,
228 _variant_index: u32,
229 _variant: &'static str,
230 _len: usize,
231 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
232 Err(TermSerializeError::NotTerm)
233 }
234
235 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
236 Err(TermSerializeError::NotTerm)
237 }
238
239 fn serialize_struct(
240 self,
241 _name: &'static str,
242 _len: usize,
243 ) -> Result<Self::SerializeStruct, Self::Error> {
244 Err(TermSerializeError::NotTerm)
245 }
246
247 fn serialize_struct_variant(
248 self,
249 _name: &'static str,
250 _variant_index: u32,
251 _variant: &'static str,
252 _len: usize,
253 ) -> Result<Self::SerializeStructVariant, Self::Error> {
254 Err(TermSerializeError::NotTerm)
255 }
256}
257
258impl ser::SerializeSeq for Serializer {
259 type Error = TermSerializeError;
260 type Ok = Term;
261
262 fn serialize_element<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
263 where
264 T: Serialize,
265 {
266 Err(TermSerializeError::NotTerm)
267 }
268
269 fn end(self) -> Result<Self::Ok, Self::Error> {
270 Err(TermSerializeError::NotTerm)
271 }
272}
273
274impl ser::SerializeTuple for Serializer {
275 type Error = TermSerializeError;
276 type Ok = Term;
277
278 fn serialize_element<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
279 where
280 T: Serialize,
281 {
282 Err(TermSerializeError::NotTerm)
283 }
284
285 fn end(self) -> Result<Self::Ok, Self::Error> {
286 Err(TermSerializeError::NotTerm)
287 }
288}
289
290impl ser::SerializeTupleStruct for Serializer {
291 type Error = TermSerializeError;
292 type Ok = Term;
293
294 fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
295 where
296 T: Serialize,
297 {
298 Err(TermSerializeError::NotTerm)
299 }
300
301 fn end(self) -> Result<Self::Ok, Self::Error> {
302 Err(TermSerializeError::NotTerm)
303 }
304}
305impl ser::SerializeTupleVariant for Serializer {
306 type Error = TermSerializeError;
307 type Ok = Term;
308
309 fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
310 where
311 T: Serialize,
312 {
313 Err(TermSerializeError::NotTerm)
314 }
315
316 fn end(self) -> Result<Self::Ok, Self::Error> {
317 Err(TermSerializeError::NotTerm)
318 }
319}
320
321impl ser::SerializeMap for Serializer {
322 type Error = TermSerializeError;
323 type Ok = Term;
324
325 fn serialize_key<T: ?Sized>(&mut self, _key: &T) -> Result<(), Self::Error>
326 where
327 T: Serialize,
328 {
329 Err(TermSerializeError::NotTerm)
330 }
331
332 fn serialize_value<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
333 where
334 T: Serialize,
335 {
336 Err(TermSerializeError::NotTerm)
337 }
338
339 fn end(self) -> Result<Self::Ok, Self::Error> {
340 Err(TermSerializeError::NotTerm)
341 }
342}
343
344impl ser::SerializeStruct for Serializer {
345 type Error = TermSerializeError;
346 type Ok = Term;
347
348 fn serialize_field<T: ?Sized>(
349 &mut self,
350 _key: &'static str,
351 _value: &T,
352 ) -> Result<(), Self::Error>
353 where
354 T: Serialize,
355 {
356 Err(TermSerializeError::NotTerm)
357 }
358
359 fn end(self) -> Result<Self::Ok, Self::Error> {
360 Err(TermSerializeError::NotTerm)
361 }
362}
363
364impl ser::SerializeStructVariant for Serializer {
365 type Error = TermSerializeError;
366 type Ok = Term;
367
368 fn serialize_field<T: ?Sized>(
369 &mut self,
370 _key: &'static str,
371 _value: &T,
372 ) -> Result<(), Self::Error>
373 where
374 T: Serialize,
375 {
376 Err(TermSerializeError::NotTerm)
377 }
378
379 fn end(self) -> Result<Self::Ok, Self::Error> {
380 Err(TermSerializeError::NotTerm)
381 }
382}
383
384#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)]
386pub enum TermSerializeError {
387 NoTerm,
389
390 NotTerm,
392}
393
394impl std::fmt::Display for TermSerializeError {
395 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
396 match self {
397 Self::NoTerm => "no term was provided".fmt(f),
398 Self::NotTerm => "provided value was not a term".fmt(f),
399 }
400 }
401}
402
403impl std::error::Error for TermSerializeError {}
404
405impl ser::Error for TermSerializeError {
406 fn custom<T>(_msg: T) -> Self
407 where
408 T: std::fmt::Display,
409 {
410 Self::NotTerm
411 }
412}
413
414#[cfg(test)]
415mod tests {
416 use chrono::prelude::*;
417
418 use super::*;
419
420 #[test]
421 fn serializes_primitives_correctly() {
422 assert_eq!(Term::new(true), Some(Term::Boolean(true)));
423 assert_eq!(Term::new(12345), Some(Term::PositiveNumber(12345)));
424 assert_eq!(Term::new(-1234), Some(Term::NegativeNumber(-1234)));
425 assert_eq!(Term::new(1_f32), Some(Term::Float32(1.0)));
426 assert_eq!(Term::new(1_f64), Some(Term::Float64(1.0)));
427 assert_eq!(Term::new('s'), Some(Term::String("s".into())));
428 assert_eq!(Term::new("str"), Some(Term::String("str".into())));
429 assert_eq!(
430 Term::new(Utc.with_ymd_and_hms(2022, 3, 21, 0, 5, 8).single().unwrap()),
431 Some(Term::String("2022-03-21T00:05:08Z".into()))
432 );
433 }
434
435 #[test]
436 fn serializes_newtypes_correctly() {
437 #[derive(Serialize)]
438 struct Newtype<T>(T);
439
440 assert_eq!(Term::new(Newtype(123)), Some(Term::PositiveNumber(123)));
441 }
442
443 #[test]
444 fn serializes_wrappers_correctly() {
445 struct Wrapper<T> {
446 value: T,
447 }
448
449 impl<T> Serialize for Wrapper<T>
450 where
451 T: Serialize,
452 {
453 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
454 where
455 S: serde::Serializer,
456 {
457 self.value.serialize(serializer)
458 }
459 }
460
461 assert_eq!(
462 Term::new(Wrapper { value: 123 }),
463 Some(Term::PositiveNumber(123))
464 );
465 }
466
467 #[test]
468 fn custom_partial_eq() {
469 assert_eq!(Term::Float32(1.0), Term::Float64(1.0));
470 assert_eq!(Term::Float64(1.0), Term::Float32(1.0));
471 }
472}