endian_type_rs/
lib.rs

1// Build without default features in order to include this library in #![no_std]
2// crates.
3#![cfg_attr(not(feature = "std"), no_std)]
4
5#[cfg(feature = "std")]
6extern crate core;
7
8#[cfg(feature = "num")]
9extern crate num;
10
11use core::{mem,slice};
12use core::convert::{From};
13use core::ops::{BitAnd,BitOr,BitXor};
14
15///Type with a specified byte order
16pub trait Endian<T>{}
17
18macro_rules! impl_Endian{
19	( for $e:ident) => {
20		impl<T> BitAnd for $e<T>
21			where T: BitAnd
22		{
23			type Output = $e<<T as BitAnd>::Output>;
24
25			#[inline]
26			fn bitand(self,other: Self) -> Self::Output{
27				$e(self.0 & other.0)
28			}
29		}
30		impl<T> BitOr for $e<T>
31			where T: BitOr
32		{
33			type Output = $e<<T as BitOr>::Output>;
34
35			#[inline]
36			fn bitor(self,other: Self) -> Self::Output{
37				$e(self.0 | other.0)
38			}
39		}
40		impl<T> BitXor for $e<T>
41			where T: BitXor
42		{
43			type Output = $e<<T as BitXor>::Output>;
44
45			#[inline]
46			fn bitxor(self,other: Self) -> Self::Output{
47				$e(self.0 ^ other.0)
48			}
49		}
50
51		impl<T> $e<T>
52			where T: Sized + Copy
53		{
54			#[inline]
55			pub fn from_bytes(bytes: &[u8]) -> Self{
56				debug_assert!(bytes.len() >= mem::size_of::<T>());
57				$e(unsafe{*(bytes.as_ptr() as *const T)})
58			}
59
60			#[inline]
61			pub fn as_bytes(&self) -> &[u8]{
62				unsafe{slice::from_raw_parts(
63					&self.0 as *const T as *const u8,
64					mem::size_of::<T>()
65				)}
66			}
67
68			/*pub fn write_bytes(self,buffer: &mut [u8]){
69				debug_assert!(buffer.len() >= mem::size_of::<T>());
70				let bytes = mem::transmute::<_,[u8; mem::size_of::<T>()]>();
71				unsafe{ptr::copy_nonoverlapping(bytes.as_ptr(),buffer.as_mut_ptr(),mem::size_of::<T>())};
72			}*/
73		}
74	}
75}
76
77
78
79///Big endian byte order
80///
81///Most significant byte first
82#[derive(Copy,Clone,Debug,Eq,PartialEq,Hash,Ord,PartialOrd)]
83pub struct BigEndian<T>(T);
84impl<T> Endian<T> for BigEndian<T>{}
85macro_rules! impl_for_BigEndian{
86	( $t:ident ) => {
87        impl BigEndian<$t> {
88            pub const fn new(data: $t) -> Self {
89                Self(data.to_be())
90            }
91        }
92
93		impl From<BigEndian<$t>> for $t {
94			#[inline]
95			fn from(data: BigEndian<$t>) -> $t {
96				$t::from_be(data.0)
97			}
98		}
99
100        #[cfg(feature = "num")]
101        impl num::ToPrimitive for BigEndian<$t> {
102            fn to_i64(&self) -> Option<i64> {
103                Some($t::from_be(self.0) as i64)
104            }
105
106            fn to_u64(&self) -> Option<u64> {
107                Some($t::from_be(self.0) as u64)
108            }
109        }
110
111		impl From<$t> for BigEndian<$t>{
112			#[inline]
113			fn from(data: $t) -> Self{
114				BigEndian(data.to_be())
115			}
116		}
117
118		impl From<LittleEndian<$t>> for BigEndian<$t>{
119			#[inline]
120			fn from(data: LittleEndian<$t>) -> Self{
121				BigEndian(data.0.swap_bytes())
122			}
123		}
124	}
125}
126impl_Endian!(for BigEndian);
127impl_for_BigEndian!(u16);
128impl_for_BigEndian!(u32);
129impl_for_BigEndian!(u64);
130impl_for_BigEndian!(usize);
131impl_for_BigEndian!(i16);
132impl_for_BigEndian!(i32);
133impl_for_BigEndian!(i64);
134impl_for_BigEndian!(isize);
135
136
137
138///Little endian byte order
139///
140///Least significant byte first
141#[derive(Copy,Clone,Debug,Eq,PartialEq,Hash,Ord,PartialOrd)]
142pub struct LittleEndian<T>(T);
143impl<T> Endian<T> for LittleEndian<T>{}
144macro_rules! impl_for_LittleEndian{
145	( $t:ident ) => {
146        impl LittleEndian<$t> {
147            pub const fn new(data: $t) -> Self {
148                Self(data.to_le())
149            }
150        }
151
152		impl From<LittleEndian<$t>> for $t {
153			#[inline]
154			fn from(data: LittleEndian<$t>) -> $t {
155				$t::from_le(data.0)
156			}
157		}
158
159		impl From<$t> for LittleEndian<$t>{
160			#[inline]
161			fn from(data: $t) -> Self{
162				LittleEndian(data.to_le())
163			}
164		}
165
166		impl From<BigEndian<$t>> for LittleEndian<$t>{
167			#[inline]
168			fn from(data: BigEndian<$t>) -> Self{
169				LittleEndian(data.0.swap_bytes())
170			}
171		}
172
173        #[cfg(feature = "num")]
174        impl num::ToPrimitive for LittleEndian<$t> {
175            fn to_i64(&self) -> Option<i64> {
176                Some($t::from_le(self.0) as i64)
177            }
178
179            fn to_u64(&self) -> Option<u64> {
180                Some($t::from_le(self.0) as u64)
181            }
182        }
183	}
184}
185impl_Endian!(for LittleEndian);
186impl_for_LittleEndian!(u16);
187impl_for_LittleEndian!(u32);
188impl_for_LittleEndian!(u64);
189impl_for_LittleEndian!(usize);
190impl_for_LittleEndian!(i16);
191impl_for_LittleEndian!(i32);
192impl_for_LittleEndian!(i64);
193impl_for_LittleEndian!(isize);
194
195
196///Network byte order as defined by IETF RFC1700 [http://tools.ietf.org/html/rfc1700]
197pub type NetworkOrder<T> = BigEndian<T>;
198
199
200///Type aliases for primitive types
201pub mod types{
202	#![allow(non_camel_case_types)]
203
204	use super::*;
205
206	pub type i16_be   = BigEndian<i16>;
207	pub type i32_be   = BigEndian<i32>;
208	pub type i64_be   = BigEndian<i64>;
209	pub type isize_be = BigEndian<isize>;
210
211	pub type u16_be   = BigEndian<u16>;
212	pub type u32_be   = BigEndian<u32>;
213	pub type u64_be   = BigEndian<u64>;
214	pub type usize_be = BigEndian<usize>;
215
216	pub type i16_le   = LittleEndian<i16>;
217	pub type i32_le   = LittleEndian<i32>;
218	pub type i64_le   = LittleEndian<i64>;
219	pub type isize_le = LittleEndian<isize>;
220
221	pub type u16_le   = LittleEndian<u16>;
222	pub type u32_le   = LittleEndian<u32>;
223	pub type u64_le   = LittleEndian<u64>;
224	pub type usize_le = LittleEndian<usize>;
225
226	pub type i16_net   = NetworkOrder<i16>;
227	pub type i32_net   = NetworkOrder<i32>;
228	pub type i64_net   = NetworkOrder<i64>;
229	pub type isize_net = NetworkOrder<isize>;
230
231	pub type u16_net   = NetworkOrder<u16>;
232	pub type u32_net   = NetworkOrder<u32>;
233	pub type u64_net   = NetworkOrder<u64>;
234	pub type usize_net = NetworkOrder<usize>;
235}
236
237/*#[cfg(test)]
238mod tests{
239	use super::*;
240	use super::types::*;
241
242	#[test]
243	fn construct_big(){
244		//#[cfg(target_endian = "big")]{}
245
246	}
247}*/