#[cfg(feature = "json")]
pub use json::*;
#[cfg(feature = "json")]
mod json {
use std::io::Write;
use serde::{Serialize, de::DeserializeOwned};
use smol_str::SmolStr;
use crate::uformat_smolstr;
pub trait JSONSerialize
where
Self: Serialize,
{
fn write_json<W: Write>(&self, writer: &mut W) -> Result<(), SmolStr> {
serde_json::to_writer(writer, self)
.map_err(|e| uformat_smolstr!("Serialization (json) failed: {}", e.to_string()))
}
fn to_json(&self) -> Result<Vec<u8>, SmolStr> {
let mut buffer = Vec::with_capacity(8192);
self.write_json(&mut buffer)?;
Ok(buffer)
}
}
pub trait JSONDeserialize
where
Self: DeserializeOwned,
{
fn try_from_json(json: &[u8]) -> Result<Self, SmolStr> {
serde_json::from_slice::<Self>(json)
.map_err(|e| uformat_smolstr!("Deserialization (json) failed: {}", e.to_string()))
}
}
impl<E> JSONSerialize for E where E: Serialize {}
impl<E> JSONDeserialize for E where E: DeserializeOwned {}
}
#[cfg(feature = "postcard")]
pub use postcard::*;
#[cfg(feature = "postcard")]
mod postcard {
use std::io::Write;
use base64::{Engine, engine::general_purpose};
use postcard::{ser_flavors::Flavor, serialize_with_flavor};
use serde::{Serialize, de::DeserializeOwned};
use smol_str::SmolStr;
use crate::uformat_smolstr;
struct PostcardWriteStorage<'a, W> {
writer: &'a mut W,
}
impl<W> Flavor for PostcardWriteStorage<'_, W>
where
W: Write,
{
type Output = ();
fn try_push(&mut self, data: u8) -> postcard::Result<()> {
self.try_extend(&[data])
}
fn finalize(self) -> postcard::Result<Self::Output> {
Ok(())
}
fn try_extend(&mut self, data: &[u8]) -> postcard::Result<()> {
match self.writer.write_all(data) {
Ok(_) => Ok(()),
Err(_) => Err(postcard::Error::SerializeBufferFull),
}
}
}
pub trait PostcardSerialize
where
Self: Serialize,
{
fn write_postcard<W: Write>(&self, writer: &mut W) -> Result<(), SmolStr> {
let storage = PostcardWriteStorage { writer };
serialize_with_flavor(self, storage)
.map_err(|e| uformat_smolstr!("Serialization (postcard) failed: {}", e.to_string()))
}
fn to_postcard(&self) -> Result<Vec<u8>, SmolStr> {
let mut buffer = Vec::with_capacity(4096);
self.write_postcard(&mut buffer)?;
Ok(buffer)
}
fn to_postcard_base64(&self) -> Result<SmolStr, SmolStr> {
self.to_postcard()
.map(|payload| general_purpose::STANDARD.encode(payload).into())
}
}
pub trait PostcardDeserialize
where
Self: DeserializeOwned,
{
fn try_from_postcard(postcard: &[u8]) -> Result<Self, SmolStr> {
postcard::from_bytes::<Self>(postcard).map_err(|e| {
uformat_smolstr!("Deserialization (postcard) failed: {}", e.to_string())
})
}
fn try_from_postcard_base64(base64: impl AsRef<[u8]>) -> Result<Self, SmolStr> {
general_purpose::STANDARD
.decode(base64)
.map_err(|e| {
uformat_smolstr!(
"Deserialization (base64 of postcard) failed: {}",
e.to_string()
)
})
.and_then(|postcard| Self::try_from_postcard(&postcard))
}
}
impl<E> PostcardSerialize for E where E: Serialize {}
impl<E> PostcardDeserialize for E where E: DeserializeOwned {}
}