use super::*;
use std::error::Error;
#[derive(Debug)]
pub enum SerError {
InvalidData(String),
InvalidType(String),
BufferError(String),
NoBuffersAvailable(String),
NoClone,
Unknown(String),
ThirdParty {
context: String,
source: Box<dyn Error + 'static>,
},
}
impl SerError {
pub fn from_debug<E: Debug>(error: E) -> SerError {
let msg = format!("Wrapped error: {:?}", error);
SerError::Unknown(msg)
}
}
impl fmt::Display for SerError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SerError::BufferError(s) => {
write!(f, "An issue occurred with the serialisation buffers: {}", s)
}
SerError::InvalidData(s) => write!(
f,
"The provided data was not appropriate for (de-)serialisation: {}",
s
),
SerError::InvalidType(s) => write!(
f,
"The provided type was not appropriate for (de-)serialisation: {}",
s
),
SerError::NoClone => write!(
f,
"The provided type can not be cloned, but try_clone() was attempted"
),
SerError::NoBuffersAvailable(s) => write!(
f,
"Serialising into a BufferPool with no available buffers: {}",
s
),
SerError::Unknown(s) => write!(f, "A serialisation error occurred: {}", s),
SerError::ThirdParty { context, source } => write!(
f,
"A serialisation error occurred in a third party crate: {context}\n Caused by {source}"
),
}
}
}
impl std::error::Error for SerError {}
pub trait SerialisationId {
const SER_ID: SerId;
}
pub trait Serialiser<T>: Send + TryClone {
fn ser_id(&self) -> SerId;
fn size_hint(&self) -> Option<usize> {
None
}
fn serialise(&self, v: &T, buf: &mut dyn BufMut) -> Result<(), SerError>;
fn try_clone_data(&self, _v: &T) -> Option<T> {
None
}
}
pub trait Serialisable: Send + Debug {
fn ser_id(&self) -> SerId;
fn size_hint(&self) -> Option<usize>;
fn serialise(&self, buf: &mut dyn BufMut) -> Result<(), SerError>;
fn local(self: Box<Self>) -> Result<Box<dyn Any + Send>, Box<dyn Serialisable>>;
fn serialised(&self) -> Result<crate::messaging::Serialised, SerError> {
crate::serialisation::ser_helpers::serialise_to_serialised(self)
}
fn cloned(&self) -> Option<Box<dyn Serialisable>> {
None
}
}
impl<T, S> From<(T, S)> for SerialisableValue<T, S>
where
T: Send + Debug + 'static,
S: Serialiser<T> + 'static,
{
fn from(t: (T, S)) -> Self {
SerialisableValue::from_tuple(t)
}
}
impl<T, S> From<(T, S)> for Box<dyn Serialisable>
where
T: Send + Debug + 'static,
S: Serialiser<T> + 'static,
{
fn from(t: (T, S)) -> Self {
let sv: SerialisableValue<T, S> = t.into();
Box::new(sv) as Box<dyn Serialisable>
}
}
impl<T> From<T> for Box<dyn Serialisable>
where
T: Send + Debug + Serialisable + Sized + 'static,
{
fn from(t: T) -> Self {
Box::new(t) as Box<dyn Serialisable>
}
}
pub struct SerialisableValue<T, S>
where
T: Send + Debug,
S: Serialiser<T>,
{
pub v: T,
pub ser: S,
}
impl<T, S> SerialisableValue<T, S>
where
T: Send + Debug + 'static,
S: Serialiser<T>,
{
pub fn new(v: T, ser: S) -> Self {
SerialisableValue { v, ser }
}
pub fn from_tuple(t: (T, S)) -> Self {
Self::new(t.0, t.1)
}
}
impl<T, S> Serialisable for SerialisableValue<T, S>
where
T: Send + Debug + 'static,
S: Serialiser<T> + 'static,
{
fn ser_id(&self) -> SerId {
self.ser.ser_id()
}
fn size_hint(&self) -> Option<usize> {
self.ser.size_hint()
}
fn serialise(&self, buf: &mut dyn BufMut) -> Result<(), SerError> {
self.ser.serialise(&self.v, buf)
}
fn local(self: Box<Self>) -> Result<Box<dyn Any + Send>, Box<dyn Serialisable>> {
let b: Box<dyn Any + Send> = Box::new(self.v);
Ok(b)
}
fn cloned(&self) -> Option<Box<dyn Serialisable>> {
self.ser.try_clone().ok().and_then(|ser| {
self.ser.try_clone_data(&self.v).map(|v| {
let b: Box<dyn Serialisable> = Box::new(SerialisableValue::new(v, ser));
b
})
})
}
}
impl<T, S> Debug for SerialisableValue<T, S>
where
T: Send + Debug,
S: Serialiser<T>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(
f,
"Serialisable(id={:?},size={:?}, value={:?})",
self.ser.ser_id(),
self.ser.size_hint(),
self.v
)
}
}
pub trait Deserialiser<T>: Send {
const SER_ID: SerId;
fn deserialise(buf: &mut dyn Buf) -> Result<T, SerError>;
}
pub trait Deserialisable<T> {
fn ser_id(&self) -> SerId;
fn get_deserialised(self) -> Result<T, SerError>;
}