use ::mem;
pub trait ByteSlice {
fn byte_slice(&self) -> &[u8];
fn byte_mut_slice(&mut self) -> &mut [u8];
}
pub trait ByteIndex : ByteSlice {
fn byte(&self, idx: usize) -> Option<u8>;
}
macro_rules! impl_index_trait1
{
($($t:ty), +) => {
$(
impl ByteSlice for $t {
fn byte_slice(&self) -> &[u8] {
let bytes: &[u8; 1] = unsafe { mem::transmute(self) };
&bytes[..]
}
fn byte_mut_slice(&mut self) -> &mut [u8] {
let bytes: &mut [u8; 1] = unsafe { mem::transmute(self) };
&mut bytes[..]
}
}
impl ByteIndex for $t {
fn byte(&self, idx: usize) -> Option<u8> {
if idx >= mem::size_of::<$t>() {
return None;
}
Some(self.byte_slice()[idx])
}
}
)+
};
}
macro_rules! impl_index_trait2
{
($($t:ty), +) => {
$(
impl ByteSlice for $t {
fn byte_slice(&self) -> &[u8] {
let bytes: &[u8; 2] = unsafe { mem::transmute(self) };
&bytes[..]
}
fn byte_mut_slice(&mut self) -> &mut [u8] {
let bytes: &mut [u8; 2] = unsafe { mem::transmute(self) };
&mut bytes[..]
}
}
impl ByteIndex for $t {
fn byte(&self, idx: usize) -> Option<u8> {
if idx >= mem::size_of::<$t>() {
return None;
}
Some(self.byte_slice()[idx])
}
}
)+
};
}
macro_rules! impl_index_trait4
{
($($t:ty), +) => {
$(
impl ByteSlice for $t {
fn byte_slice(&self) -> &[u8] {
let bytes: &[u8; 4] = unsafe { mem::transmute(self) };
&bytes[..]
}
fn byte_mut_slice(&mut self) -> &mut [u8] {
let bytes: &mut [u8; 4] = unsafe { mem::transmute(self) };
&mut bytes[..]
}
}
impl ByteIndex for $t {
fn byte(&self, idx: usize) -> Option<u8> {
if idx >= mem::size_of::<$t>() {
return None;
}
Some(self.byte_slice()[idx])
}
}
)+
};
}
macro_rules! impl_index_trait8
{
($($t:ty), +) => {
$(
impl ByteSlice for $t {
fn byte_slice(&self) -> &[u8] {
let bytes: &[u8; 8] = unsafe { mem::transmute(self) };
&bytes[..]
}
fn byte_mut_slice(&mut self) -> &mut [u8] {
let bytes: &mut [u8; 8] = unsafe { mem::transmute(self) };
&mut bytes[..]
}
}
impl ByteIndex for $t {
fn byte(&self, idx: usize) -> Option<u8> {
if idx >= mem::size_of::<$t>(){
return None;
}
Some(self.byte_slice()[idx])
}
}
)+
};
}
impl_index_trait1!(i8, u8);
impl_index_trait2!(i16, u16);
impl_index_trait4!(i32, u32, f32);
impl_index_trait8!(i64, u64, f64);
#[cfg(target_pointer_width = "64")]
impl_index_trait8!(isize, usize);
#[cfg(target_pointer_width = "32")]
impl_index_trait4!(isize, usize);