1use byteorder::{self, ReadBytesExt, WriteBytesExt};
2
3const FIX_ARRAY_SIZE: u8 = 0x0f;
4const FIX_MAP_SIZE: u8 = 0x0f;
5const FIX_STR_SIZE: u8 = 0x1f;
6
7#[derive(Clone, Copy, Debug, PartialEq)]
10pub enum Format {
11 PositiveFixInt(u8),
12 FixMap(u8),
13 FixArray(u8),
14 FixStr(u8),
15 Nil,
16 Reserved,
17 False,
18 True,
19 Bin8,
20 Bin16,
21 Bin32,
22 Ext8,
23 Ext16,
24 Ext32,
25 Float32,
26 Float64,
27 Uint8,
28 Uint16,
29 Uint32,
30 Uint64,
31 Int8,
32 Int16,
33 Int32,
34 Int64,
35 FixExt1,
36 FixExt2,
37 FixExt4,
38 FixExt8,
39 FixExt16,
40 Str8,
41 Str16,
42 Str32,
43 Array16,
44 Array32,
45 Map16,
46 Map32,
47 NegativeFixInt(i8),
48}
49
50impl Format {
51 pub fn is_positive_fixed_int(u: u8) -> bool {
52 u >> 7 == 0
53 }
54
55 pub fn is_negative_fixed_int(u: u8) -> bool {
56 (u & 0xe0) == Format::to_u8(&Format::NegativeFixInt(u as i8))
57 }
58
59 pub fn is_fixed_map(u: u8) -> bool {
60 (u & 0xf0) == Format::to_u8(&Format::FixMap(u))
61 }
62
63 pub fn is_fixed_array(u: u8) -> bool {
64 (u & 0xf0) == Format::to_u8(&Format::FixArray(u))
65 }
66
67 pub fn is_fixed_string(u: u8) -> bool {
68 (u & 0xe0) == Format::to_u8(&Format::FixStr(u))
69 }
70
71 pub fn set_format<W: std::io::Write>(
72 writer: &mut W,
73 format: Format,
74 ) -> Result<(), std::io::Error> {
75 WriteBytesExt::write_u8(writer, format.to_u8())?;
76
77 Ok(())
78 }
79
80 pub fn get_format<R: std::io::Read>(reader: &mut R) -> Result<Format, std::io::Error> {
81 let bytesval = ReadBytesExt::read_u8(reader)?;
82 Ok(Format::from_u8(bytesval))
83 }
84
85 pub fn from_u8(val: u8) -> Format {
87 match val {
88 0x00..=0x7f => Format::PositiveFixInt(val),
89 0x80..=0x8f => Format::FixMap(val & FIX_MAP_SIZE),
90 0x90..=0x9f => Format::FixArray(val & FIX_ARRAY_SIZE),
91 0xa0..=0xbf => Format::FixStr(val & FIX_STR_SIZE),
92 0xc0 => Format::Nil,
93 0xc1 => Format::Reserved,
94 0xc2 => Format::False,
95 0xc3 => Format::True,
96 0xc4 => Format::Bin8,
97 0xc5 => Format::Bin16,
98 0xc6 => Format::Bin32,
99 0xc7 => Format::Ext8,
100 0xc8 => Format::Ext16,
101 0xc9 => Format::Ext32,
102 0xca => Format::Float32,
103 0xcb => Format::Float64,
104 0xcc => Format::Uint8,
105 0xcd => Format::Uint16,
106 0xce => Format::Uint32,
107 0xcf => Format::Uint64,
108 0xd0 => Format::Int8,
109 0xd1 => Format::Int16,
110 0xd2 => Format::Int32,
111 0xd3 => Format::Int64,
112 0xd4 => Format::FixExt1,
113 0xd5 => Format::FixExt2,
114 0xd6 => Format::FixExt4,
115 0xd7 => Format::FixExt8,
116 0xd8 => Format::FixExt16,
117 0xd9 => Format::Str8,
118 0xda => Format::Str16,
119 0xdb => Format::Str32,
120 0xdc => Format::Array16,
121 0xdd => Format::Array32,
122 0xde => Format::Map16,
123 0xdf => Format::Map32,
124 0xe0..=0xff => Format::NegativeFixInt(val as i8),
125 }
126 }
127
128 pub fn to_u8(&self) -> u8 {
130 match *self {
131 Format::PositiveFixInt(val) => val,
132 Format::FixMap(val) => 0x80 | (val & FIX_MAP_SIZE),
133 Format::FixArray(val) => 0x90 | (val & FIX_ARRAY_SIZE),
134 Format::FixStr(val) => 0xa0 | (val & FIX_STR_SIZE),
135 Format::Nil => 0xc0,
136 Format::Reserved => 0xc1,
137 Format::False => 0xc2,
138 Format::True => 0xc3,
139 Format::Bin8 => 0xc4,
140 Format::Bin16 => 0xc5,
141 Format::Bin32 => 0xc6,
142 Format::Ext8 => 0xc7,
143 Format::Ext16 => 0xc8,
144 Format::Ext32 => 0xc9,
145 Format::Float32 => 0xca,
146 Format::Float64 => 0xcb,
147 Format::Uint8 => 0xcc,
148 Format::Uint16 => 0xcd,
149 Format::Uint32 => 0xce,
150 Format::Uint64 => 0xcf,
151 Format::Int8 => 0xd0,
152 Format::Int16 => 0xd1,
153 Format::Int32 => 0xd2,
154 Format::Int64 => 0xd3,
155 Format::FixExt1 => 0xd4,
156 Format::FixExt2 => 0xd5,
157 Format::FixExt4 => 0xd6,
158 Format::FixExt8 => 0xd7,
159 Format::FixExt16 => 0xd8,
160 Format::Str8 => 0xd9,
161 Format::Str16 => 0xda,
162 Format::Str32 => 0xdb,
163 Format::Array16 => 0xdc,
164 Format::Array32 => 0xdd,
165 Format::Map16 => 0xde,
166 Format::Map32 => 0xdf,
167 Format::NegativeFixInt(val) => val as u8,
168 }
169 }
170}
171
172impl std::fmt::Display for Format {
173 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
174 write!(f, "{:?}", self)
175 }
176}
177
178impl From<u8> for Format {
179 #[inline]
180 fn from(val: u8) -> Format {
181 Format::from_u8(val)
182 }
183}
184
185impl Into<u8> for Format {
186 #[inline]
187 fn into(self) -> u8 {
188 self.to_u8()
189 }
190}