#![cfg_attr(test, feature(test))]
#![forbid(unsafe_code)]
#[cfg(test)]
extern crate core;
#[cfg(test)]
extern crate test;
pub use buffer::Buffer;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
mod buffer;
mod de;
mod nightly;
mod read;
mod ser;
mod word;
mod word_buffer;
mod write;
#[cfg(all(test, not(miri)))]
mod benches;
#[cfg(test)]
mod bit_buffer;
#[cfg(test)]
mod tests;
pub fn serialize<T: ?Sized>(t: &T) -> Result<Vec<u8>>
where
T: Serialize,
{
Ok(Buffer::new().serialize(t)?.to_vec())
}
pub fn deserialize<'a, T>(bytes: &'a [u8]) -> Result<T>
where
T: Deserialize<'a>,
{
Buffer::new().deserialize(bytes)
}
impl Buffer {
pub fn serialize<T: ?Sized>(&mut self, t: &T) -> Result<&[u8]>
where
T: Serialize,
{
ser::serialize_internal(&mut self.0, t)
}
pub fn deserialize<'a, T>(&mut self, bytes: &'a [u8]) -> Result<T>
where
T: Deserialize<'a>,
{
de::deserialize_internal(&mut self.0, bytes)
}
}
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq))]
pub struct Error(ErrorImpl);
#[cfg(not(debug_assertions))]
type ErrorImpl = ();
#[cfg(debug_assertions)]
type ErrorImpl = E;
impl Error {
pub(crate) fn map_invalid(self, _s: &'static str) -> Self {
#[cfg(debug_assertions)]
return Self(match self.0 {
E::Invalid(_) => E::Invalid(_s),
_ => self.0,
});
#[cfg(not(debug_assertions))]
self
}
pub(crate) fn same(&self, other: &Self) -> bool {
self.0 == other.0
}
}
#[derive(Debug, PartialEq)]
pub(crate) enum E {
#[cfg(debug_assertions)]
Custom(String),
Eof,
ExpectedEof,
Invalid(&'static str),
NotSupported(&'static str),
}
impl E {
fn e(self) -> Error {
#[cfg(debug_assertions)]
return Error(self);
#[cfg(not(debug_assertions))]
Error(())
}
}
type Result<T> = std::result::Result<T, Error>;
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
#[cfg(debug_assertions)]
return Display::fmt(&self.0, f);
#[cfg(not(debug_assertions))]
f.write_str("bitcode error")
}
}
impl Display for E {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
#[cfg(debug_assertions)]
Self::Custom(s) => write!(f, "custom: {s}"),
Self::Eof => write!(f, "eof"),
Self::ExpectedEof => write!(f, "expected eof"),
Self::Invalid(s) => write!(f, "invalid {s}"),
Self::NotSupported(s) => write!(f, "{s} is not supported"),
}
}
}
impl std::error::Error for Error {}
impl serde::ser::Error for Error {
fn custom<T>(_msg: T) -> Self
where
T: Display,
{
#[cfg(debug_assertions)]
return Self(E::Custom(_msg.to_string()));
#[cfg(not(debug_assertions))]
Self(())
}
}
impl serde::de::Error for Error {
fn custom<T>(_msg: T) -> Self
where
T: Display,
{
#[cfg(debug_assertions)]
return Self(E::Custom(_msg.to_string()));
#[cfg(not(debug_assertions))]
Self(())
}
}