diff --git a/examples/server_fns_axum/Cargo.toml b/examples/server_fns_axum/Cargo.toml index fb1d7b762..dfd06f382 100644 --- a/examples/server_fns_axum/Cargo.toml +++ b/examples/server_fns_axum/Cargo.toml @@ -28,6 +28,7 @@ wasm-bindgen = "0.2" serde_toml = "0.0.1" toml = "0.8.8" web-sys = { version = "0.3.67", features = ["FileList", "File"] } +strum = { version = "0.25.0", features = ["strum_macros", "derive"] } [features] hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"] diff --git a/examples/server_fns_axum/src/app.rs b/examples/server_fns_axum/src/app.rs index dd5edb0fb..b37526b80 100644 --- a/examples/server_fns_axum/src/app.rs +++ b/examples/server_fns_axum/src/app.rs @@ -9,6 +9,7 @@ use std::sync::{ atomic::{AtomicU8, Ordering}, Mutex, }; +use strum::{Display, EnumString}; use wasm_bindgen::JsCast; use web_sys::{FormData, HtmlFormElement, SubmitEvent}; @@ -39,6 +40,8 @@ pub fn HomePage() -> impl IntoView { +

"Custom Error Types"

+

"Alternative Encodings"

@@ -368,3 +371,66 @@ pub fn FileUpload() -> impl IntoView {

} } + +/// The `ServerFnError` type is generic over a custom error type, which defaults to `NoCustomError` +/// for backwards compatibility and to support the most common use case. +/// +/// A custom error type should implement `FromStr` and `Display`, which allows it to be converted +/// into and from a string easily to be sent over the network. It does *not* need to implement +/// `Serialize` and `Deserialize`, although these can be used to generate the `FromStr`/`Display` +/// 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> { + if text.len() < 5 { + Err(InvalidArgument::TooShort.into()) + } else if text.len() > 15 { + Err(InvalidArgument::TooLong.into()) + } else if text.is_ascii() { + Ok(text.to_ascii_uppercase()) + } else { + Err(InvalidArgument::NotAscii.into()) + } +} + +// The EnumString and Display derive macros are provided by strum +#[derive(Debug, Clone, EnumString, Display)] +pub enum InvalidArgument { + TooShort, + TooLong, + NotAscii, +} + +#[component] +pub fn CustomErrorTypes() -> impl IntoView { + let input_ref = NodeRef::::new(); + let (result, set_result) = create_signal(None); + + view! { +

Using custom error types

+

+ "Server functions can use a custom error type that is preserved across the network boundary." +

+

+ "Try typing a message that is between 5 and 15 characters of ASCII text below. Then try breaking \ + the rules!" +

+ + +

+ {move || format!("{:?}", result.get())} +

+ } +}