1use std::io::{self, Read};
15
16macro_rules! impl_traits {
17 ($($type:ty),+) => {
18 $(
19 ::paste::paste!{
20 #[doc = "Trait to read "$type "."]
21 #[doc = "# Errors"]
22 #[doc = "errors exactly when [`Read::read_exact`](https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact) errors"]
23 pub trait [<Read $type:camel>]: Read {
24 #[doc = "Read " $type "in native byte order"]
25 fn [<read_ne_ $type>](&mut self) -> io::Result<$type> {
26 let mut bytes = [0u8; std::mem::size_of::<$type>()];
27 self.read_exact(&mut bytes)?;
28 Ok($type::from_ne_bytes(bytes))
29 }
30 #[doc = "Read " $type "in little endian byte order"]
31 #[doc = "# Errors"]
32 #[doc = "errors exactly when [`Read::read_exact`](https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact) errors"]
33 fn [<read_le_ $type>](&mut self) -> io::Result<$type> {
34 let mut bytes = [0u8; std::mem::size_of::<$type>()];
35 self.read_exact(&mut bytes)?;
36 Ok($type::from_le_bytes(bytes))
37 }
38 #[doc = "Read " $type "in big endian byte order"]
39 #[doc = "# Errors"]
40 #[doc = "errors exactly when [`Read::read_exact`](https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact) errors"]
41 fn [<read_be_ $type>](&mut self) -> io::Result<$type> {
42 let mut bytes = [0u8; std::mem::size_of::<$type>()];
43 self.read_exact(&mut bytes)?;
44 Ok($type::from_be_bytes(bytes))
45 }
46 }
47 impl<T:Read> [<Read $type:camel>] for T{}
48 }
49 )+
50 };
51}
52
53impl_traits!(u16, i16, u32, i32, u64, i64, u128, i128, usize, isize, f32, f64);
54
55pub trait ReadU8: Read {
57 fn read_u8(&mut self) -> io::Result<u8> {
61 let mut bytes = [0u8; 1];
62 self.read_exact(&mut bytes)?;
63 Ok(u8::from_ne_bytes(bytes))
64 }
65}
66impl<R> ReadU8 for R where R: Read {}
67
68pub trait ReadChar: Read {
70 fn read_char(&mut self) -> io::Result<Option<char>> {
75 let mut bytes = [0u8; 4];
76 self.read_exact(&mut bytes)?;
77 Ok(char::from_u32(u32::from_ne_bytes(bytes)))
78 }
79}
80impl<R> ReadChar for R where R: Read {}
81
82pub trait ReadBool: Read {
84 fn read_bool(&mut self) -> io::Result<bool> {
88 let mut bytes = [0u8; 1];
89 self.read_exact(&mut bytes)?;
90 Ok(u8::from_ne_bytes(bytes) != 0)
91 }
92}
93impl<R> ReadBool for R where R: Read {}
94
95#[cfg(test)]
96mod test {
97 use crate::*;
98
99 macro_rules! impl_tests {
100 ($($type:ty),+) => {
101 $(
102 ::paste::paste! {
103 #[test]
104 fn [<read_ne_ $type>]() {
105 let bytes = [<37 $type>].to_ne_bytes();
106 let number = bytes.as_slice().[<read_ne_ $type>]().unwrap();
107 assert_eq!([<37 $type>], number)
108 }
109 }
110 ::paste::paste! {
111 #[test]
112 fn [<read_le_ $type>]() {
113 let bytes = [<37 $type>].to_le_bytes();
114 let number = bytes.as_slice().[<read_le_ $type>]().unwrap();
115 assert_eq!([<37 $type>], number)
116 }
117 }
118 ::paste::paste! {
119 #[test]
120 fn [<read_be_ $type>]() {
121 let bytes = [<37 $type>].to_be_bytes();
122 let number = bytes.as_slice().[<read_be_ $type>]().unwrap();
123 assert_eq!([<37 $type>], number)
124 }
125 }
126 )+
127 };
128 }
129 impl_tests!(u16, i16, u32, i32, u64, i64, u128, i128, usize, isize, f32, f64);
130
131 #[test]
132 fn read_u8() {
133 let bytes = 37u8.to_ne_bytes();
134 let byte = bytes.as_slice().read_u8().unwrap();
135 assert_eq!(37, byte)
136 }
137}