#![forbid(unsafe_code)]
use cfg_if::cfg_if;
use std::rc::Rc;
use thiserror::Error;
#[derive(Debug, Clone, Error)]
pub enum SerializationError {
#[error("error serializing Resource: {0}")]
Serialize(Rc<dyn std::error::Error>),
#[error("error deserializing Resource: {0}")]
Deserialize(Rc<dyn std::error::Error>),
}
pub trait Serializable
where
Self: Sized,
{
fn ser(&self) -> Result<String, SerializationError>;
fn de(bytes: &str) -> Result<Self, SerializationError>;
}
cfg_if! {
if #[cfg(feature = "rkyv")] {
use rkyv::{Archive, CheckBytes, Deserialize, Serialize, ser::serializers::AllocSerializer, de::deserializers::SharedDeserializeMap, validation::validators::DefaultValidator};
use base64::Engine as _;
use base64::engine::general_purpose::STANDARD_NO_PAD;
impl<T> Serializable for T
where
T: Serialize<AllocSerializer<1024>>,
T: Archive,
T::Archived: for<'b> CheckBytes<DefaultValidator<'b>> + Deserialize<T, SharedDeserializeMap>,
{
fn ser(&self) -> Result<String, SerializationError> {
let bytes = rkyv::to_bytes::<T, 1024>(self).map_err(|e| SerializationError::Serialize(Rc::new(e)))?;
Ok(STANDARD_NO_PAD.encode(bytes))
}
fn de(serialized: &str) -> Result<Self, SerializationError> {
let bytes = STANDARD_NO_PAD.decode(serialized.as_bytes()).map_err(|e| SerializationError::Deserialize(Rc::new(e)))?;
rkyv::from_bytes::<T>(&bytes).map_err(|e| SerializationError::Deserialize(Rc::new(e)))
}
}
}
else if #[cfg(feature = "miniserde")] {
use miniserde::{json, Deserialize, Serialize};
impl<T> Serializable for T
where
T: Serialize + Deserialize,
{
fn ser(&self) -> Result<String, SerializationError> {
Ok(json::to_string(&self))
}
fn de(json: &str) -> Result<Self, SerializationError> {
json::from_str(json).map_err(|e| SerializationError::Deserialize(Rc::new(e)))
}
}
}
else if #[cfg(feature = "serde-lite")] {
use serde_lite::{Deserialize, Serialize};
impl<T> Serializable for T
where
T: Serialize + Deserialize,
{
fn ser(&self) -> Result<String, SerializationError> {
let intermediate = self
.serialize()
.map_err(|e| SerializationError::Serialize(Rc::new(e)))?;
serde_json::to_string(&intermediate).map_err(|e| SerializationError::Serialize(Rc::new(e)))
}
fn de(json: &str) -> Result<Self, SerializationError> {
let intermediate =
serde_json::from_str(&json).map_err(|e| SerializationError::Deserialize(Rc::new(e)))?;
Self::deserialize(&intermediate).map_err(|e| SerializationError::Deserialize(Rc::new(e)))
}
}
}
else {
use serde::{de::DeserializeOwned, Serialize};
impl<T> Serializable for T
where
T: DeserializeOwned + Serialize,
{
fn ser(&self) -> Result<String, SerializationError> {
serde_json::to_string(&self).map_err(|e| SerializationError::Serialize(Rc::new(e)))
}
fn de(json: &str) -> Result<Self, SerializationError> {
serde_json::from_str(json).map_err(|e| SerializationError::Deserialize(Rc::new(e)))
}
}
}
}