use super::*; pub use bytecheck::CheckBytes; use core::fmt::Debug; use rkyv::Archive as RkyvArchive; use rkyv::Deserialize as RkyvDeserialize; use rkyv::Serialize as RkyvSerialize; // Don't trace these functions as they are used in the transfer of API logs, which will recurse! // #[instrument(level = "trace", ret, err)] pub fn deserialize_json<'a, T: de::Deserialize<'a> + Debug>( arg: &'a str, ) -> Result { serde_json::from_str(arg).map_err(|e| VeilidAPIError::ParseError { message: e.to_string(), value: format!( "deserialize_json:\n---\n{}\n---\n to type {}", arg, std::any::type_name::() ), }) } // #[instrument(level = "trace", ret, err)] pub fn deserialize_opt_json( arg: Option, ) -> Result { let arg = arg.as_ref().ok_or_else(|| VeilidAPIError::ParseError { message: "invalid null string".to_owned(), value: format!( "deserialize_json_opt: null to type {}", std::any::type_name::() ), })?; deserialize_json(arg) } // #[instrument(level = "trace", ret)] pub fn serialize_json(val: T) -> String { match serde_json::to_string(&val) { Ok(v) => v, Err(e) => { panic!("failed to serialize json value: {}\nval={:?}", e, val); } } } pub mod json_as_base64 { use data_encoding::BASE64URL_NOPAD; use serde::{Deserialize, Deserializer, Serialize, Serializer}; pub fn serialize(v: &Vec, s: S) -> Result { let base64 = BASE64URL_NOPAD.encode(v); String::serialize(&base64, s) } pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result, D::Error> { let base64 = String::deserialize(d)?; BASE64URL_NOPAD .decode(base64.as_bytes()) .map_err(|e| serde::de::Error::custom(e)) } } pub mod json_as_string { use std::fmt::Display; use std::str::FromStr; use serde::{de, Deserialize, Deserializer, Serializer}; pub fn serialize(value: &T, serializer: S) -> Result where T: Display, S: Serializer, { serializer.collect_str(value) } pub fn deserialize<'de, T, D>(deserializer: D) -> Result where T: FromStr, T::Err: Display, D: Deserializer<'de>, { String::deserialize(deserializer)? .parse() .map_err(de::Error::custom) } } pub mod opt_json_as_string { use std::fmt::Display; use std::str::FromStr; use serde::{de, Deserialize, Deserializer, Serializer}; pub fn serialize(value: &Option, serializer: S) -> Result where T: Display, S: Serializer, { match value { Some(v) => serializer.collect_str(v), None => serializer.serialize_none(), } } pub fn deserialize<'de, T, D>(deserializer: D) -> Result, D::Error> where T: FromStr, T::Err: Display, D: Deserializer<'de>, { match Option::::deserialize(deserializer)? { None => Ok(None), Some(v) => Ok(Some(v.parse::().map_err(de::Error::custom)?)), } } } pub mod arc_serialize { use alloc::sync::Arc; use serde::{Deserialize, Deserializer, Serialize, Serializer}; pub fn serialize(v: &Arc, s: S) -> Result { T::serialize(v.as_ref(), s) } pub fn deserialize<'de, T: Deserialize<'de>, D: Deserializer<'de>>( d: D, ) -> Result, D::Error> { Ok(Arc::new(T::deserialize(d)?)) } } pub fn to_rkyv(v: &T) -> EyreResult> where T: RkyvSerialize>, { Ok(rkyv::to_bytes::(v) .wrap_err("failed to freeze object")? .to_vec()) } pub fn from_rkyv(v: Vec) -> EyreResult where T: RkyvArchive, ::Archived: for<'t> bytecheck::CheckBytes>, ::Archived: rkyv::Deserialize, { match rkyv::from_bytes::(&v) { Ok(v) => Ok(v), Err(e) => { bail!("failed to deserialize frozen object: {}", e); } } } pub struct RkyvEnumSet; impl rkyv::with::ArchiveWith> for RkyvEnumSet where T: EnumSetType + EnumSetTypeWithRepr, ::Repr: rkyv::Archive, { type Archived = rkyv::Archived<::Repr>; type Resolver = rkyv::Resolver<::Repr>; #[inline] unsafe fn resolve_with( field: &EnumSet, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived, ) { let r = field.as_repr(); r.resolve(pos, resolver, out); } } impl rkyv::with::SerializeWith, S> for RkyvEnumSet where S: rkyv::Fallible + ?Sized, T: EnumSetType + EnumSetTypeWithRepr, ::Repr: rkyv::Serialize, { fn serialize_with(field: &EnumSet, serializer: &mut S) -> Result { let r = field.as_repr(); r.serialize(serializer) } } impl rkyv::with::DeserializeWith::Repr>, EnumSet, D> for RkyvEnumSet where D: rkyv::Fallible + ?Sized, T: EnumSetType + EnumSetTypeWithRepr, ::Repr: rkyv::Archive, rkyv::Archived<::Repr>: rkyv::Deserialize<::Repr, D>, { fn deserialize_with( field: &rkyv::Archived<::Repr>, deserializer: &mut D, ) -> Result, D::Error> { Ok(EnumSet::::from_repr(field.deserialize(deserializer)?)) } }