#![deny(missing_docs)]
#[doc(inline)]
pub use io::*;
#[doc(inline)]
pub use buffer::{Result, Error, Precision};
use data::*;
use std::{mem, result};
macro_rules! bit_store {
{ $( $(impl<$($t: ident $(: $b: ident $(+ $x: ident)*)*),+>)* for $ty: ty {
( $r: ident ) => $read: block,
( $self: ident, $w: ident ) => $write: block,
}; )+ } => { $(
impl$(<$($t $(: $b $(+ $x)*)*, )+>)* $crate::data::BitStore for $ty {
fn read_from<R: $crate::io::BitRead>($r: &mut R) -> $crate::buffer::Result<Self> $read
fn write_to<W: $crate::io::BitWrite>(&$self, $w: &mut W) -> $crate::buffer::Result<()> $write
}
)+ };
}
macro_rules! bit_const {
{ $(impl<$($t: ident $(: $b: ident $(+ $x: ident)*)*),+>)* const $ty: ty {
$read: expr,
$write: expr,
}; } => {
impl$(<$($t $(: $b $(+ $x)*)*, )+>)* $crate::data::BitStore for $ty {
fn read_from<R: $crate::io::BitRead>(_: &mut R) -> $crate::buffer::Result<Self> { $read }
fn write_to<W: $crate::io::BitWrite>(&self, _: &mut W) -> $crate::buffer::Result<()> { $write }
}
};
}
macro_rules! bit_convert {
{ $( $(impl<$($t: ident $(: $b: ident $(+ $x: ident)*)*),+>)* for $ty: ty: $return: ty {
( $self_r: ident, $r: ident ) => $read: block,
( $self_w: ident, $v: ident, $w: ident ) => $write: block,
}; )+ } => { $(
impl$(<$($t $(: $b $(+ $x)*)*, )+>)* $crate::data::BitConvert<$return> for $ty {
fn read_value_from<R: $crate::io::BitRead>(&$self_r, $r: &mut R) -> $crate::buffer::Result<$return> $read
fn write_value_to<W: $crate::io::BitWrite>(&$self_w, $v: &$return, $w: &mut W) -> $crate::buffer::Result<()> $write
}
)+ };
}
pub mod prelude;
pub mod buffer;
pub mod data;
pub mod io;
bit_store! {
for bool {
(reader) => { reader.read_bit() },
(self, writer) => { writer.write_bit(*self) },
};
for u8 {
(reader) => { reader.read_byte() },
(self, writer) => { writer.write_byte(*self) },
};
for i8 {
(reader) => { reader.read_byte().map(|b| b as i8) },
(self, writer) => { writer.write_byte(*self as u8) },
};
}
macro_rules! int_impl {
($( $s: expr => $( $v: ident ),+ );+) => { $( $( bit_store! { for $v {
(reader) => { Ok(Self::from_be( unsafe { mem::transmute::<[u8; $s], Self>(reader.read()?) } )) },
(self, writer) => { writer.write( & unsafe { mem::transmute::<Self, [u8; $s]>((*self).to_be()) } ) },
}; } )+ )+ }
}
int_impl!(2 => u16, i16; 4 => u32, i32; 8 => u64, i64);
macro_rules! float_impl {
($( $s: expr => $u: ident => $v: ident );+) => { $( bit_store! { for $v {
(reader) => { Ok( unsafe { mem::transmute($u::from_be(mem::transmute::<[u8; $s], $u>(reader.read()?))) } ) },
(self, writer) => { writer.write( & unsafe { mem::transmute::<$u, [u8; $s]>(mem::transmute::<Self, $u>(*self).to_be()) } ) },
}; } )+ }
}
float_impl!(4 => u32 => f32; 8 => u64 => f64);
bit_store! {
for String {
(reader) => { reader.read_using(&StringConverter::default()) },
(self, writer) => { writer.write_using(self, &StringConverter::default()) },
};
impl<T: BitStore> for Option<T> {
(reader) => {
if reader.read_bit()? {
Ok(Some(reader.read()?))
} else {
Ok(None)
}
},
(self, writer) => {
if let &Some(ref value) = self {
writer.write_bit(true)?;
writer.write(value)
} else {
writer.write_bit(false)
}
},
};
impl<T: BitStore, F: BitStore> for result::Result<T, F> {
(reader) => {
if reader.read_bit()? {
Ok(Ok(reader.read()?))
} else {
Ok(Err(reader.read()?))
}
},
(self, writer) => {
match self {
&Ok(ref value) => {
writer.write_bit(true)?;
writer.write(value)
},
&Err(ref value) => {
writer.write_bit(false)?;
writer.write(value)
}
}
},
};
}
macro_rules! array_impl {
($x: expr; $a: ident $( $b: ident )*) => {
array_impl! { $x - 1; $( $b )* }
bit_store! {
impl<T: BitStore> for [T; $x] {
(reader) => { Ok([reader.$a()? $(, reader.$b()?)*]) },
(self, writer) => {
for item in self.iter() {
writer.write(item)?;
}
Ok(())
},
};
}
};
($x: expr; ) => {
bit_const! {
impl<T> const [T; $x] {
Ok([]),
Ok(()),
};
}
};
}
array_impl! { 32; read read read read read read read read read read read read read read read read read read read read read read read read read read read read read read read read }
bit_const! {
const () {
Ok(()),
Ok(()),
};
}