use anyhow::{anyhow,bail};
use std::path::PathBuf;
use crate::common;
use bincode2::config::*;
use crate::header::*;
use std::io::{Seek};
use std::io::{
Read,Write,
BufReader,BufWriter,
};
use once_cell::sync::Lazy;
static ENCODING_OPTIONS: Lazy<Configuration> = Lazy::new(bincode2::config::standard);
crate::common::impl_macro_binary!(Bincode2, "bin");
pub unsafe trait Bincode2: bincode2::Encode + bincode2::Decode {
#[doc(hidden)]
#[inline(always)]
fn __from_file() -> Result <Self, anyhow::Error> {
let path = Self::absolute_path()?;
let mut file = std::fs::File::open(path)?;
Self::from_reader(&mut file)
}
#[doc(hidden)]
#[inline(always)]
fn __from_path(path: &std::path::Path) -> Result <Self, anyhow::Error> {
let mut file = std::fs::File::open(path)?;
Self::from_reader(&mut file)
}
#[inline(always)]
fn from_bytes(bytes: &[u8]) -> Result<Self, anyhow::Error> {
ensure_header!(bytes);
match bincode2::decode_from_slice(&bytes[25..], *ENCODING_OPTIONS) {
Ok((s, _)) => Ok(s),
Err(e) => Err(e)?,
}
}
#[inline(always)]
fn to_bytes(&self) -> Result<Vec<u8>, anyhow::Error> {
let mut vec = match bincode2::encode_to_vec(self, *ENCODING_OPTIONS) {
Ok(v) => v,
Err(e) => Err(e)?,
};
header_return!(vec)
}
#[inline(always)]
fn from_reader<R>(reader: &mut R) -> Result<Self, anyhow::Error>
where
R: Read,
{
let mut bytes = [0_u8; 25];
let mut reader = BufReader::new(reader);
reader.read_exact(&mut bytes)?;
ensure_header!(bytes);
Ok(bincode2::decode_from_std_read(&mut reader, *ENCODING_OPTIONS)?)
}
#[inline(always)]
fn to_slice(&self, slice: &mut [u8]) -> Result<usize, anyhow::Error> {
let len = slice.len();
if len < 25 {
bail!("input slice length less than 25: {len}");
}
slice[..25].copy_from_slice(&Self::full_header());
Ok(bincode2::encode_into_slice(self, &mut slice[25..], *ENCODING_OPTIONS)?)
}
#[inline(always)]
fn to_writer<W>(&self, writer: &mut W) -> Result<usize, anyhow::Error>
where
W: Write,
{
let mut writer = BufWriter::new(writer);
writer.write_all(&Self::full_header())?;
Ok(bincode2::encode_into_std_write(self, &mut writer, *ENCODING_OPTIONS)?)
}
impl_header!();
common::impl_binary!("bincode2");
}