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