From 861d70280aed348e58fdb7c8ea14143a8132333e Mon Sep 17 00:00:00 2001 From: Ryo Hirayama Date: Fri, 22 Nov 2024 13:33:19 +0900 Subject: [PATCH] Redo fd68c76 example fix --- examples/server_fns_axum/src/app.rs | 52 +++++++++++++++++------------ 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/examples/server_fns_axum/src/app.rs b/examples/server_fns_axum/src/app.rs index 75f5c8fe79..e64917fd60 100644 --- a/examples/server_fns_axum/src/app.rs +++ b/examples/server_fns_axum/src/app.rs @@ -9,6 +9,7 @@ use server_fn::{ MultipartFormData, Postcard, Rkyv, SerdeLite, StreamingText, TextStream, }, + error::{FromServerFnError, ServerFnErrorErr}, request::{browser::BrowserRequest, ClientReq, Req}, response::{browser::BrowserResponse, ClientRes, Res}, }; @@ -18,7 +19,7 @@ use std::sync::{ atomic::{AtomicU8, Ordering}, Mutex, }; -use strum::{Display, EnumString}; +use strum::Display; use wasm_bindgen::JsCast; use web_sys::{FormData, HtmlFormElement, SubmitEvent}; @@ -652,9 +653,7 @@ pub fn FileWatcher() -> impl IntoView { /// implementations if you'd like. However, it's much lighter weight to use something like `strum` /// simply to generate those trait implementations. #[server] -pub async fn ascii_uppercase( - text: String, -) -> Result> { +pub async fn ascii_uppercase(text: String) -> Result { if text.len() < 5 { Err(InvalidArgument::TooShort.into()) } else if text.len() > 15 { @@ -667,11 +666,18 @@ pub async fn ascii_uppercase( } // The EnumString and Display derive macros are provided by strum -#[derive(Debug, Clone, EnumString, Display)] +#[derive(Debug, Clone, Display, Serialize, Deserialize)] pub enum InvalidArgument { TooShort, TooLong, NotAscii, + ServerFnError(ServerFnErrorErr), +} + +impl From for InvalidArgument { + fn from(value: ServerFnErrorErr) -> Self { + InvalidArgument::ServerFnError(value) + } } #[component] @@ -726,14 +732,11 @@ impl IntoReq for TomlEncoded where Request: ClientReq, T: Serialize, + Err: FromServerFnError, { - fn into_req( - self, - path: &str, - accepts: &str, - ) -> Result> { + fn into_req(self, path: &str, accepts: &str) -> Result { let data = toml::to_string(&self.0) - .map_err(|e| ServerFnError::Serialization(e.to_string()))?; + .map_err(|e| ServerFnErrorErr::Serialization(e.to_string()))?; Request::try_new_post(path, Toml::CONTENT_TYPE, accepts, data) } } @@ -742,12 +745,13 @@ impl FromReq for TomlEncoded where Request: Req + Send, T: DeserializeOwned, + Err: FromServerFnError, { - async fn from_req(req: Request) -> Result> { + async fn from_req(req: Request) -> Result { let string_data = req.try_into_string().await?; toml::from_str::(&string_data) .map(TomlEncoded) - .map_err(|e| ServerFnError::Args(e.to_string())) + .map_err(|e| ServerFnErrorErr::Args(e.to_string()).into()) } } @@ -755,10 +759,11 @@ impl IntoRes for TomlEncoded where Response: Res, T: Serialize + Send, + Err: FromServerFnError, { - async fn into_res(self) -> Result> { + async fn into_res(self) -> Result { let data = toml::to_string(&self.0) - .map_err(|e| ServerFnError::Serialization(e.to_string()))?; + .map_err(|e| ServerFnErrorErr::Serialization(e.to_string()))?; Response::try_from_string(Toml::CONTENT_TYPE, data) } } @@ -767,12 +772,13 @@ impl FromRes for TomlEncoded where Response: ClientRes + Send, T: DeserializeOwned, + Err: FromServerFnError, { - async fn from_res(res: Response) -> Result> { + async fn from_res(res: Response) -> Result { let data = res.try_into_string().await?; - toml::from_str(&data) - .map(TomlEncoded) - .map_err(|e| ServerFnError::Deserialization(e.to_string())) + toml::from_str(&data).map(TomlEncoded).map_err(|e| { + ServerFnErrorErr::Deserialization(e.to_string()).into() + }) } } @@ -835,7 +841,10 @@ pub fn CustomClientExample() -> impl IntoView { pub struct CustomClient; // Implement the `Client` trait for it. - impl Client for CustomClient { + impl Client for CustomClient + where + E: FromServerFnError, + { // BrowserRequest and BrowserResponse are the defaults used by other server functions. // They are wrappers for the underlying Web Fetch API types. type Request = BrowserRequest; @@ -844,8 +853,7 @@ pub fn CustomClientExample() -> impl IntoView { // Our custom `send()` implementation does all the work. fn send( req: Self::Request, - ) -> impl Future>> - + Send { + ) -> impl Future> + Send { // BrowserRequest derefs to the underlying Request type from gloo-net, // so we can get access to the headers here let headers = req.headers();