use std::io::{
Read,
Write
};
pub trait WriteBin<T> {
fn write_bin(&mut self, x: T) -> Result<(), String>;
}
pub trait ReadBin<T> {
fn read_bin(&mut self) -> Result<T, String>;
}
impl<W: Write> WriteBin<i16> for W {
fn write_bin(&mut self, x: i16) -> Result<(), String> {
self.write_all(& x.to_le_bytes()).map_err(|e| e.to_string())
}
}
impl<R: Read> ReadBin<i16> for R {
fn read_bin(&mut self) -> Result<i16, String> {
let mut buf = [0u8; (i16::BITS >> 3) as usize];
self.read_exact(&mut buf).map_err(|e| e.to_string())?;
Ok(i16::from_le_bytes(buf))
}
}
impl<W: Write> WriteBin<i32> for W {
fn write_bin(&mut self, x: i32) -> Result<(), String> {
self.write_all(& x.to_le_bytes()).map_err(|e| e.to_string())
}
}
impl<R: Read> ReadBin<i32> for R {
fn read_bin(&mut self) -> Result<i32, String> {
let mut buf = [0u8; (i32::BITS >> 3) as usize];
self.read_exact(&mut buf).map_err(|e| e.to_string())?;
Ok(i32::from_le_bytes(buf))
}
}
impl<W: Write> WriteBin<i64> for W {
fn write_bin(&mut self, x: i64) -> Result<(), String> {
self.write_all(& x.to_le_bytes()).map_err(|e| e.to_string())
}
}
impl<R: Read> ReadBin<i64> for R {
fn read_bin(&mut self) -> Result<i64, String> {
let mut buf = [0u8; (i64::BITS >> 3) as usize];
self.read_exact(&mut buf).map_err(|e| e.to_string())?;
Ok(i64::from_le_bytes(buf))
}
}
impl<W: Write> WriteBin<i128> for W {
fn write_bin(&mut self, x: i128) -> Result<(), String> {
self.write_all(& x.to_le_bytes()).map_err(|e| e.to_string())
}
}
impl<R: Read> ReadBin<i128> for R {
fn read_bin(&mut self) -> Result<i128, String> {
let mut buf = [0u8; (i128::BITS >> 3) as usize];
self.read_exact(&mut buf).map_err(|e| e.to_string())?;
Ok(i128::from_le_bytes(buf))
}
}
impl<W: Write> WriteBin<bool> for W {
fn write_bin(&mut self, x: bool) -> Result<(), String> {
self.write_all(& (if x {1u8} else {0u8}).to_le_bytes()).map_err(|e| e.to_string())
}
}
impl<R: Read> ReadBin<bool> for R {
fn read_bin(&mut self) -> Result<bool, String> {
let mut buf8 = [0u8; 1];
self.read_exact(&mut buf8).map_err(|e| e.to_string())?;
Ok(u8::from_le_bytes(buf8) != 0)
}
}
impl<W: Write> WriteBin<usize> for W { fn write_bin(&mut self, mut x: usize) -> Result<(), String> {
let mut part: u8;
loop {
part = (x & 0x7F) as u8;
if x >= 0x80 {
part |= 0x80; }
self.write_all(&[part]).map_err(|e| e.to_string())?;
x >>= 7;
if x == 0 {
break;
}
}
Ok(())
}
}
impl<R: Read> ReadBin<usize> for R { fn read_bin(&mut self) -> Result<usize, String> {
let mut shift: u32 = 0;
let mut x: usize = 0;
let mut buf8 = [0u8; 1];
loop {
self.read_exact(&mut buf8).map_err(|e| e.to_string())?;
x += ((buf8[0] & 0x7F) as usize) << shift;
if (buf8[0] & 0x80) == 0 { break;
}
shift += 7;
}
Ok(x)
}
}
impl<W: Write> WriteBin<f64> for W {
fn write_bin(&mut self, x: f64) -> Result<(), String> {
self.write_all(& x.to_le_bytes()).map_err(|e| e.to_string())
}
}
impl<R: Read> ReadBin<f64> for R {
fn read_bin(&mut self) -> Result<f64, String> {
let mut buf64 = [0u8; 8];
self.read_exact(&mut buf64).map_err(|e| e.to_string())?;
Ok(f64::from_le_bytes(buf64))
}
}