1use byteorder::{ReadBytesExt};
9use std::io::Error;
10
11#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
13pub enum Type {
14 Array,
15 Bool,
16 Break,
17 Bytes,
18 Float16,
19 Float32,
20 Float64,
21 Int16,
22 Int32,
23 Int64,
24 Int8,
25 Null,
26 Object,
27 Tagged,
28 Text,
29 UInt16,
30 UInt32,
31 UInt64,
32 UInt8,
33 Undefined,
34 Unknown { major: u8, info: u8 },
35 Reserved { major: u8, info: u8 },
36 Unassigned { major: u8, info: u8 }
37}
38
39impl Type {
40 pub fn major(&self) -> u8 {
41 match *self {
42 Type::Array => 4,
43 Type::Bool => 7,
44 Type::Break => 7,
45 Type::Bytes => 2,
46 Type::Float16 => 7,
47 Type::Float32 => 7,
48 Type::Float64 => 7,
49 Type::Int16 => 1,
50 Type::Int32 => 1,
51 Type::Int64 => 1,
52 Type::Int8 => 1,
53 Type::Null => 7,
54 Type::Object => 5,
55 Type::Tagged => 6,
56 Type::Text => 3,
57 Type::UInt16 => 0,
58 Type::UInt32 => 0,
59 Type::UInt64 => 0,
60 Type::UInt8 => 0,
61 Type::Undefined => 7,
62 Type::Unknown { major: m, .. } => m,
63 Type::Reserved { major: m, .. } => m,
64 Type::Unassigned { major: m, .. } => m
65 }
66 }
67
68 pub fn read<R: ReadBytesExt>(r: &mut R) -> Result<(Type, u8), Error> {
69 let b = r.read_u8()?;
70 match ((b & 0b111_00000) >> 5, b & 0b000_11111) {
71 (0, a @ 0...24) => Ok((Type::UInt8, a)),
72 (0, 25) => Ok((Type::UInt16, 25)),
73 (0, 26) => Ok((Type::UInt32, 26)),
74 (0, 27) => Ok((Type::UInt64, 27)),
75 (1, a @ 0...24) => Ok((Type::Int8, a)),
76 (1, 25) => Ok((Type::Int16, 25)),
77 (1, 26) => Ok((Type::Int32, 26)),
78 (1, 27) => Ok((Type::Int64, 27)),
79 (2, a) => Ok((Type::Bytes, a)),
80 (3, a) => Ok((Type::Text, a)),
81 (4, a) => Ok((Type::Array, a)),
82 (5, a) => Ok((Type::Object, a)),
83 (6, a) => Ok((Type::Tagged, a)),
84 (7, a @ 0...19) => Ok((Type::Unassigned { major: 7, info: a }, a)),
85 (7, 20) => Ok((Type::Bool, 20)),
86 (7, 21) => Ok((Type::Bool, 21)),
87 (7, 22) => Ok((Type::Null, 22)),
88 (7, 23) => Ok((Type::Undefined, 23)),
89 (7, 24) => match r.read_u8()? {
90 a @ 0...31 => Ok((Type::Reserved { major: 7, info: a }, a)),
91 a => Ok((Type::Unassigned { major: 7, info: a }, a))
92 },
93 (7, 25) => Ok((Type::Float16, 25)),
94 (7, 26) => Ok((Type::Float32, 26)),
95 (7, 27) => Ok((Type::Float64, 27)),
96 (7, a @ 28...30) => Ok((Type::Unassigned { major: 7, info: a }, a)),
97 (7, 31) => Ok((Type::Break, 31)),
98 (m, a) => Ok((Type::Unknown { major: m, info: a }, a))
99 }
100 }
101}
102
103#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
105pub enum Tag {
106 DateTime,
107 Timestamp,
108 Bignum,
109 NegativeBignum,
110 Decimal,
111 Bigfloat,
112 Unassigned(u64),
113 ToBase64Url,
114 ToBase64,
115 ToBase16,
116 Cbor,
117 Uri,
118 Base64Url,
119 Base64,
120 Regex,
121 Mime,
122 CborSelf
123}
124
125impl Tag {
126 pub fn of(x: u64) -> Tag {
127 match x {
128 0 => Tag::DateTime,
129 1 => Tag::Timestamp,
130 2 => Tag::Bignum,
131 3 => Tag::NegativeBignum,
132 4 => Tag::Decimal,
133 5 => Tag::Bigfloat,
134 21 => Tag::ToBase64Url,
135 22 => Tag::ToBase64,
136 23 => Tag::ToBase16,
137 24 => Tag::Cbor,
138 32 => Tag::Uri,
139 33 => Tag::Base64Url,
140 34 => Tag::Base64,
141 35 => Tag::Regex,
142 36 => Tag::Mime,
143 55799 => Tag::CborSelf,
144 _ => Tag::Unassigned(x)
145 }
146 }
147
148 pub fn to(&self) -> u64 {
149 match *self {
150 Tag::DateTime => 0,
151 Tag::Timestamp => 1,
152 Tag::Bignum => 2,
153 Tag::NegativeBignum => 3,
154 Tag::Decimal => 4,
155 Tag::Bigfloat => 5,
156 Tag::ToBase64Url => 21,
157 Tag::ToBase64 => 22,
158 Tag::ToBase16 => 23,
159 Tag::Cbor => 24,
160 Tag::Uri => 32,
161 Tag::Base64Url => 33,
162 Tag::Base64 => 34,
163 Tag::Regex => 35,
164 Tag::Mime => 36,
165 Tag::CborSelf => 55799,
166 Tag::Unassigned(x) => x
167 }
168 }
169}