Skip to main content

tendermint_rpc/
id.rs

1//! JSON-RPC IDs
2
3use core::fmt;
4
5use serde::{Deserialize, Serialize};
6
7use crate::{prelude::*, utils::uuid_str};
8
9/// JSON-RPC ID: request-specific identifier
10#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq, Ord, PartialOrd)]
11#[serde(untagged)]
12pub enum Id {
13    /// Numerical JSON ID
14    Num(i64),
15    /// String JSON ID
16    Str(String),
17    /// null JSON ID
18    None,
19}
20
21impl Id {
22    /// Create a JSON-RPC ID containing a UUID v4 (i.e. random)
23    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}