1use crate::{i256, u256};
6use core::cell::Cell;
7use core::fmt;
8use core::str::Utf8Error;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
12pub enum DecodeError {
13 BufferLength {
15 for_type: &'static str,
16 expected: usize,
17 given: usize,
18 },
19 InvalidLen { expected: usize, given: usize },
21 InvalidTag { tag: u8, sum_name: Option<String> },
23 InvalidUtf8,
25 InvalidBool(u8),
27 Other(String),
29}
30
31impl fmt::Display for DecodeError {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 match self {
34 DecodeError::BufferLength {
35 for_type,
36 expected,
37 given,
38 } => write!(f, "data too short for {for_type}: Expected {expected}, given {given}"),
39 DecodeError::InvalidLen { expected, given } => {
40 write!(f, "unexpected data length: Expected {expected}, given {given}")
41 }
42 DecodeError::InvalidTag { tag, sum_name } => {
43 write!(
44 f,
45 "unknown tag {tag:#x} for sum type {}",
46 sum_name.as_deref().unwrap_or("<unknown>")
47 )
48 }
49 DecodeError::InvalidUtf8 => f.write_str("invalid utf8"),
50 DecodeError::InvalidBool(byte) => write!(f, "byte {byte} not valid as `bool` (must be 0 or 1)"),
51 DecodeError::Other(err) => f.write_str(err),
52 }
53 }
54}
55impl From<DecodeError> for String {
56 fn from(err: DecodeError) -> Self {
57 err.to_string()
58 }
59}
60impl std::error::Error for DecodeError {}
61
62impl From<Utf8Error> for DecodeError {
63 fn from(_: Utf8Error) -> Self {
64 DecodeError::InvalidUtf8
65 }
66}
67
68pub trait BufWriter {
70 fn put_slice(&mut self, slice: &[u8]);
75
76 fn put_u8(&mut self, val: u8) {
78 self.put_slice(&val.to_le_bytes())
79 }
80
81 fn put_u16(&mut self, val: u16) {
83 self.put_slice(&val.to_le_bytes())
84 }
85
86 fn put_u32(&mut self, val: u32) {
88 self.put_slice(&val.to_le_bytes())
89 }
90
91 fn put_u64(&mut self, val: u64) {
93 self.put_slice(&val.to_le_bytes())
94 }
95
96 fn put_u128(&mut self, val: u128) {
98 self.put_slice(&val.to_le_bytes())
99 }
100
101 fn put_u256(&mut self, val: u256) {
103 self.put_slice(&val.to_le_bytes())
104 }
105
106 fn put_i8(&mut self, val: i8) {
108 self.put_slice(&val.to_le_bytes())
109 }
110
111 fn put_i16(&mut self, val: i16) {
113 self.put_slice(&val.to_le_bytes())
114 }
115
116 fn put_i32(&mut self, val: i32) {
118 self.put_slice(&val.to_le_bytes())
119 }
120
121 fn put_i64(&mut self, val: i64) {
123 self.put_slice(&val.to_le_bytes())
124 }
125
126 fn put_i128(&mut self, val: i128) {
128 self.put_slice(&val.to_le_bytes())
129 }
130
131 fn put_i256(&mut self, val: i256) {
133 self.put_slice(&val.to_le_bytes())
134 }
135}
136
137macro_rules! get_int {
138 ($self:ident, $int:ident) => {
139 match $self.get_array_chunk() {
140 Some(&arr) => Ok($int::from_le_bytes(arr)),
141 None => Err(DecodeError::BufferLength {
142 for_type: stringify!($int),
143 expected: std::mem::size_of::<$int>(),
144 given: $self.remaining(),
145 }),
146 }
147 };
148}
149
150pub trait BufReader<'de> {
154 fn get_chunk(&mut self, size: usize) -> Option<&'de [u8]>;
156
157 fn remaining(&self) -> usize;
159
160 #[inline]
162 fn get_array_chunk<const N: usize>(&mut self) -> Option<&'de [u8; N]> {
163 self.get_chunk(N)?.try_into().ok()
164 }
165
166 #[inline]
168 fn get_slice(&mut self, size: usize) -> Result<&'de [u8], DecodeError> {
169 self.get_chunk(size).ok_or_else(|| DecodeError::BufferLength {
170 for_type: "[u8]",
171 expected: size,
172 given: self.remaining(),
173 })
174 }
175
176 #[inline]
178 fn get_array<const N: usize>(&mut self) -> Result<&'de [u8; N], DecodeError> {
179 self.get_array_chunk().ok_or_else(|| DecodeError::BufferLength {
180 for_type: "[u8; _]",
181 expected: N,
182 given: self.remaining(),
183 })
184 }
185
186 #[inline]
191 fn get_u8(&mut self) -> Result<u8, DecodeError> {
192 get_int!(self, u8)
193 }
194
195 #[inline]
200 fn get_u16(&mut self) -> Result<u16, DecodeError> {
201 get_int!(self, u16)
202 }
203
204 #[inline]
209 fn get_u32(&mut self) -> Result<u32, DecodeError> {
210 get_int!(self, u32)
211 }
212
213 #[inline]
218 fn get_u64(&mut self) -> Result<u64, DecodeError> {
219 get_int!(self, u64)
220 }
221
222 #[inline]
227 fn get_u128(&mut self) -> Result<u128, DecodeError> {
228 get_int!(self, u128)
229 }
230
231 #[inline]
236 fn get_u256(&mut self) -> Result<u256, DecodeError> {
237 get_int!(self, u256)
238 }
239
240 #[inline]
245 fn get_i8(&mut self) -> Result<i8, DecodeError> {
246 get_int!(self, i8)
247 }
248
249 #[inline]
254 fn get_i16(&mut self) -> Result<i16, DecodeError> {
255 get_int!(self, i16)
256 }
257
258 #[inline]
263 fn get_i32(&mut self) -> Result<i32, DecodeError> {
264 get_int!(self, i32)
265 }
266
267 #[inline]
272 fn get_i64(&mut self) -> Result<i64, DecodeError> {
273 get_int!(self, i64)
274 }
275
276 #[inline]
281 fn get_i128(&mut self) -> Result<i128, DecodeError> {
282 get_int!(self, i128)
283 }
284
285 #[inline]
290 fn get_i256(&mut self) -> Result<i256, DecodeError> {
291 get_int!(self, i256)
292 }
293}
294
295impl BufWriter for Vec<u8> {
296 fn put_slice(&mut self, slice: &[u8]) {
297 self.extend_from_slice(slice);
298 }
299}
300
301impl BufWriter for &mut [u8] {
302 fn put_slice(&mut self, slice: &[u8]) {
303 if self.len() < slice.len() {
304 panic!("not enough buffer space")
305 }
306 let (buf, rest) = std::mem::take(self).split_at_mut(slice.len());
307 buf.copy_from_slice(slice);
308 *self = rest;
309 }
310}
311
312#[derive(Default)]
314pub struct CountWriter {
315 num_bytes: usize,
317}
318
319impl CountWriter {
320 pub fn finish(self) -> usize {
322 self.num_bytes
323 }
324}
325
326impl BufWriter for CountWriter {
327 fn put_slice(&mut self, slice: &[u8]) {
328 self.num_bytes += slice.len();
329 }
330}
331
332pub struct TeeWriter<W1, W2> {
334 pub w1: W1,
335 pub w2: W2,
336}
337
338impl<W1: BufWriter, W2: BufWriter> TeeWriter<W1, W2> {
339 pub fn new(w1: W1, w2: W2) -> Self {
340 Self { w1, w2 }
341 }
342}
343
344impl<W1: BufWriter, W2: BufWriter> BufWriter for TeeWriter<W1, W2> {
345 fn put_slice(&mut self, slice: &[u8]) {
346 self.w1.put_slice(slice);
347 self.w2.put_slice(slice);
348 }
349}
350
351impl<'de> BufReader<'de> for &'de [u8] {
352 #[inline]
353 fn get_chunk(&mut self, size: usize) -> Option<&'de [u8]> {
354 let (ret, rest) = self.split_at_checked(size)?;
355 *self = rest;
356 Some(ret)
357 }
358
359 #[inline]
360 fn get_array_chunk<const N: usize>(&mut self) -> Option<&'de [u8; N]> {
361 let (ret, rest) = self.split_first_chunk()?;
362 *self = rest;
363 Some(ret)
364 }
365
366 #[inline(always)]
367 fn remaining(&self) -> usize {
368 self.len()
369 }
370}
371
372#[derive(Debug)]
374pub struct Cursor<I> {
375 pub buf: I,
377 pub pos: Cell<usize>,
379}
380
381impl<I> Cursor<I> {
382 pub fn new(buf: I) -> Self {
386 Self { buf, pos: 0.into() }
387 }
388}
389
390impl<'de, I: AsRef<[u8]>> BufReader<'de> for &'de Cursor<I> {
391 #[inline]
392 fn get_chunk(&mut self, size: usize) -> Option<&'de [u8]> {
393 let buf = &self.buf.as_ref()[self.pos.get()..];
395 let ret = buf.get(..size)?;
396
397 self.pos.set(self.pos.get() + size);
399
400 Some(ret)
401 }
402
403 #[inline]
404 fn get_array_chunk<const N: usize>(&mut self) -> Option<&'de [u8; N]> {
405 let buf = &self.buf.as_ref()[self.pos.get()..];
407 let ret = buf.first_chunk()?;
408
409 self.pos.set(self.pos.get() + N);
411
412 Some(ret)
413 }
414
415 fn remaining(&self) -> usize {
416 self.buf.as_ref().len() - self.pos.get()
417 }
418}
419
420#[cfg(test)]
421mod tests {
422 use crate::buffer::{BufReader, BufWriter};
423
424 #[test]
425 fn test_simple_encode_decode() {
426 let mut writer: Vec<u8> = vec![];
427 writer.put_u8(5);
428 writer.put_u32(6);
429 writer.put_u64(7);
430
431 let arr_val = [1, 2, 3, 4];
432 writer.put_slice(&arr_val[..]);
433
434 let mut reader = writer.as_slice();
435 assert_eq!(reader.get_u8().unwrap(), 5);
436 assert_eq!(reader.get_u32().unwrap(), 6);
437 assert_eq!(reader.get_u64().unwrap(), 7);
438
439 let slice = reader.get_slice(4).unwrap();
440 assert_eq!(slice, arr_val);
441
442 assert!(reader.get_slice(1).is_err());
444 assert!(reader.get_slice(123).is_err());
445 assert!(reader.get_u64().is_err());
446 assert!(reader.get_u32().is_err());
447 assert!(reader.get_u8().is_err());
448 }
449}