mina_p2p_messages/
char.rs1use binprot::byteorder::{ReadBytesExt, WriteBytesExt};
2use serde::{de::Visitor, Deserialize, Serialize};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
5pub struct Char(pub u8);
6
7impl std::ops::Deref for Char {
8 type Target = u8;
9
10 fn deref(&self) -> &Self::Target {
11 &self.0
12 }
13}
14
15impl Char {
16 pub fn as_u8(&self) -> u8 {
17 self.0
18 }
19}
20
21impl Serialize for Char {
22 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
23 where
24 S: serde::Serializer,
25 {
26 if serializer.is_human_readable() {
27 char::from_u32(self.0.into())
28 .unwrap()
29 .to_string()
30 .serialize(serializer)
31 } else {
32 self.0.serialize(serializer)
33 }
34 }
35}
36
37impl<'de> Deserialize<'de> for Char {
38 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
39 where
40 D: serde::Deserializer<'de>,
41 {
42 fn str_to_char(v: &str) -> Result<u8, &str> {
43 if v.len() != 1 {
44 return Err("incorrect length");
45 }
46 let ch = v.chars().next().unwrap();
47 (ch as u32).try_into().map_err(|_| "incorrect char")
48 }
49 if deserializer.is_human_readable() {
50 struct V;
51 impl Visitor<'_> for V {
52 type Value = u8;
53
54 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
55 formatter.write_str("string consisting of a single escaped unicode character")
56 }
57
58 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
59 where
60 E: serde::de::Error,
61 {
62 str_to_char(&v).map_err(serde::de::Error::custom)
63 }
64
65 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
66 where
67 E: serde::de::Error,
68 {
69 str_to_char(v).map_err(serde::de::Error::custom)
70 }
71 }
72
73 deserializer.deserialize_string(V)
74 } else {
75 u8::deserialize(deserializer)
76 }
77 .map(Self)
78 }
79}
80
81impl From<u8> for Char {
82 fn from(source: u8) -> Self {
83 Self(source)
84 }
85}
86
87impl From<Char> for u8 {
88 fn from(source: Char) -> Self {
89 source.0
90 }
91}
92
93impl binprot::BinProtRead for Char {
94 fn binprot_read<R: std::io::Read + ?Sized>(r: &mut R) -> Result<Self, binprot::Error>
95 where
96 Self: Sized,
97 {
98 Ok(r.read_u8().map(Self)?)
99 }
100}
101
102impl binprot::BinProtWrite for Char {
103 fn binprot_write<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
104 w.write_u8(self.0)
105 }
106}
107
108#[cfg(test)]
109mod tests {
110
111 #[test]
112 fn json() {
113 let ch = super::Char(16);
114 let json = serde_json::to_value(ch).unwrap();
115 assert_eq!(json.as_str().unwrap(), "\u{0010}");
116 assert_eq!(
117 serde_json::from_value::<super::Char>(json).unwrap(),
118 super::Char(16)
119 );
120 }
121}