diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 9d3d630..ff9d038 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -8,6 +8,8 @@ serde = { version = "1.0", features = ["derive"] } utoipa = { version = "5.4.0", features = ["axum_extras"] } struct-patch = "0.5" rmp-serde = "1.3" +bytes = "1" +http = "1" # Leptos 0.8.7 leptos = { version = "0.8.7", features = ["nightly"] } @@ -17,7 +19,6 @@ axum = { version = "0.8", features = ["macros"], optional = true } # SSR Dependencies (XML-RPC & SCGI) tokio = { version = "1", features = ["full"], optional = true } -bytes = { version = "1", optional = true } thiserror = { version = "2", optional = true } quick-xml = { version = "0.31", features = ["serde", "serialize"], optional = true } @@ -34,7 +35,6 @@ bcrypt = { version = "0.17", optional = true } default = [] ssr = [ "dep:tokio", - "dep:bytes", "dep:thiserror", "dep:quick-xml", "dep:leptos_axum", diff --git a/shared/src/codec.rs b/shared/src/codec.rs index 3fc68e1..73d4a64 100644 --- a/shared/src/codec.rs +++ b/shared/src/codec.rs @@ -7,8 +7,11 @@ use std::future::Future; pub struct MessagePack; -impl Encoding for MessagePack { +impl leptos::server_fn::codec::ContentType for MessagePack { const CONTENT_TYPE: &'static str = "application/msgpack"; +} + +impl Encoding for MessagePack { const METHOD: leptos::server_fn::request::Method = leptos::server_fn::request::Method::POST; } @@ -18,46 +21,15 @@ where Input: Serialize + Send, Output: Send, { - fn into_req(args: Input, path: &str) -> Result { + fn into_req(self, args: Input, path: &str) -> Result { let data = rmp_serde::to_vec(&args) .map_err(|e| ServerFnError::Serialization(e.to_string()))?; - // ClientReq is typically http::Request or similar. - // If ClientReq::new(method, path) doesn't exist, check if ClientReq is alias for Request. - // In leptos 0.8+, ClientReq::try_new(method, uri, body) is available via trait extension usually or direct impl. - // Actually, ClientReq IS http::Request in server/ssr, and gloo_net::Request in hydrate (often). - - // Let's assume ClientReq::post(path).body(...) or similar builders. - // Or if it's http::Request: - // http::Request::builder().method("POST").uri(path).header(...).body(data) - - // But ClientReq type differs between Features. - // Let's try to use `ClientReq` assuming it has `try_new` as seen in other codecs (Json). - // If that fails, I will use conditional compilation for specific types. - - // The error "expected a type, found a trait" suggests `ClientReq` handles differently. - // Let's look at `Json` codec usage pattern if possible - I can't read source. - - // Let's try constructing via builder if available. - // Or better, let's look at what `ClientReq` is. - // In `leptos_server_fn::request`, `ClientReq` is public type alias. - - // If I use `ClientReq::try_new`, I need it to be available. - // Let's try `ClientReq::new` again but verify imports. - // Maybe I need to import `http::Method`? - - // Let's try using `http::Request` explicitly if possible, or just construct it. - // If `ClientReq` is `http::Request`, `ClientReq::builder()` works. - - let req = ClientReq::builder() - .method("POST") - .uri(path) - .header("Content-Type", "application/msgpack") - .header("Accept", "application/msgpack") - .body(bytes::Bytes::from(data)) - .map_err(|e| ServerFnError::Request(e.to_string()))?; - - Ok(req) + ClientReq::try_new( + leptos::server_fn::request::Method::POST, + path, + leptos::server_fn::request::Payload::Binary(bytes::Bytes::from(data)) + ) } } @@ -102,10 +74,10 @@ where let data = rmp_serde::to_vec(&res) .map_err(|e| ServerFnError::Serialization(e.to_string()))?; - let mut res = Res::new(200); - res.try_set_header("Content-Type", "application/msgpack")?; - res.try_set_body(bytes::Bytes::from(data))?; - Ok(res) + Res::try_from_bytes( + bytes::Bytes::from(data), + "application/msgpack" + ) } } } diff --git a/shared/src/server_fns/auth.rs b/shared/src/server_fns/auth.rs index 0156f55..9850fe8 100644 --- a/shared/src/server_fns/auth.rs +++ b/shared/src/server_fns/auth.rs @@ -20,7 +20,7 @@ pub struct SetupStatus { pub completed: bool, } -#[server(GetSetupStatus, "/api/server_fns/GetSetupStatus", encoding = "MessagePack")] +#[server(GetSetupStatus, "/api/server_fns/GetSetupStatus", encoding = MessagePack)] pub async fn get_setup_status() -> Result { use crate::DbContext; @@ -33,7 +33,7 @@ pub async fn get_setup_status() -> Result { }) } -#[server(Setup, "/api/server_fns/Setup", encoding = "MessagePack")] +#[server(Setup, "/api/server_fns/Setup", encoding = MessagePack)] pub async fn setup(username: String, password: String) -> Result<(), ServerFnError> { use crate::DbContext; @@ -55,7 +55,7 @@ pub async fn setup(username: String, password: String) -> Result<(), ServerFnErr Ok(()) } -#[server(Login, "/api/server_fns/Login", encoding = "MessagePack")] +#[server(Login, "/api/server_fns/Login", encoding = MessagePack)] pub async fn login(username: String, password: String) -> Result { use crate::DbContext; use leptos_axum::ResponseOptions; @@ -111,7 +111,7 @@ pub async fn login(username: String, password: String) -> Result Result<(), ServerFnError> { use leptos_axum::ResponseOptions; use cookie::{Cookie, SameSite}; @@ -132,7 +132,7 @@ pub async fn logout() -> Result<(), ServerFnError> { Ok(()) } -#[server(GetUser, "/api/server_fns/GetUser", encoding = "MessagePack")] +#[server(GetUser, "/api/server_fns/GetUser", encoding = MessagePack)] pub async fn get_user() -> Result, ServerFnError> { use axum::http::HeaderMap; use leptos_axum::extract;