#[cfg(all(feature = "deser_borsh", feature = "deser_json"))]
pub trait Serialize: borsh::BorshSerialize + serde::Serialize {}
#[cfg(all(feature = "deser_borsh", feature = "deser_json"))]
impl<T> Serialize for T where T: borsh::BorshSerialize + serde::Serialize {}
#[cfg(all(feature = "deser_borsh", feature = "deser_json"))]
pub trait Deserialize: borsh::BorshDeserialize + serde::de::DeserializeOwned {}
#[cfg(all(feature = "deser_borsh", feature = "deser_json"))]
impl<T> Deserialize for T where T: borsh::BorshDeserialize + serde::de::DeserializeOwned {}
#[cfg(all(feature = "deser_borsh", not(feature = "deser_json")))]
pub trait Serialize: borsh::BorshSerialize {}
#[cfg(all(feature = "deser_borsh", not(feature = "deser_json")))]
impl<T> Serialize for T where T: borsh::BorshSerialize {}
#[cfg(all(feature = "deser_borsh", not(feature = "deser_json")))]
pub trait Deserialize: borsh::BorshDeserialize {}
#[cfg(all(feature = "deser_borsh", not(feature = "deser_json")))]
impl<T> Deserialize for T where T: borsh::BorshDeserialize {}
#[derive(Debug, Copy, Clone)]
pub enum Deser {
#[cfg(feature = "deser_borsh")]
Borsh,
#[cfg(feature = "deser_json")]
Json,
}
impl Deser {
pub fn from_slice<T>(&self, bytes: &[u8]) -> Result<T, Error>
where
T: Deserialize,
{
match self {
#[cfg(feature = "deser_borsh")]
Self::Borsh => {
Ok(<T as borsh::BorshDeserialize>::try_from_slice(bytes)
.map_err(Error::Borsh)?)
}
#[cfg(feature = "deser_json")]
Self::Json => Ok(serde_json::from_slice(bytes)?),
}
}
pub fn to_vec<T>(&self, t: &T) -> Result<Vec<u8>, Error>
where
T: Serialize,
{
match self {
#[cfg(feature = "deser_borsh")]
Self::Borsh => {
Ok(<T as borsh::BorshSerialize>::try_to_vec(t)
.map_err(Error::Borsh)?)
}
#[cfg(feature = "deser_json")]
Self::Json => Ok(cjson::to_vec(t)?),
}
}
}
#[cfg(all(feature = "deser_borsh"))]
impl Default for Deser {
fn default() -> Self {
Self::Borsh
}
}
#[cfg(all(feature = "deser_json", not(feature = "deser_borsh")))]
impl Default for Deser {
fn default() -> Self {
Self::Json
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[cfg(feature = "deser_borsh")]
#[error("borsh error: `{0:?}`")]
Borsh(std::io::Error),
#[cfg(feature = "deser_json")]
#[error("serde_json error: `{0:?}`")]
SerdeJson(#[from] serde_json::Error),
#[cfg(feature = "deser_json")]
#[error("cjson error: `{0:?}`")]
Cjson(cjson::Error),
}
#[cfg(feature = "deser_json")]
impl From<cjson::Error> for Error {
fn from(err: cjson::Error) -> Self {
Self::Cjson(err)
}
}
#[cfg(test)]
pub mod test {
use {super::*, crate::value::Value};
#[cfg(feature = "deser_borsh")]
#[tokio::test]
async fn borsh() {
let mut env_builder = env_logger::builder();
env_builder.is_test(true);
if std::env::var("RUST_LOG").is_err() {
env_builder.filter(Some("fixity"), log::LevelFilter::Debug);
}
let expected = Value::from(1);
let bytes = Deser::to_vec(&Deser::Borsh, &expected).unwrap();
let got = Deser::from_slice::<Value>(&Deser::Borsh, &bytes).unwrap();
assert_eq!(expected, got);
}
#[cfg(feature = "deser_json")]
#[tokio::test]
async fn json() {
let mut env_builder = env_logger::builder();
env_builder.is_test(true);
if std::env::var("RUST_LOG").is_err() {
env_builder.filter(Some("fixity"), log::LevelFilter::Debug);
}
let expected = Value::from(1);
let bytes = Deser::to_vec(&Deser::Json, &expected).unwrap();
let got = Deser::from_slice::<Value>(&Deser::Json, &bytes).unwrap();
assert_eq!(expected, got);
}
}