web3api_wasm_rs/msgpack/
format.rs

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/// Format markers in the MsgPack specification
8/// The `Reserved` variant is not used, according to the spec.
9#[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    /// Converts a single byte to its MsgPack marker representation
86    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    /// Converts a MsgPack marker into a single byte
129    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}