1use crate::{decode, encode};
23use std::{fmt, io};
24
25macro_rules! gen {
26 ($($name:ident, $d:expr, $t:ident, $b:ident);*) => {
27 $(
28 #[doc = " Try to read and decode a "]
29 #[doc = $d]
30 #[doc = " from the given `Read` type."]
31 pub fn $name<R: io::Read>(mut reader: R) -> Result<$t, ReadError> {
32 let mut b = encode::$b();
33 for i in 0 .. b.len() {
34 let n = reader.read(&mut b[i .. i + 1])?;
35 if n == 0 {
36 return Err(ReadError::Io(io::ErrorKind::UnexpectedEof.into()))
37 }
38 if decode::is_last(b[i]) {
39 return Ok(decode::$t(&b[..= i])?.0)
40 }
41 }
42 Err(decode::Error::Overflow.into())
43 }
44 )*
45 }
46}
47
48gen! {
49 read_u8, "`u8`", u8, u8_buffer;
50 read_u16, "`u16`", u16, u16_buffer;
51 read_u32, "`u32`", u32, u32_buffer;
52 read_u64, "`u64`", u64, u64_buffer;
53 read_u128, "`u128`", u128, u128_buffer;
54 read_usize, "`usize`", usize, usize_buffer
55}
56
57#[non_exhaustive]
59#[derive(Debug)]
60pub enum ReadError {
61 Io(io::Error),
62 Decode(decode::Error)
63}
64
65impl fmt::Display for ReadError {
66 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67 match self {
68 ReadError::Io(e) => write!(f, "i/o error: {}", e),
69 ReadError::Decode(e) => write!(f, "decode error: {}", e)
70 }
71 }
72}
73
74impl std::error::Error for ReadError {
75 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
76 if let ReadError::Io(e) = self {
77 Some(e)
78 } else {
79 None
80 }
81 }
82}
83
84impl From<io::Error> for ReadError {
85 fn from(e: io::Error) -> Self {
86 ReadError::Io(e)
87 }
88}
89
90impl From<decode::Error> for ReadError {
91 fn from(e: decode::Error) -> Self {
92 ReadError::Decode(e)
93 }
94}
95
96impl Into<io::Error> for ReadError {
97 fn into(self) -> io::Error {
98 match self {
99 ReadError::Io(e) => e,
100 ReadError::Decode(e) => e.into(),
101 }
102 }
103}