/rust/registry/src/index.crates.io-1949cf8c6b5b557f/minicbor-0.18.0/src/data.rs
Line | Count | Source |
1 | | //! Information about CBOR data types and tags. |
2 | | |
3 | | use core::fmt; |
4 | | |
5 | | /// CBOR data types. |
6 | | #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] |
7 | | pub enum Type { |
8 | | Bool, |
9 | | Null, |
10 | | Undefined, |
11 | | U8, |
12 | | U16, |
13 | | U32, |
14 | | U64, |
15 | | I8, |
16 | | I16, |
17 | | I32, |
18 | | I64, |
19 | | Int, |
20 | | F16, |
21 | | F32, |
22 | | F64, |
23 | | Simple, |
24 | | Bytes, |
25 | | BytesIndef, |
26 | | String, |
27 | | StringIndef, |
28 | | Array, |
29 | | ArrayIndef, |
30 | | Map, |
31 | | MapIndef, |
32 | | Tag, |
33 | | Break, |
34 | | Unknown(u8) |
35 | | } |
36 | | |
37 | | impl fmt::Display for Type { |
38 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
39 | 0 | match self { |
40 | 0 | Type::Bool => f.write_str("bool"), |
41 | 0 | Type::Null => f.write_str("null"), |
42 | 0 | Type::Undefined => f.write_str("undefined"), |
43 | 0 | Type::U8 => f.write_str("u8"), |
44 | 0 | Type::U16 => f.write_str("u16"), |
45 | 0 | Type::U32 => f.write_str("u32"), |
46 | 0 | Type::U64 => f.write_str("u64"), |
47 | 0 | Type::I8 => f.write_str("i8"), |
48 | 0 | Type::I16 => f.write_str("i16"), |
49 | 0 | Type::I32 => f.write_str("i32"), |
50 | 0 | Type::I64 => f.write_str("i64"), |
51 | 0 | Type::Int => f.write_str("int"), |
52 | 0 | Type::F16 => f.write_str("f16"), |
53 | 0 | Type::F32 => f.write_str("f32"), |
54 | 0 | Type::F64 => f.write_str("f64"), |
55 | 0 | Type::Simple => f.write_str("simple"), |
56 | 0 | Type::Bytes => f.write_str("bytes"), |
57 | 0 | Type::BytesIndef => f.write_str("indefinite bytes"), |
58 | 0 | Type::String => f.write_str("string"), |
59 | 0 | Type::StringIndef => f.write_str("indefinite string"), |
60 | 0 | Type::Array => f.write_str("array"), |
61 | 0 | Type::ArrayIndef => f.write_str("indefinite array"), |
62 | 0 | Type::Map => f.write_str("map"), |
63 | 0 | Type::MapIndef => f.write_str("indefinite map"), |
64 | 0 | Type::Tag => f.write_str("tag"), |
65 | 0 | Type::Break => f.write_str("break"), |
66 | 0 | Type::Unknown(n) => write!(f, "{:#x}", n) |
67 | | } |
68 | 0 | } |
69 | | } |
70 | | |
71 | | /// CBOR data item tag. |
72 | | #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] |
73 | | pub enum Tag { |
74 | | DateTime, |
75 | | Timestamp, |
76 | | PosBignum, |
77 | | NegBignum, |
78 | | Decimal, |
79 | | Bigfloat, |
80 | | ToBase64Url, |
81 | | ToBase64, |
82 | | ToBase16, |
83 | | Cbor, |
84 | | Uri, |
85 | | Base64Url, |
86 | | Base64, |
87 | | Regex, |
88 | | Mime, |
89 | | Unassigned(u64) |
90 | | } |
91 | | |
92 | | impl Tag { |
93 | 0 | pub(crate) fn from(n: u64) -> Self { |
94 | 0 | match n { |
95 | 0 | 0x00 => Tag::DateTime, |
96 | 0 | 0x01 => Tag::Timestamp, |
97 | 0 | 0x02 => Tag::PosBignum, |
98 | 0 | 0x03 => Tag::NegBignum, |
99 | 0 | 0x04 => Tag::Decimal, |
100 | 0 | 0x05 => Tag::Bigfloat, |
101 | 0 | 0x15 => Tag::ToBase64Url, |
102 | 0 | 0x16 => Tag::ToBase64, |
103 | 0 | 0x17 => Tag::ToBase16, |
104 | 0 | 0x18 => Tag::Cbor, |
105 | 0 | 0x20 => Tag::Uri, |
106 | 0 | 0x21 => Tag::Base64Url, |
107 | 0 | 0x22 => Tag::Base64, |
108 | 0 | 0x23 => Tag::Regex, |
109 | 0 | 0x24 => Tag::Mime, |
110 | 0 | _ => Tag::Unassigned(n) |
111 | | } |
112 | 0 | } |
113 | | |
114 | 0 | pub(crate) fn numeric(self) -> u64 { |
115 | 0 | match self { |
116 | 0 | Tag::DateTime => 0x00, |
117 | 0 | Tag::Timestamp => 0x01, |
118 | 0 | Tag::PosBignum => 0x02, |
119 | 0 | Tag::NegBignum => 0x03, |
120 | 0 | Tag::Decimal => 0x04, |
121 | 0 | Tag::Bigfloat => 0x05, |
122 | 0 | Tag::ToBase64Url => 0x15, |
123 | 0 | Tag::ToBase64 => 0x16, |
124 | 0 | Tag::ToBase16 => 0x17, |
125 | 0 | Tag::Cbor => 0x18, |
126 | 0 | Tag::Uri => 0x20, |
127 | 0 | Tag::Base64Url => 0x21, |
128 | 0 | Tag::Base64 => 0x22, |
129 | 0 | Tag::Regex => 0x23, |
130 | 0 | Tag::Mime => 0x24, |
131 | 0 | Tag::Unassigned(n) => n |
132 | | } |
133 | 0 | } |
134 | | } |
135 | | |
136 | | /// CBOR integer type that covers values of [-2<sup>64</sup>, 2<sup>64</sup> - 1] |
137 | | /// |
138 | | /// CBOR integers keep the sign bit in the major type so there is one extra bit |
139 | | /// available for signed numbers compared to Rust's integer types. This type can |
140 | | /// be used to encode and decode the full CBOR integer range. |
141 | | #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] |
142 | | pub struct Int { neg: bool, val: u64 } |
143 | | |
144 | | /// Max. CBOR integer value (2<sup>64</sup> - 1). |
145 | | pub const MAX_INT: Int = Int { neg: false, val: u64::MAX }; |
146 | | |
147 | | /// Min. CBOR integer value (-2<sup>64</sup>). |
148 | | pub const MIN_INT: Int = Int { neg: true, val: u64::MAX }; |
149 | | |
150 | | impl Int { |
151 | 0 | pub(crate) fn pos<T: Into<u64>>(val: T) -> Self { |
152 | 0 | Int { neg: false, val: val.into() } |
153 | 0 | } Unexecuted instantiation: <minicbor::data::Int>::pos::<u8> Unexecuted instantiation: <minicbor::data::Int>::pos::<u32> Unexecuted instantiation: <minicbor::data::Int>::pos::<u16> Unexecuted instantiation: <minicbor::data::Int>::pos::<u64> |
154 | | |
155 | 0 | pub(crate) fn neg<T: Into<u64>>(val: T) -> Self { |
156 | 0 | Int { neg: true, val: val.into() } |
157 | 0 | } Unexecuted instantiation: <minicbor::data::Int>::neg::<u8> Unexecuted instantiation: <minicbor::data::Int>::neg::<u32> Unexecuted instantiation: <minicbor::data::Int>::neg::<u16> Unexecuted instantiation: <minicbor::data::Int>::neg::<u64> |
158 | | |
159 | 0 | pub(crate) fn value(&self) -> u64 { |
160 | 0 | self.val |
161 | 0 | } |
162 | | |
163 | 0 | pub(crate) fn is_negative(&self) -> bool { |
164 | 0 | self.neg |
165 | 0 | } |
166 | | } |
167 | | |
168 | | impl fmt::Display for Int { |
169 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::fmt::Result { |
170 | 0 | write!(f, "{}", i128::from(*self)) |
171 | 0 | } |
172 | | } |
173 | | |
174 | | // Introductions: |
175 | | |
176 | | impl From<u8> for Int { |
177 | 0 | fn from(i: u8) -> Self { |
178 | 0 | Int::from(u64::from(i)) |
179 | 0 | } |
180 | | } |
181 | | |
182 | | impl From<u16> for Int { |
183 | 0 | fn from(i: u16) -> Self { |
184 | 0 | Int::from(u64::from(i)) |
185 | 0 | } |
186 | | } |
187 | | |
188 | | impl From<u32> for Int { |
189 | 0 | fn from(i: u32) -> Self { |
190 | 0 | Int::from(u64::from(i)) |
191 | 0 | } |
192 | | } |
193 | | |
194 | | impl From<u64> for Int { |
195 | 0 | fn from(i: u64) -> Self { |
196 | 0 | Int::pos(i) |
197 | 0 | } |
198 | | } |
199 | | |
200 | | impl TryFrom<u128> for Int { |
201 | | type Error = TryFromIntError; |
202 | | |
203 | 0 | fn try_from(i: u128) -> Result<Self, Self::Error> { |
204 | 0 | Ok(Int::from(u64::try_from(i).map_err(|_| TryFromIntError("u64"))?)) |
205 | 0 | } |
206 | | } |
207 | | |
208 | | impl From<i8> for Int { |
209 | 0 | fn from(i: i8) -> Self { |
210 | 0 | Int::from(i64::from(i)) |
211 | 0 | } |
212 | | } |
213 | | |
214 | | impl From<i16> for Int { |
215 | 0 | fn from(i: i16) -> Self { |
216 | 0 | Int::from(i64::from(i)) |
217 | 0 | } |
218 | | } |
219 | | |
220 | | impl From<i32> for Int { |
221 | 0 | fn from(i: i32) -> Self { |
222 | 0 | Int::from(i64::from(i)) |
223 | 0 | } |
224 | | } |
225 | | |
226 | | impl From<i64> for Int { |
227 | 0 | fn from(i: i64) -> Self { |
228 | 0 | if i.is_negative() { |
229 | 0 | Int { neg: true, val: (-1 - i) as u64 } |
230 | | } else { |
231 | 0 | Int { neg: false, val: i as u64 } |
232 | | } |
233 | 0 | } |
234 | | } |
235 | | |
236 | | impl TryFrom<i128> for Int { |
237 | | type Error = TryFromIntError; |
238 | | |
239 | 0 | fn try_from(i: i128) -> Result<Self, Self::Error> { |
240 | 0 | if i.is_negative() { |
241 | 0 | if i < -0x1_0000_0000_0000_0000 { |
242 | 0 | Err(TryFromIntError("Int")) |
243 | | } else { |
244 | 0 | Ok(Int { neg: true, val: (-1 - i) as u64 }) |
245 | | } |
246 | 0 | } else if i > 0xFFFF_FFFF_FFFF_FFFF { |
247 | 0 | Err(TryFromIntError("Int")) |
248 | | } else { |
249 | 0 | Ok(Int { neg: false, val: i as u64 }) |
250 | | } |
251 | 0 | } |
252 | | } |
253 | | |
254 | | // Eliminations: |
255 | | |
256 | | impl TryFrom<Int> for u8 { |
257 | | type Error = TryFromIntError; |
258 | | |
259 | 0 | fn try_from(i: Int) -> Result<Self, Self::Error> { |
260 | 0 | u64::try_from(i).and_then(|n| u8::try_from(n).map_err(|_| TryFromIntError("u8"))) |
261 | 0 | } |
262 | | } |
263 | | |
264 | | impl TryFrom<Int> for u16 { |
265 | | type Error = TryFromIntError; |
266 | | |
267 | 0 | fn try_from(i: Int) -> Result<Self, Self::Error> { |
268 | 0 | u64::try_from(i).and_then(|n| u16::try_from(n).map_err(|_| TryFromIntError("u16"))) |
269 | 0 | } |
270 | | } |
271 | | |
272 | | impl TryFrom<Int> for u32 { |
273 | | type Error = TryFromIntError; |
274 | | |
275 | 0 | fn try_from(i: Int) -> Result<Self, Self::Error> { |
276 | 0 | u64::try_from(i).and_then(|n| u32::try_from(n).map_err(|_| TryFromIntError("u32"))) |
277 | 0 | } |
278 | | } |
279 | | |
280 | | impl TryFrom<Int> for u64 { |
281 | | type Error = TryFromIntError; |
282 | | |
283 | 0 | fn try_from(i: Int) -> Result<Self, Self::Error> { |
284 | 0 | if i.neg { |
285 | 0 | return Err(TryFromIntError("u64")) |
286 | 0 | } |
287 | 0 | Ok(i.val) |
288 | 0 | } |
289 | | } |
290 | | |
291 | | impl TryFrom<Int> for u128 { |
292 | | type Error = TryFromIntError; |
293 | | |
294 | 0 | fn try_from(i: Int) -> Result<Self, Self::Error> { |
295 | 0 | if i.neg { |
296 | 0 | return Err(TryFromIntError("u128")) |
297 | 0 | } |
298 | 0 | Ok(u128::from(i.val)) |
299 | 0 | } |
300 | | } |
301 | | |
302 | | impl TryFrom<Int> for i8 { |
303 | | type Error = TryFromIntError; |
304 | | |
305 | 0 | fn try_from(i: Int) -> Result<Self, Self::Error> { |
306 | 0 | i64::try_from(i).and_then(|n| i8::try_from(n).map_err(|_| TryFromIntError("i8"))) |
307 | 0 | } |
308 | | } |
309 | | |
310 | | impl TryFrom<Int> for i16 { |
311 | | type Error = TryFromIntError; |
312 | | |
313 | 0 | fn try_from(i: Int) -> Result<Self, Self::Error> { |
314 | 0 | i64::try_from(i).and_then(|n| i16::try_from(n).map_err(|_| TryFromIntError("i16"))) |
315 | 0 | } |
316 | | } |
317 | | |
318 | | impl TryFrom<Int> for i32 { |
319 | | type Error = TryFromIntError; |
320 | | |
321 | 0 | fn try_from(i: Int) -> Result<Self, Self::Error> { |
322 | 0 | i64::try_from(i).and_then(|n| i32::try_from(n).map_err(|_| TryFromIntError("i32"))) |
323 | 0 | } |
324 | | } |
325 | | |
326 | | impl TryFrom<Int> for i64 { |
327 | | type Error = TryFromIntError; |
328 | | |
329 | 0 | fn try_from(i: Int) -> Result<Self, Self::Error> { |
330 | 0 | let j = i64::try_from(i.val).map_err(|_| TryFromIntError("i64"))?; |
331 | 0 | Ok(if i.neg { -1 - j } else { j }) |
332 | 0 | } |
333 | | } |
334 | | |
335 | | impl From<Int> for i128 { |
336 | 0 | fn from(i: Int) -> Self { |
337 | 0 | let j = i128::from(i.val); |
338 | 0 | if i.neg { -1 - j } else { j } |
339 | 0 | } |
340 | | } |
341 | | |
342 | | /// Error when conversion of a CBOR [`Int`] to another type failed. |
343 | | #[derive(Debug)] |
344 | | pub struct TryFromIntError(&'static str); |
345 | | |
346 | | impl fmt::Display for TryFromIntError { |
347 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
348 | 0 | write!(f, "value out of {} range", self.0) |
349 | 0 | } |
350 | | } |
351 | | |
352 | | #[cfg(feature = "std")] |
353 | | impl std::error::Error for TryFromIntError {} |
354 | | |