pub trait ViaductSerialize {
type Error: std::fmt::Debug;
fn to_pipeable(&self, buf: &mut Vec<u8>) -> Result<(), Self::Error>;
}
pub trait ViaductDeserialize: Sized {
type Error: std::fmt::Debug;
fn from_pipeable(bytes: &[u8]) -> Result<Self, Self::Error>;
}
#[derive(Clone, Copy, Debug)]
pub enum Never {}
impl ViaductSerialize for Never {
type Error = std::convert::Infallible;
fn to_pipeable(&self, _buf: &mut Vec<u8>) -> Result<(), Self::Error> {
unreachable!()
}
}
impl ViaductDeserialize for Never {
type Error = std::convert::Infallible;
fn from_pipeable(_bytes: &[u8]) -> Result<Self, Self::Error> {
unreachable!()
}
}
#[cfg(feature = "bincode")]
mod bincode {
use super::{ViaductDeserialize, ViaductSerialize};
impl<T: serde::Serialize> ViaductSerialize for T {
type Error = bincode::Error;
#[inline]
fn to_pipeable(&self, mut buf: &mut Vec<u8>) -> Result<(), Self::Error> {
bincode::serialize_into(&mut buf, self)
}
}
impl<T: serde::de::DeserializeOwned> ViaductDeserialize for T {
type Error = bincode::Error;
#[inline]
fn from_pipeable(bytes: &[u8]) -> Result<Self, Self::Error> {
bincode::deserialize(bytes)
}
}
}
#[cfg(feature = "speedy")]
mod speedy {
use super::{ViaductDeserialize, ViaductSerialize};
#[cfg(target_endian = "little")]
type SpeedyEndian = speedy::LittleEndian;
#[cfg(target_endian = "big")]
type SpeedyEndian = speedy::BigEndian;
impl<T: speedy::Writable<SpeedyEndian>> ViaductSerialize for T {
type Error = speedy::Error;
#[inline]
fn to_pipeable(&self, mut buf: &mut Vec<u8>) -> Result<(), Self::Error> {
self.write_to_stream(&mut buf)
}
}
impl<'de, T: speedy::Readable<'de, SpeedyEndian>> ViaductDeserialize for T {
type Error = speedy::Error;
#[inline]
fn from_pipeable(bytes: &[u8]) -> Result<Self, Self::Error> {
Self::read_from_buffer_copying_data(bytes)
}
}
}
#[cfg(all(feature = "bytemuck", not(any(feature = "bincode", feature = "speedy"))))]
mod primitives {
use super::{ViaductDeserialize, ViaductSerialize};
impl<T: bytemuck::Pod> ViaductSerialize for T {
type Error = bytemuck::PodCastError;
fn to_pipeable(&self, buf: &mut Vec<u8>) -> Result<(), Self::Error> {
buf.extend_from_slice(bytemuck::bytes_of(self));
Ok(())
}
}
impl<T: bytemuck::Pod> ViaductDeserialize for T {
type Error = bytemuck::PodCastError;
fn from_pipeable(bytes: &[u8]) -> Result<Self, Self::Error> {
bytemuck::try_from_bytes(bytes).copied()
}
}
}