endio/
read.rs

1use std::io::Read;
2use std::io::Result as Res;
3
4use crate::{BigEndian, Deserialize, Endianness, LittleEndian};
5
6/**
7	Only necessary for custom (de-)serializations.
8
9	Interface for reading data with a specified endianness. Use this interface to make deserializations automatically switch endianness without having to write the same code twice.
10
11	In theory this would be the only write trait and BE-/LERead would be aliases to the BE/LE type parameter variants, but for some reason that doesn't import methods in `use` notation.
12
13	## Examples
14
15	```
16	use endio::LERead;
17
18	let mut reader = &b"\x2a\x01\xcf\xfe\xf3\x2c"[..];
19	let a: u8 = reader.read().unwrap();
20	let b: bool = reader.read().unwrap();
21	let c: u32 = reader.read().unwrap();
22	assert_eq!(a, 42);
23	assert_eq!(b, true);
24	assert_eq!(c, 754187983);
25	```
26*/
27pub trait ERead<E: Endianness>: Sized {
28	/**
29		Reads a `Deserialize` from the reader, in the reader's endianness.
30
31		What's actually read is up to the implementation of the `Deserialize`.
32	*/
33	fn read   <D: Deserialize<E,            Self>>(&mut self) -> Res<D> { D::deserialize(self) }
34	/// Reads in forced big endian.
35	fn read_be<D: Deserialize<BigEndian,    Self>>(&mut self) -> Res<D> { D::deserialize(self) }
36	/// Reads in forced little endian.
37	fn read_le<D: Deserialize<LittleEndian, Self>>(&mut self) -> Res<D> { D::deserialize(self) }
38}
39
40/**
41	Use this to `read` in **big** endian.
42
43	Wrapper for `ERead<BigEndian>`.
44
45	This exists solely to make `use` notation work. See `ERead` for documentation.
46*/
47pub trait BERead: Sized {
48	fn read   <D: Deserialize<BigEndian,    Self>>(&mut self) -> Res<D> { D::deserialize(self) }
49	fn read_be<D: Deserialize<BigEndian,    Self>>(&mut self) -> Res<D> { D::deserialize(self) }
50	fn read_le<D: Deserialize<LittleEndian, Self>>(&mut self) -> Res<D> { D::deserialize(self) }
51}
52
53/**
54	Use this to `read` in **little** endian.
55
56	Wrapper for `ERead<LittleEndian>`.
57
58	This exists solely to make `use` notation work. See `ERead` for documentation.
59*/
60pub trait LERead: Sized {
61	fn read   <D: Deserialize<LittleEndian, Self>>(&mut self) -> Res<D> { D::deserialize(self) }
62	fn read_be<D: Deserialize<BigEndian,    Self>>(&mut self) -> Res<D> { D::deserialize(self) }
63	fn read_le<D: Deserialize<LittleEndian, Self>>(&mut self) -> Res<D> { D::deserialize(self) }
64}
65
66impl<R: Read, E: Endianness> ERead<E> for R {}
67impl<R: Read> BERead for R {}
68impl<R: Read> LERead for R {}
69
70#[cfg(test)]
71mod tests {
72	const DATA: &[u8] = b"\xba\xad";
73
74	#[test]
75	fn read_be_forced() {
76		use super::LERead;
77		let mut reader = &DATA[..];
78		let val: u16 = reader.read_be().unwrap();
79		assert_eq!(val, 0xbaad);
80	}
81
82	#[test]
83	fn read_le_forced() {
84		use crate::BERead;
85		let mut reader = &DATA[..];
86		let val: u16 = reader.read_le().unwrap();
87		assert_eq!(val, 0xadba);
88	}
89}