json_rpc_types/
id.rs

1use serde::{Deserialize, Deserializer, Serialize, Serializer};
2use serde::de::{Error, Visitor};
3
4type StrBuf = str_buf::StrBuf<36>;
5
6use core::fmt;
7
8///Request identfier
9#[derive(Debug, PartialEq, Clone, Hash, Eq)]
10pub enum Id {
11    /// Numeric id
12    Num(u64),
13    /// String id, maximum 36 characters which works for UUID
14    Str(StrBuf),
15}
16
17impl Serialize for Id {
18    #[inline]
19    fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
20        match self {
21            Id::Num(id) => ser.serialize_u64(*id),
22            Id::Str(id) => ser.serialize_str(id.as_str()),
23        }
24    }
25}
26
27impl<'a> Deserialize<'a> for Id {
28    #[inline]
29    fn deserialize<D: Deserializer<'a>>(des: D) -> Result<Self, D::Error> {
30        #[cfg(all(feature = "id-number-only", feature = "id-str-only"))]
31        compile_error!("You MUST select either 'id-number-only' or 'id-str-only' feature");
32
33        #[cfg(not(any(feature = "id-number-only", feature = "id-str-only")))]
34        {
35            des.deserialize_any(IdVisitor)
36        }
37        #[cfg(feature = "id-str-only")]
38        {
39            des.deserialize_str(IdVisitor)
40        }
41        #[cfg(feature = "id-number-only")]
42        {
43            des.deserialize_u64(IdVisitor)
44        }
45    }
46}
47
48struct IdVisitor;
49
50impl<'a> Visitor<'a> for IdVisitor {
51    type Value = Id;
52
53    #[inline]
54    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
55        formatter.write_str("Identifier must be either unsigned integer or 36 character long string")
56    }
57
58    #[inline]
59    fn visit_u64<E: Error>(self, id: u64) -> Result<Self::Value, E> {
60        Ok(Id::Num(id))
61    }
62
63    #[inline]
64    fn visit_i64<E: Error>(self, id: i64) -> Result<Self::Value, E> {
65        if id < 0 {
66            Err(Error::invalid_value(serde::de::Unexpected::Signed(id), &self))
67        } else {
68            Ok(Id::Num(id as u64))
69        }
70    }
71
72    #[inline]
73    fn visit_f64<E: Error>(self, id: f64) -> Result<Self::Value, E> {
74        Err(Error::invalid_value(serde::de::Unexpected::Float(id), &self))
75    }
76
77    #[inline]
78    fn visit_str<E: Error>(self, id: &str) -> Result<Self::Value, E> {
79        if id.len() > StrBuf::capacity() {
80            Err(Error::invalid_length(id.len(), &self))
81        } else {
82            let mut res = StrBuf::new();
83            unsafe {
84                res.push_str_unchecked(id);
85            }
86            Ok(Id::Str(res))
87        }
88    }
89}