data_stream/
numbers.rs

1use crate::{FromStream, ToStream};
2
3use std::io::{Read, Result, Write};
4
5/// The endian encoding of numbers.
6pub enum Endian {
7    /// Little endian encoding.
8    Little,
9    /// Big endian encoding.
10    Big,
11    /// The native endian encoding of the system.
12    Native,
13}
14
15/// The endian settings required for reading and writing numbers.
16pub trait EndianSettings: Sized {
17    /// The endian used by these endian settings.
18    const ENDIAN: Endian;
19}
20
21/// Simple settings for using little endian encoding.
22pub struct LittleEndian;
23/// Simple settings for using big endian encoding.
24pub struct BigEndian;
25/// Simple settings for using native endian encoding.
26pub 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);