ioendian/
lib.rs

1use std::fmt::{Debug, Display, Formatter, Error};
2
3pub trait EndianBufFor<Out> {
4    #[inline(always)]
5    fn reverse(&mut self);
6    #[inline(always)]
7    fn native(self) -> Out;
8}
9
10pub trait FromBuf: Sized + Clone {
11    type Buf: EndianBufFor<Self>;
12
13    #[inline(always)]
14    fn from_buf(buf: Self::Buf) -> Self {
15        buf.native()
16    }
17
18    #[inline(always)]
19    fn into_buf(self) -> Self::Buf;
20}
21
22pub trait IntoNativeEndian {
23    type Out;
24
25    #[inline(always)]
26    fn native(self) -> Self::Out;
27}
28
29#[derive(Clone)]
30pub struct Big<T: FromBuf>(pub T::Buf);
31#[derive(Clone)]
32pub struct Little<T: FromBuf>(pub T::Buf);
33
34impl<T: FromBuf + Debug> Debug for Big<T>
35    where Self: Clone
36{
37    #[inline(always)]
38    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
39        write!(f, "Big({:?})", self.clone().native())
40    }
41}
42
43impl<T: FromBuf + Debug> Debug for Little<T>
44    where Self: Clone
45{
46    #[inline(always)]
47    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
48        write!(f, "Big({:?})", self.clone().native())
49    }
50}
51
52impl<T: FromBuf + Display> Display for Big<T>
53    where Self: Clone
54{
55    #[inline(always)]
56    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
57        self.clone().native().fmt(f)
58    }
59}
60
61impl<T: FromBuf + Debug> Display for Little<T>
62    where Self: Clone
63{
64    #[inline(always)]
65    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
66        self.clone().native().fmt(f)
67    }
68}
69
70macro_rules! impl_buf_traits {
71    ($type:ty, $count:expr) => {
72        impl EndianBufFor<$type> for [u8; $count] {
73            #[inline(always)]
74            fn reverse(&mut self) {
75                self.as_mut().reverse()
76            }
77
78            #[inline(always)]
79            fn native(self) -> $type {
80                unsafe { ::std::mem::transmute(self) }
81            }
82        }
83
84        impl FromBuf for $type {
85            type Buf = [u8; $count];
86
87            #[inline(always)]
88            fn into_buf(self) -> Self::Buf {
89                unsafe { ::std::mem::transmute(self) }
90            }
91        }
92
93        impl Copy for Big<$type> {}
94        impl Copy for Little<$type> {}
95    };
96}
97
98impl_buf_traits!(u8, 1);
99impl_buf_traits!(u16, 2);
100impl_buf_traits!(u32, 4);
101impl_buf_traits!(u64, 8);
102
103impl_buf_traits!(i8, 1);
104impl_buf_traits!(i16, 2);
105impl_buf_traits!(i32, 4);
106impl_buf_traits!(i64, 8);
107
108impl_buf_traits!(f32, 4);
109impl_buf_traits!(f64, 8);
110
111#[cfg(target_endian = "big")]
112mod trait_impls {
113    use super::{FromBuf, EndianBufFor, IntoNativeEndian, Big, Little};
114
115    impl<T: FromBuf> Big<T> {
116        #[inline(always)]
117        fn new(inner: T) -> Self {
118            Big(inner.into_buf())
119        }
120    }
121
122    impl<T: FromBuf> Little<T> {
123        #[inline(always)]
124        fn new(inner: T) -> Self {
125            let mut buf = inner.into_buf();
126            buf.reverse();
127            Little(buf)
128        }
129    }
130
131    impl<T: FromBuf> IntoNativeEndian for Big<T> {
132        type Out = T;
133
134        #[inline(always)]
135        fn native(self) -> Self::Out {
136            T::from_buf(self.0)
137        }
138    }
139
140    impl<T: FromBuf> IntoNativeEndian for Little<T> {
141        type Out = T;
142
143        #[inline(always)]
144        fn native(mut self) -> Self::Out {
145            self.0.reverse();
146            T::from_buf(self.0)
147        }
148    }
149}
150
151#[cfg(target_endian = "little")]
152mod trait_impls {
153    use super::{FromBuf, EndianBufFor, IntoNativeEndian, Big, Little};
154
155    impl<T: FromBuf> Big<T> {
156        #[inline(always)]
157        pub fn new(inner: T) -> Self {
158            let mut buf = inner.into_buf();
159            buf.reverse();
160            Big(buf)
161        }
162    }
163
164    impl<T: FromBuf> Little<T> {
165        #[inline(always)]
166        pub fn new(inner: T) -> Self {
167            Little(inner.into_buf())
168        }
169    }
170
171    impl<T: FromBuf> IntoNativeEndian for Big<T> {
172        type Out = T;
173
174        #[inline(always)]
175        fn native(mut self) -> Self::Out {
176            self.0.reverse();
177            T::from_buf(self.0)
178        }
179    }
180
181    impl<T: FromBuf> IntoNativeEndian for Little<T> {
182        type Out = T;
183
184        #[inline(always)]
185        fn native(self) -> Self::Out {
186            T::from_buf(self.0)
187        }
188    }
189}
190
191#[cfg(test)]
192mod tests {
193    #[test]
194    fn it_works() {}
195}