1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use crate::utils::uuid_str;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq, Ord, PartialOrd)]
#[serde(untagged)]
pub enum Id {
Num(i64),
Str(String),
None,
}
impl Id {
pub fn uuid_v4() -> Self {
Self::Str(uuid_str())
}
}
impl fmt::Display for Id {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Id::Num(i) => write!(f, "{}", i),
Id::Str(s) => write!(f, "{}", s),
Id::None => write!(f, ""),
}
}
}
#[cfg(test)]
mod tests {
use serde::{de::DeserializeOwned, Serialize};
use std::fmt::Debug;
use super::*;
#[test]
fn round_tripping_jsonrpc_id() {
let str = r#""42""#;
serialization_roundtrip::<Id>(str);
let str2 = r#""936DA01F-9ABD-4D9D-80C7-02AF85C822A8""#;
serialization_roundtrip::<Id>(str2);
let num = r#"42"#;
serialization_roundtrip::<Id>(num);
let zero = r#"0"#;
serialization_roundtrip::<Id>(zero);
let null = r#"null"#;
serialization_roundtrip::<Id>(null);
}
fn serialization_roundtrip<T>(json_data: &str)
where
T: Debug + PartialEq + Serialize + DeserializeOwned,
{
let parsed0 = serde_json::from_str::<T>(json_data);
assert!(parsed0.is_ok());
let parsed0 = parsed0.unwrap();
let serialized = serde_json::to_string(&parsed0);
assert!(serialized.is_ok());
let serialized = serialized.unwrap();
let parsed1 = serde_json::from_str::<T>(&serialized);
assert!(parsed1.is_ok());
let parsed1 = parsed1.unwrap();
assert_eq!(parsed0, parsed1);
}
}