feat: support `rkyv` encoding (#577)

This commit is contained in:
Azz 2023-02-26 21:12:53 +00:00 committed by GitHub
parent 34f7b90177
commit b153ab51ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 46 additions and 21 deletions

View File

@ -34,7 +34,7 @@ where
abort_controller.abort()
}
});
T::from_json(&json).ok()
T::de(&json).ok()
}
#[cfg(feature = "ssr")]
@ -49,7 +49,7 @@ where
.text()
.await
.ok()?;
T::from_json(&json).map_err(|e| log::error!("{e}")).ok()
T::de(&json).map_err(|e| log::error!("{e}")).ok()
}
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]

View File

@ -34,7 +34,7 @@ where
abort_controller.abort()
}
});
T::from_json(&json).ok()
T::de(&json).ok()
}
#[cfg(feature = "ssr")]
@ -49,7 +49,7 @@ where
.text()
.await
.ok()?;
T::from_json(&json).map_err(|e| log::error!("{e}")).ok()
T::de(&json).map_err(|e| log::error!("{e}")).ok()
}
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]

View File

@ -50,6 +50,7 @@ stable = [
serde = ["leptos_reactive/serde"]
serde-lite = ["leptos_reactive/serde-lite"]
miniserde = ["leptos_reactive/miniserde"]
rkyv = ["leptos_reactive/rkyv"]
tracing = ["leptos_macro/tracing"]
[package.metadata.cargo-all-features]

View File

@ -14,6 +14,8 @@ serde-lite = { version = "0.3", optional = true }
futures = { version = "0.3" }
js-sys = "0.3"
miniserde = { version = "0.1", optional = true }
rkyv = { version = "0.7.39", features = ["validation", "uuid", "copy", "strict"], optional = true }
bytecheck = { version = "0.6.9", features = ["uuid", "simdutf8_std", "simdutf8"], optional = true }
serde-wasm-bindgen = "0.4"
serde_json = "1"
base64 = "0.21"
@ -45,6 +47,7 @@ stable = []
serde = []
serde-lite = ["dep:serde-lite"]
miniserde = ["dep:miniserde"]
rkyv = ["dep:rkyv", "dep:bytecheck"]
[package.metadata.cargo-all-features]
denylist = ["stable"]

View File

@ -307,7 +307,7 @@ where
context.pending_resources.remove(&id); // no longer pending
r.resolved.set(true);
let res = T::from_json(&data)
let res = T::de(&data)
.expect_throw("could not deserialize Resource JSON");
r.set_value.update(|n| *n = Some(res));
@ -326,7 +326,7 @@ where
let set_value = r.set_value;
let set_loading = r.set_loading;
move |res: String| {
let res = T::from_json(&res)
let res = T::de(&res)
.expect_throw("could not deserialize Resource JSON");
resolved.set(true);
set_value.update(|n| *n = Some(res));
@ -680,9 +680,7 @@ where
if let Some(value) = value.as_ref() {
tx.try_send((
id,
value
.to_json()
.expect("could not serialize Resource"),
value.ser().expect("could not serialize Resource"),
))
.expect(
"failed while trying to write to Resource \

View File

@ -30,27 +30,50 @@ pub trait Serializable
where
Self: Sized,
{
/// Serializes the object to JSON.
fn to_json(&self) -> Result<String, SerializationError>;
/// Serializes the object to a string.
fn ser(&self) -> Result<String, SerializationError>;
/// Deserializes the object from JSON.
fn from_json(json: &str) -> Result<Self, SerializationError>;
/// Deserializes the object from some bytes.
fn de(bytes: &str) -> Result<Self, SerializationError>;
}
cfg_if! {
if #[cfg(feature = "rkyv")] {
use rkyv::{Archive, Deserialize, Serialize, ser::serializers::AllocSerializer, de::deserializers::SharedDeserializeMap, validation::validators::DefaultValidator};
use bytecheck::CheckBytes;
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)))
}
}
}
// prefer miniserde if it's chosen
if #[cfg(feature = "miniserde")] {
else if #[cfg(feature = "miniserde")] {
use miniserde::{json, Deserialize, Serialize};
impl<T> Serializable for T
where
T: Serialize + Deserialize,
{
fn to_json(&self) -> Result<String, SerializationError> {
fn ser(&self) -> Result<String, SerializationError> {
Ok(json::to_string(&self))
}
fn from_json(json: &str) -> Result<Self, SerializationError> {
fn de(json: &str) -> Result<Self, SerializationError> {
json::from_str(json).map_err(|e| SerializationError::Deserialize(Rc::new(e)))
}
}
@ -64,14 +87,14 @@ cfg_if! {
where
T: Serialize + Deserialize,
{
fn to_json(&self) -> Result<String, SerializationError> {
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 from_json(json: &str) -> Result<Self, SerializationError> {
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)))
@ -87,11 +110,11 @@ cfg_if! {
where
T: DeserializeOwned + Serialize,
{
fn to_json(&self) -> Result<String, SerializationError> {
fn ser(&self) -> Result<String, SerializationError> {
serde_json::to_string(&self).map_err(|e| SerializationError::Serialize(Rc::new(e)))
}
fn from_json(json: &str) -> Result<Self, SerializationError> {
fn de(json: &str) -> Result<Self, SerializationError> {
serde_json::from_str(json).map_err(|e| SerializationError::Deserialize(Rc::new(e)))
}

View File

@ -229,7 +229,7 @@ where
.await;
match body {
Ok(json) => {
match O::from_json(
match O::de(
&json
.as_string()
.expect("couldn't get String from JsString"),