1extern crate byteorder;
2
3use byteorder::{BigEndian, LittleEndian, WriteBytesExt};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub enum EncodeType {
10 Int8(i8),
12 Int16(i16),
14 Int32(i32),
16 Int64(i64),
18 Int128(i128),
20
21 Uint8(u8),
23 Uint16(u16),
25 Uint32(u32),
27 Uint64(u64),
29 Uint128(u128),
31
32 Str(String),
34
35 Bytes(Vec<u8>),
37}
38
39#[derive(Debug, Clone)]
40pub enum EncodeError {
44 Int8(i8),
46 Int16(i16),
47 Int32(i32),
48 Int64(i64),
49 Int128(i128),
50
51 Uint8(u8),
53 Uint16(u16),
54 Uint32(u32),
55 Uint64(u64),
56 Uint128(u128),
57
58 Str(String),
60
61 Bytes(Vec<u8>),
63}
64
65#[derive(Debug, Clone)]
66pub enum EncodeOrder {
69 Big,
70 Little,
71}
72
73#[inline]
76fn encode_i8(array: &mut [u8], value: &i8) -> Result<(), EncodeError> {
77 array[0] = *value as u8;
78 Ok(())
79}
80
81#[inline]
82fn encode_i16(
83 mut array: &mut [u8],
84 value: &i16,
85 encode_order: EncodeOrder,
86) -> Result<(), EncodeError> {
87 match encode_order {
88 EncodeOrder::Big => array.write_i16::<BigEndian>(*value),
89 EncodeOrder::Little => array.write_i16::<LittleEndian>(*value),
90 }
91 .map_or_else(|_| Err(EncodeError::Int16(*value)), |_| Ok(()))
92}
93
94#[inline]
95fn encode_i32(
96 mut array: &mut [u8],
97 value: &i32,
98 encode_order: EncodeOrder,
99) -> Result<(), EncodeError> {
100 match encode_order {
101 EncodeOrder::Big => array.write_i32::<BigEndian>(*value),
102 EncodeOrder::Little => array.write_i32::<LittleEndian>(*value),
103 }
104 .map_or_else(|_| Err(EncodeError::Int32(*value)), |_| Ok(()))
105}
106
107#[inline]
108fn encode_i64(
109 mut array: &mut [u8],
110 value: &i64,
111 encode_order: EncodeOrder,
112) -> Result<(), EncodeError> {
113 match encode_order {
114 EncodeOrder::Big => array.write_i64::<BigEndian>(*value),
115 EncodeOrder::Little => array.write_i64::<LittleEndian>(*value),
116 }
117 .map_or_else(|_| Err(EncodeError::Int64(*value)), |_| Ok(()))
118}
119
120#[inline]
121fn encode_i128(
122 mut array: &mut [u8],
123 value: &i128,
124 encode_order: EncodeOrder,
125) -> Result<(), EncodeError> {
126 match encode_order {
127 EncodeOrder::Big => array.write_i128::<BigEndian>(*value),
128 EncodeOrder::Little => array.write_i128::<LittleEndian>(*value),
129 }
130 .map_or_else(|_| Err(EncodeError::Int128(*value)), |_| Ok(()))
131}
132
133#[inline]
136fn encode_u8(array: &mut [u8], value: &u8) -> Result<(), EncodeError> {
137 array[0] = *value as u8;
138 Ok(())
139}
140
141#[inline]
142fn encode_u16(
143 mut array: &mut [u8],
144 value: &u16,
145 encode_order: EncodeOrder,
146) -> Result<(), EncodeError> {
147 match encode_order {
148 EncodeOrder::Big => array.write_u16::<BigEndian>(*value),
149 EncodeOrder::Little => array.write_u16::<LittleEndian>(*value),
150 }
151 .map_or_else(|_| Err(EncodeError::Uint16(*value)), |_| Ok(()))
152}
153
154#[inline]
155fn encode_u32(
156 mut array: &mut [u8],
157 value: &u32,
158 encode_order: EncodeOrder,
159) -> Result<(), EncodeError> {
160 match encode_order {
161 EncodeOrder::Big => array.write_u32::<BigEndian>(*value),
162 EncodeOrder::Little => array.write_u32::<LittleEndian>(*value),
163 }
164 .map_or_else(|_| Err(EncodeError::Uint32(*value)), |_| Ok(()))
165}
166
167#[inline]
168fn encode_u64(
169 mut array: &mut [u8],
170 value: &u64,
171 encode_order: EncodeOrder,
172) -> Result<(), EncodeError> {
173 match encode_order {
174 EncodeOrder::Big => array.write_u64::<BigEndian>(*value),
175 EncodeOrder::Little => array.write_u64::<LittleEndian>(*value),
176 }
177 .map_or_else(|_| Err(EncodeError::Uint64(*value)), |_| Ok(()))
178}
179
180#[inline]
181fn encode_u128(
182 mut array: &mut [u8],
183 value: &u128,
184 encode_order: EncodeOrder,
185) -> Result<(), EncodeError> {
186 match encode_order {
187 EncodeOrder::Big => array.write_u128::<BigEndian>(*value),
188 EncodeOrder::Little => array.write_u128::<LittleEndian>(*value),
189 }
190 .map_or_else(|_| Err(EncodeError::Uint128(*value)), |_| Ok(()))
191}
192
193#[inline]
194fn encode_string(array: &mut [u8], value: &str) -> Result<(), EncodeError> {
195 let u8_repr = value.as_bytes();
196 array.clone_from_slice(u8_repr);
197 Ok(())
198}
199
200pub fn encode_packed(elements: &[EncodeType], endian: EncodeOrder) -> Result<Vec<u8>, EncodeError> {
231 let mut buffer: Vec<u8> = Vec::new();
232 let mut last_read = 0;
233
234 for symbol in elements {
235 let (result, size_offset) = match symbol {
236 EncodeType::Int8(value) => {
237 buffer.extend_from_slice(&[0]);
238 (encode_i8(&mut buffer[last_read..], value), 1)
239 }
240 EncodeType::Int16(value) => {
241 buffer.extend_from_slice(&[0, 0]);
242 (
243 encode_i16(&mut buffer[last_read..], value, endian.clone()),
244 2,
245 )
246 }
247 EncodeType::Int32(value) => {
248 buffer.extend_from_slice(&[0, 0, 0, 0]);
249 (
250 encode_i32(&mut buffer[last_read..], value, endian.clone()),
251 4,
252 )
253 }
254 EncodeType::Int64(value) => {
255 buffer.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
256 (
257 encode_i64(&mut buffer[last_read..], value, endian.clone()),
258 8,
259 )
260 }
261 EncodeType::Int128(value) => {
262 buffer.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
263 (
264 encode_i128(&mut buffer[last_read..], value, endian.clone()),
265 16,
266 )
267 }
268 EncodeType::Uint8(value) => {
269 buffer.extend_from_slice(&[0]);
270 (encode_u8(&mut buffer[last_read..], value), 1)
271 }
272 EncodeType::Uint16(value) => {
273 buffer.extend_from_slice(&[0, 0]);
274 (
275 encode_u16(&mut buffer[last_read..], value, endian.clone()),
276 2,
277 )
278 }
279 EncodeType::Uint32(value) => {
280 buffer.extend_from_slice(&[0, 0, 0, 0]);
281 (
282 encode_u32(&mut buffer[last_read..], value, endian.clone()),
283 4,
284 )
285 }
286 EncodeType::Uint64(value) => {
287 buffer.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
288 (
289 encode_u64(&mut buffer[last_read..], value, endian.clone()),
290 8,
291 )
292 }
293 EncodeType::Uint128(value) => {
294 buffer.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
295 (
296 encode_u128(&mut buffer[last_read..], value, endian.clone()),
297 16,
298 )
299 }
300 EncodeType::Str(string) => {
301 let mut temp = Vec::new();
302 temp.resize(string.len(), 0);
303 buffer.extend_from_slice(&temp);
304 (
305 encode_string(&mut buffer[last_read..], string),
306 string.len(),
307 )
308 }
309 EncodeType::Bytes(bytes) => {
310 buffer.extend_from_slice(bytes);
311 (Ok(()), bytes.len())
312 }
313 };
314
315 last_read += size_offset;
316 result?;
317 }
318
319 Ok(buffer)
320}