use crate::bipack_sink::{BipackSink, IntoU64};
use crate::bipack_source::{BipackSource, Result};
pub trait BiPackable {
fn bi_pack(self: &Self, sink: &mut impl BipackSink) -> Result<()>;
}
pub trait BiUnpackable where Self: Sized {
fn bi_unpack(source: &mut dyn BipackSource) -> Result<Self>;
}
#[macro_export]
macro_rules! bipack {
( $( $e: expr),* ) => {{
let mut result = Vec::new();
$(
$e.bi_pack(&mut result).unwrap();
)*
result
}};
}
impl<T: IntoU64 + Copy> BiPackable for T {
fn bi_pack(self: &Self, sink: &mut impl BipackSink) -> Result<()> {
sink.put_unsigned(self.into_u64())
}
}
impl BiPackable for &str {
fn bi_pack(self: &Self, sink: &mut impl BipackSink) -> Result<()> {
sink.put_str(self)
}
}
macro_rules! declare_unpack_u {
($($type:ident),*) => {
$(impl BiUnpackable for $type {
fn bi_unpack(source: &mut dyn BipackSource) -> Result<$type> {
Ok(source.get_unsigned()? as $type)
}
})*
};
}
declare_unpack_u!(u16, u32, u64);
impl BiUnpackable for u8 {
fn bi_unpack(source: &mut dyn BipackSource) -> Result<u8> {
source.get_u8()
}
}
impl BiUnpackable for String {
fn bi_unpack(source: &mut dyn BipackSource) -> Result<String> {
source.get_str()
}
}