1use crate::{FromStream, ToStream};
2
3use std::io::{Read, Result, Write};
4
5pub enum Endian {
7 Little,
9 Big,
11 Native,
13}
14
15pub trait EndianSettings: Sized {
17 const ENDIAN: Endian;
19}
20
21pub struct LittleEndian;
23pub struct BigEndian;
25pub struct NativeEndian;
27
28impl EndianSettings for LittleEndian {
29 const ENDIAN: Endian = Endian::Little;
30}
31
32impl EndianSettings for BigEndian {
33 const ENDIAN: Endian = Endian::Big;
34}
35
36impl EndianSettings for NativeEndian {
37 const ENDIAN: Endian = Endian::Native;
38}
39
40macro_rules! impl_num {
41 ($t: ty) => {
42 impl<S: EndianSettings> ToStream<S> for $t {
43 fn to_stream<W: Write>(&self, stream: &mut W) -> Result<()> {
44 use Endian::*;
45 let bytes = match S::ENDIAN {
46 Little => self.to_le_bytes(),
47 Big => self.to_be_bytes(),
48 Native => self.to_ne_bytes(),
49 };
50
51 stream.write_all(&bytes)?;
52
53 Ok(())
54 }
55 }
56
57 impl<S: EndianSettings> FromStream<S> for $t {
58 fn from_stream<R: Read>(stream: &mut R) -> Result<Self> {
59 const SIZE: usize = std::mem::size_of::<$t>();
60 let mut bytes = [0; SIZE];
61
62 stream.read_exact(&mut bytes)?;
63
64 use Endian::*;
65 Ok(match S::ENDIAN {
66 Little => Self::from_le_bytes(bytes),
67 Big => Self::from_be_bytes(bytes),
68 Native => Self::from_ne_bytes(bytes),
69 })
70 }
71 }
72 };
73 ($t: ty, $($rest: ty),+) => {
74 impl_num!($t);
75 impl_num!($($rest),+);
76 };
77}
78
79impl_num!(u8, u16, u32, u64, u128);
80impl_num!(i8, i16, i32, i64, i128);
81impl_num!(f32, f64);
82impl_num!(usize);