use crate::io::error::{IoError, IoResult};
use serde::{Deserialize, Serialize};
use std::io::{Read, Write};
pub fn read_binary<T, R>(reader: &mut R) -> IoResult<T>
where
T: for<'de> Deserialize<'de>,
R: Read,
{
let mut buffer = Vec::new();
reader.read_to_end(&mut buffer)?;
let value = bincode::deserialize(&buffer)?;
Ok(value)
}
pub fn write_binary<T, W>(data: &T, writer: &mut W) -> IoResult<()>
where
T: Serialize,
W: Write,
{
let encoded = bincode::serialize(data)?;
writer.write_all(&encoded)?;
Ok(())
}
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct BinaryConfig {
pub little_endian: bool,
pub varint_encoding: bool,
}
impl BinaryConfig {
pub fn new() -> Self {
Self {
little_endian: true,
varint_encoding: false,
}
}
pub fn compact() -> Self {
Self {
little_endian: true,
varint_encoding: true,
}
}
pub fn fast() -> Self {
Self {
little_endian: true,
varint_encoding: false,
}
}
}
impl Default for BinaryConfig {
fn default() -> Self {
Self::new()
}
}
#[allow(dead_code)]
pub struct BinaryReader {
config: BinaryConfig,
}
impl BinaryReader {
pub fn new() -> Self {
Self {
config: BinaryConfig::new(),
}
}
pub fn with_config(config: BinaryConfig) -> Self {
Self { config }
}
pub fn read<T, R>(&self, reader: &mut R) -> IoResult<T>
where
T: for<'de> Deserialize<'de>,
R: Read,
{
read_binary(reader)
}
pub fn read_with_limit<T, R>(&self, reader: &mut R, limit: u64) -> IoResult<T>
where
T: for<'de> Deserialize<'de>,
R: Read,
{
let mut buffer = Vec::new();
let mut limited_reader = reader.take(limit);
limited_reader.read_to_end(&mut buffer)?;
if buffer.len() as u64 == limit {
return Err(IoError::SerializationError(
"Data exceeds size limit".to_string(),
));
}
let value = bincode::deserialize(&buffer)?;
Ok(value)
}
}
impl Default for BinaryReader {
fn default() -> Self {
Self::new()
}
}
#[allow(dead_code)]
pub struct BinaryWriter {
config: BinaryConfig,
}
impl BinaryWriter {
pub fn new() -> Self {
Self {
config: BinaryConfig::new(),
}
}
pub fn with_config(config: BinaryConfig) -> Self {
Self { config }
}
pub fn write<T, W>(&self, data: &T, writer: &mut W) -> IoResult<()>
where
T: Serialize,
W: Write,
{
write_binary(data, writer)
}
pub fn serialized_size<T>(&self, data: &T) -> IoResult<u64>
where
T: Serialize,
{
let size = bincode::serialized_size(data)?;
Ok(size)
}
}
impl Default for BinaryWriter {
fn default() -> Self {
Self::new()
}
}
pub mod inspect {
use super::*;
#[allow(dead_code)]
pub fn serialized_size<T>(data: &T) -> IoResult<u64>
where
T: Serialize,
{
let size = bincode::serialized_size(data)?;
Ok(size)
}
#[allow(dead_code)]
pub fn validate_serializable<T>(data: &T) -> IoResult<()>
where
T: Serialize,
{
bincode::serialize(data)?;
Ok(())
}
}