mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-12 23:57:09 +00:00
Migrate rkyv 0.8.x (#3054)
This commit is contained in:
parent
e6da266b4f
commit
8feee5e5d7
9 changed files with 56 additions and 91 deletions
|
@ -40,6 +40,8 @@ pin-project-lite = "0.2.14"
|
|||
dashmap = { version = "6.0", optional = true }
|
||||
once_cell = { version = "1.19", optional = true }
|
||||
async-broadcast = { version = "0.7.1", optional = true }
|
||||
bytecheck = "0.8.0"
|
||||
rkyv = { version = "0.8.8" }
|
||||
|
||||
[features]
|
||||
hydrate = ["leptos/hydrate"]
|
||||
|
|
|
@ -417,7 +417,6 @@ pub fn FileUploadWithProgress() -> impl IntoView {
|
|||
/// This requires us to store some global state of all the uploads. In a real app, you probably
|
||||
/// shouldn't do exactly what I'm doing here in the demo. For example, this map just
|
||||
/// distinguishes between files by filename, not by user.
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
mod progress {
|
||||
use async_broadcast::{broadcast, Receiver, Sender};
|
||||
|
|
|
@ -4,6 +4,8 @@ use leptos::{config::get_configuration, logging};
|
|||
use leptos_axum::{generate_route_list, LeptosRoutes};
|
||||
use server_fns_axum::*;
|
||||
|
||||
// cargo make cli: error: unneeded `return` statement
|
||||
#[allow(clippy::needless_return)]
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
simple_logger::init_with_level(log::Level::Error)
|
||||
|
|
58
flake.lock
58
flake.lock
|
@ -5,29 +5,11 @@
|
|||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701680307,
|
||||
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||
"lastModified": 1726560853,
|
||||
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1681202837,
|
||||
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
|
||||
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -38,11 +20,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1703961334,
|
||||
"narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=",
|
||||
"lastModified": 1727634051,
|
||||
"narHash": "sha256-S5kVU7U82LfpEukbn/ihcyNt2+EvG7Z5unsKW9H/yFA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9",
|
||||
"rev": "06cf0e1da4208d3766d898b7fdab6513366d45b9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -54,11 +36,11 @@
|
|||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1681358109,
|
||||
"narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=",
|
||||
"lastModified": 1718428119,
|
||||
"narHash": "sha256-WdWDpNaq6u1IPtxtYHHWpl5BmabtpmLnMAx0RdJ/vo8=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9",
|
||||
"rev": "e6cea36f83499eb4e9cd184c8a8e823296b50ad5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -77,15 +59,14 @@
|
|||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1704075545,
|
||||
"narHash": "sha256-L3zgOuVKhPjKsVLc3yTm2YJ6+BATyZBury7wnhyc8QU=",
|
||||
"lastModified": 1727749966,
|
||||
"narHash": "sha256-DUS8ehzqB1DQzfZ4bRXVSollJhu+y7cvh1DJ9mbWebE=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "a0df72e106322b67e9c6e591fe870380bd0da0d5",
|
||||
"rev": "00decf1b4f9886d25030b9ee4aed7bfddccb5f66",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -108,21 +89,6 @@
|
|||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_2": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
|
|
|
@ -28,7 +28,7 @@ once_cell = "1"
|
|||
parking_lot = "0.12.3"
|
||||
serde_json = "1.0"
|
||||
tokio = { version = "1.39", default-features = false }
|
||||
tower = "0.4.13"
|
||||
tower = { version = "0.4.13", features = ["util"] }
|
||||
tower-http = "0.5.2"
|
||||
tracing = { version = "0.1.40", optional = true }
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ use server_fn::{redirect::REDIRECT_HEADER, ServerFnError};
|
|||
use std::path::Path;
|
||||
use std::{fmt::Debug, io, pin::Pin, sync::Arc};
|
||||
#[cfg(feature = "default")]
|
||||
use tower::ServiceExt;
|
||||
use tower::util::ServiceExt;
|
||||
#[cfg(feature = "default")]
|
||||
use tower_http::services::ServeDir;
|
||||
// use tracing::Instrument; // TODO check tracing span -- was this used in 0.6 for a missing link?
|
||||
|
|
|
@ -25,8 +25,8 @@ inventory = { version = "0.3.15", optional = true }
|
|||
dashmap = "6.0"
|
||||
once_cell = "1.19"
|
||||
|
||||
## servers
|
||||
# actix
|
||||
## servers
|
||||
# actix
|
||||
actix-web = { version = "4.8", optional = true }
|
||||
|
||||
# axum
|
||||
|
@ -36,12 +36,12 @@ axum = { version = "0.7.5", optional = true, default-features = false, features
|
|||
tower = { version = "0.4.13", optional = true }
|
||||
tower-layer = { version = "0.3.2", optional = true }
|
||||
|
||||
## input encodings
|
||||
## input encodings
|
||||
serde_qs = { version = "0.13.0", optional = true }
|
||||
multer = { version = "3.1", optional = true }
|
||||
|
||||
## output encodings
|
||||
# serde
|
||||
## output encodings
|
||||
# serde
|
||||
serde_json = "1.0"
|
||||
serde-lite = { version = "0.5.0", features = ["derive"], optional = true }
|
||||
futures = "0.3.30"
|
||||
|
@ -51,11 +51,7 @@ postcard = { version = "1", features = ["alloc"], optional = true }
|
|||
hyper = { version = "1.4", optional = true }
|
||||
bytes = "1.7"
|
||||
http-body-util = { version = "0.1.2", optional = true }
|
||||
rkyv = { version = "0.7.44", features = [
|
||||
"validation",
|
||||
"uuid",
|
||||
"strict",
|
||||
], optional = true }
|
||||
rkyv = { version = "0.8.8", optional = true }
|
||||
rmp-serde = { version = "1.3.0", optional = true }
|
||||
|
||||
# client
|
||||
|
@ -72,7 +68,7 @@ web-sys = { version = "0.3.70", optional = true, features = [
|
|||
"AbortSignal",
|
||||
] }
|
||||
|
||||
# reqwest client
|
||||
# reqwest client
|
||||
reqwest = { version = "0.12.5", default-features = false, optional = true, features = [
|
||||
"multipart",
|
||||
"stream",
|
||||
|
|
|
@ -8,11 +8,19 @@ use bytes::Bytes;
|
|||
use futures::StreamExt;
|
||||
use http::Method;
|
||||
use rkyv::{
|
||||
de::deserializers::SharedDeserializeMap, ser::serializers::AllocSerializer,
|
||||
validation::validators::DefaultValidator, AlignedVec, Archive, CheckBytes,
|
||||
Deserialize, Serialize,
|
||||
api::high::{HighDeserializer, HighSerializer, HighValidator},
|
||||
bytecheck::CheckBytes,
|
||||
rancor,
|
||||
ser::allocator::ArenaHandle,
|
||||
util::AlignedVec,
|
||||
Archive, Deserialize, Serialize,
|
||||
};
|
||||
|
||||
type RkyvSerializer<'a> =
|
||||
HighSerializer<AlignedVec, ArenaHandle<'a>, rancor::Error>;
|
||||
type RkyvDeserializer = HighDeserializer<rancor::Error>;
|
||||
type RkyvValidator<'a> = HighValidator<'a, rancor::Error>;
|
||||
|
||||
/// Pass arguments and receive responses using `rkyv` in a `POST` request.
|
||||
pub struct Rkyv;
|
||||
|
||||
|
@ -24,17 +32,16 @@ impl Encoding for Rkyv {
|
|||
impl<CustErr, T, Request> IntoReq<Rkyv, Request, CustErr> for T
|
||||
where
|
||||
Request: ClientReq<CustErr>,
|
||||
T: Serialize<AllocSerializer<1024>> + Send,
|
||||
T: Archive,
|
||||
T::Archived: for<'a> CheckBytes<DefaultValidator<'a>>
|
||||
+ Deserialize<T, SharedDeserializeMap>,
|
||||
T: Archive + for<'a> Serialize<RkyvSerializer<'a>>,
|
||||
T::Archived: Deserialize<T, RkyvDeserializer>
|
||||
+ for<'a> CheckBytes<RkyvValidator<'a>>,
|
||||
{
|
||||
fn into_req(
|
||||
self,
|
||||
path: &str,
|
||||
accepts: &str,
|
||||
) -> Result<Request, ServerFnError<CustErr>> {
|
||||
let encoded = rkyv::to_bytes::<T, 1024>(&self)
|
||||
let encoded = rkyv::to_bytes::<rancor::Error>(&self)
|
||||
.map_err(|e| ServerFnError::Serialization(e.to_string()))?;
|
||||
let bytes = Bytes::copy_from_slice(encoded.as_ref());
|
||||
Request::try_new_post_bytes(path, accepts, Rkyv::CONTENT_TYPE, bytes)
|
||||
|
@ -44,13 +51,12 @@ where
|
|||
impl<CustErr, T, Request> FromReq<Rkyv, Request, CustErr> for T
|
||||
where
|
||||
Request: Req<CustErr> + Send + 'static,
|
||||
T: Serialize<AllocSerializer<1024>> + Send,
|
||||
T: Archive,
|
||||
T::Archived: for<'a> CheckBytes<DefaultValidator<'a>>
|
||||
+ Deserialize<T, SharedDeserializeMap>,
|
||||
T: Archive + for<'a> Serialize<RkyvSerializer<'a>>,
|
||||
T::Archived: Deserialize<T, RkyvDeserializer>
|
||||
+ for<'a> CheckBytes<RkyvValidator<'a>>,
|
||||
{
|
||||
async fn from_req(req: Request) -> Result<Self, ServerFnError<CustErr>> {
|
||||
let mut aligned = AlignedVec::new();
|
||||
let mut aligned = AlignedVec::<1024>::new();
|
||||
let mut body_stream = Box::pin(req.try_into_stream()?);
|
||||
while let Some(chunk) = body_stream.next().await {
|
||||
match chunk {
|
||||
|
@ -64,7 +70,7 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
rkyv::from_bytes::<T>(aligned.as_ref())
|
||||
rkyv::from_bytes::<T, rancor::Error>(aligned.as_ref())
|
||||
.map_err(|e| ServerFnError::Args(e.to_string()))
|
||||
}
|
||||
}
|
||||
|
@ -72,14 +78,14 @@ where
|
|||
impl<CustErr, T, Response> IntoRes<Rkyv, Response, CustErr> for T
|
||||
where
|
||||
Response: Res<CustErr>,
|
||||
T: Serialize<AllocSerializer<1024>> + Send,
|
||||
T: Archive,
|
||||
T::Archived: for<'a> CheckBytes<DefaultValidator<'a>>
|
||||
+ Deserialize<T, SharedDeserializeMap>,
|
||||
T: Send,
|
||||
T: Archive + for<'a> Serialize<RkyvSerializer<'a>>,
|
||||
T::Archived: Deserialize<T, RkyvDeserializer>
|
||||
+ for<'a> CheckBytes<RkyvValidator<'a>>,
|
||||
{
|
||||
async fn into_res(self) -> Result<Response, ServerFnError<CustErr>> {
|
||||
let encoded = rkyv::to_bytes::<T, 1024>(&self)
|
||||
.map_err(|e| ServerFnError::Serialization(e.to_string()))?;
|
||||
let encoded = rkyv::to_bytes::<rancor::Error>(&self)
|
||||
.map_err(|e| ServerFnError::Serialization(format!("{e:?}")))?;
|
||||
let bytes = Bytes::copy_from_slice(encoded.as_ref());
|
||||
Response::try_from_bytes(Rkyv::CONTENT_TYPE, bytes)
|
||||
}
|
||||
|
@ -88,14 +94,13 @@ where
|
|||
impl<CustErr, T, Response> FromRes<Rkyv, Response, CustErr> for T
|
||||
where
|
||||
Response: ClientRes<CustErr> + Send,
|
||||
T: Serialize<AllocSerializer<1024>> + Send,
|
||||
T: Archive,
|
||||
T::Archived: for<'a> CheckBytes<DefaultValidator<'a>>
|
||||
+ Deserialize<T, SharedDeserializeMap>,
|
||||
T: Archive + for<'a> Serialize<RkyvSerializer<'a>>,
|
||||
T::Archived: Deserialize<T, RkyvDeserializer>
|
||||
+ for<'a> CheckBytes<RkyvValidator<'a>>,
|
||||
{
|
||||
async fn from_res(res: Response) -> Result<Self, ServerFnError<CustErr>> {
|
||||
let data = res.try_into_bytes().await?;
|
||||
rkyv::from_bytes::<T>(&data)
|
||||
rkyv::from_bytes::<T, rancor::Error>(&data)
|
||||
.map_err(|e| ServerFnError::Deserialization(e.to_string()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -505,12 +505,7 @@ pub fn server_macro_impl(
|
|||
PathInfo::Serde => quote! {
|
||||
#[serde(crate = #serde_path)]
|
||||
},
|
||||
PathInfo::Rkyv => {
|
||||
let rkyv_path = format!("{server_fn_path}::rkyv");
|
||||
quote! {
|
||||
#[archive(crate = #rkyv_path, check_bytes)]
|
||||
}
|
||||
}
|
||||
PathInfo::Rkyv => quote! {},
|
||||
PathInfo::None => quote! {},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue