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