1use std::char::{self};
2use std::fmt::{self, Debug, Display, Formatter};
3use std::str::{FromStr};
4
5#[derive(Ord, PartialOrd, Eq, PartialEq, Hash, Copy, Clone)]
6pub struct Tag {
7 pub dword: u32
8}
9
10impl From<u32> for Tag {
11 fn from(dword: u32) -> Tag {
12 Tag { dword }
13 }
14}
15
16impl Debug for Tag {
17 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
18 Display::fmt(self, f)
19 }
20}
21
22fn byte_to_char(b: u8) -> char {
23 char::from_u32((u32::from(b >> 7) << 8) | u32::from(b)).unwrap()
24}
25
26fn char_to_byte(c: char) -> Option<u8> {
27 let c = c as u32;
28 match c {
29 0x00 ..= 0x7F => Some(c as u8),
30 0x180 ..= 0x1FF => Some((c & 0xFF) as u8),
31 _ => None
32 }
33}
34
35impl Display for Tag {
36 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
37 let c0 = byte_to_char(self.dword as u8);
38 let c1 = byte_to_char((self.dword >> 8) as u8);
39 let c2 = byte_to_char((self.dword >> 16) as u8);
40 let c3 = byte_to_char((self.dword >> 24) as u8);
41 write!(f, "{c0}{c1}{c2}{c3}")
42 }
43}
44
45impl FromStr for Tag {
46 type Err = ();
47
48 fn from_str(s: &str) -> Result<Self, Self::Err> {
49 let mut dword = 0;
50 let mut i = 0;
51 for c in s.chars() {
52 if i == 4 { return Err(()); }
53 dword |= u32::from(char_to_byte(c).ok_or(())?) << (8 * i);
54 i += 1;
55 }
56 if i != 4 { return Err(()); }
57 Ok(Tag { dword })
58 }
59}
60
61macro_rules! enum_serde {
62 ($name:ty, $exp:literal, as $bits:ty, $signed:ident, $big:ident) => {
63 impl ::serde::Serialize for $name {
64 fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error> where
65 S: ::serde::Serializer {
66
67 if serializer.is_human_readable() {
68 format!("{}", self).serialize(serializer)
69 } else {
70 <$bits as ::serde::Serialize>::serialize(
71 &(*self as $bits),
72 serializer
73 )
74 }
75 }
76 }
77
78 impl<'de> ::serde::Deserialize<'de> for $name {
79 fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error> where
80 D: ::serde::Deserializer<'de> {
81
82 struct HRDeVisitor;
83
84 impl<'de> ::serde::de::Visitor<'de> for HRDeVisitor {
85 type Value = $name;
86
87 fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, $exp) }
88
89 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: ::serde::de::Error {
90 ::std::str::FromStr::from_str(s).map_err(|_| E::invalid_value(::serde::de::Unexpected::Str(s), &self))
91 }
92 }
93
94 if deserializer.is_human_readable() {
95 deserializer.deserialize_str(HRDeVisitor)
96 } else {
97 let b = <$bits as ::serde::Deserialize>::deserialize(deserializer)?;
98 <$name>::n(b).ok_or_else(|| <D::Error as ::serde::de::Error>::invalid_value(::serde::de::Unexpected::$signed(b as $big), &$exp))
99 }
100 }
101 }
102 };
103 ($name:ty, $exp:literal, $bits:ty, $to:ident, $from:ident) => {
104 impl ::serde::Serialize for $name {
105 fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error> where
106 S: ::serde::Serializer {
107
108 if serializer.is_human_readable() {
109 format!("{}", self).serialize(serializer)
110 } else {
111 <$bits as ::serde::Serialize>::serialize(&self.$to, serializer)
112 }
113 }
114 }
115
116 impl<'de> ::serde::Deserialize<'de> for $name {
117 fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error> where
118 D: ::serde::Deserializer<'de> {
119
120 struct HRDeVisitor;
121
122 impl<'de> ::serde::de::Visitor<'de> for HRDeVisitor {
123 type Value = $name;
124
125 fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, $exp) }
126
127 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: ::serde::de::Error {
128 ::std::str::FromStr::from_str(s).map_err(|_| E::invalid_value(::serde::de::Unexpected::Str(s), &self))
129 }
130 }
131
132 if deserializer.is_human_readable() {
133 deserializer.deserialize_str(HRDeVisitor)
134 } else {
135 let b = <$bits as ::serde::Deserialize>::deserialize(deserializer)?;
136 Ok(<$name>::$from(b))
137 }
138 }
139 }
140 };
141 ($name:ty, $exp:literal, $bits:ty, $to:ident, try $from:ident, $signed:ident, $big:ident $(, ^$xor:literal)?) => {
142 impl ::serde::Serialize for $name {
143 fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error> where
144 S: ::serde::Serializer {
145
146 if serializer.is_human_readable() {
147 format!("{}", self).serialize(serializer)
148 } else {
149 <$bits as ::serde::Serialize>::serialize(&(self.$to $(^ $xor)?), serializer)
150 }
151 }
152 }
153
154 impl<'de> ::serde::Deserialize<'de> for $name {
155 fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error> where
156 D: ::serde::Deserializer<'de> {
157
158 struct HRDeVisitor;
159
160 impl<'de> ::serde::de::Visitor<'de> for HRDeVisitor {
161 type Value = $name;
162
163 fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, $exp) }
164
165 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: ::serde::de::Error {
166 ::std::str::FromStr::from_str(s).map_err(|_| E::invalid_value(::serde::de::Unexpected::Str(s), &self))
167 }
168 }
169
170 if deserializer.is_human_readable() {
171 deserializer.deserialize_str(HRDeVisitor)
172 } else {
173 let b = <$bits as ::serde::Deserialize>::deserialize(deserializer)? $(^ $xor)?;
174 let v = <$name>::$from(b).ok_or_else(|| <D::Error as ::serde::de::Error>::invalid_value(::serde::de::Unexpected::$signed(b as $big), &$exp))?;
175 Ok(v)
176 }
177 }
178 }
179 };
180 ($name:ty, $exp:literal, $bits:ty, $to:ident (), try $from:ident, $signed:ident, $big:ident $(, ^$xor:literal)?) => {
181 impl ::serde::Serialize for $name {
182 fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error> where
183 S: ::serde::Serializer {
184
185 if serializer.is_human_readable() {
186 format!("{}", self).serialize(serializer)
187 } else {
188 <$bits as ::serde::Serialize>::serialize(&(self.$to() $(^ $xor)?), serializer)
189 }
190 }
191 }
192
193 impl<'de> ::serde::Deserialize<'de> for $name {
194 fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error> where
195 D: ::serde::Deserializer<'de> {
196
197 struct HRDeVisitor;
198
199 impl<'de> ::serde::de::Visitor<'de> for HRDeVisitor {
200 type Value = $name;
201
202 fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, $exp) }
203
204 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: ::serde::de::Error {
205 ::std::str::FromStr::from_str(s).map_err(|_| E::invalid_value(::serde::de::Unexpected::Str(s), &self))
206 }
207 }
208
209 if deserializer.is_human_readable() {
210 deserializer.deserialize_str(HRDeVisitor)
211 } else {
212 let b = <$bits as ::serde::Deserialize>::deserialize(deserializer)? $(^ $xor)?;
213 let v = <$name>::$from(b).ok_or_else(|| <D::Error as ::serde::de::Error>::invalid_value(::serde::de::Unexpected::$signed(b as $big), &$exp))?;
214 Ok(v)
215 }
216 }
217 }
218 }
219}
220
221enum_serde!(Tag, "four-byte tag", u32, dword, from);