From 219af51526ffb758fbf99a4113099639bb56e398 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 3 Apr 2023 17:39:09 -0500 Subject: [PATCH] fix cargo check --- docs/guide/examples/hydration.rs | 34 +++++ docs/guide/examples/server.rs | 132 ------------------ docs/guide/examples/server_basic.rs | 30 ++++ docs/guide/examples/server_function.rs | 58 ++++++++ .../guide/src/en/getting_started/fullstack.md | 6 +- packages/router/src/components/router.rs | 7 +- packages/server/Cargo.toml | 2 +- packages/server/server-macro/Cargo.toml | 2 +- packages/server/src/lib.rs | 4 +- packages/server/src/render.rs | 3 +- 10 files changed, 136 insertions(+), 142 deletions(-) create mode 100644 docs/guide/examples/hydration.rs delete mode 100644 docs/guide/examples/server.rs create mode 100644 docs/guide/examples/server_basic.rs create mode 100644 docs/guide/examples/server_function.rs diff --git a/docs/guide/examples/hydration.rs b/docs/guide/examples/hydration.rs new file mode 100644 index 000000000..f3c9bca8f --- /dev/null +++ b/docs/guide/examples/hydration.rs @@ -0,0 +1,34 @@ +#![allow(non_snake_case, unused)] +use dioxus::prelude::*; + +fn main() { + #[cfg(feature = "web")] + dioxus_web::launch_cfg(app, dioxus_web::Config::new().hydrate(true)); + #[cfg(feature = "ssr")] + { + use dioxus_server::prelude::*; + tokio::runtime::Runtime::new() + .unwrap() + .block_on(async move { + let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 8080)); + axum::Server::bind(&addr) + .serve( + axum::Router::new() + .serve_dioxus_application("", ServeConfigBuilder::new(app, ())) + .into_make_service(), + ) + .await + .unwrap(); + }); + } +} + +fn app(cx: Scope) -> Element { + let mut count = use_state(cx, || 0); + + cx.render(rsx! { + h1 { "High-Five counter: {count}" } + button { onclick: move |_| count += 1, "Up high!" } + button { onclick: move |_| count -= 1, "Down low!" } + }) +} diff --git a/docs/guide/examples/server.rs b/docs/guide/examples/server.rs deleted file mode 100644 index 80e74a919..000000000 --- a/docs/guide/examples/server.rs +++ /dev/null @@ -1,132 +0,0 @@ -mod basic { - // ANCHOR: basic - #![allow(non_snake_case)] - use dioxus::prelude::*; - use dioxus_server::prelude::*; - - #[tokio::main] - async fn main() { - let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 8080)); - axum::Server::bind(&addr) - .serve( - axum::Router::new() - .serve_dioxus_application("", ServeConfigBuilder::new(app, ())) - .into_make_service(), - ) - .await - .unwrap(); - } - - fn app(cx: Scope) -> Element { - let mut count = use_state(cx, || 0); - - cx.render(rsx! { - h1 { "High-Five counter: {count}" } - button { onclick: move |_| count += 1, "Up high!" } - button { onclick: move |_| count -= 1, "Down low!" } - }) - } - // ANCHOR_END: basic -} - -mod hydration { - // ANCHOR: hydration - #![allow(non_snake_case)] - use dioxus::prelude::*; - use dioxus_server::prelude::*; - - fn main() { - #[cfg(feature = "web")] - dioxus_web::launch_cfg(app, dioxus_web::Config::new().hydrate(true)); - #[cfg(feature = "ssr")] - { - tokio::runtime::Runtime::new() - .unwrap() - .block_on(async move { - let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 8080)); - axum::Server::bind(&addr) - .serve( - axum::Router::new() - .serve_dioxus_application("", ServeConfigBuilder::new(app, ())) - .into_make_service(), - ) - .await - .unwrap(); - }); - } - } - - fn app(cx: Scope) -> Element { - let mut count = use_state(cx, || 0); - - cx.render(rsx! { - h1 { "High-Five counter: {count}" } - button { onclick: move |_| count += 1, "Up high!" } - button { onclick: move |_| count -= 1, "Down low!" } - }) - } - // ANCHOR_END: hydration -} - -mod server_function { - // ANCHOR: server_function - #![allow(non_snake_case)] - use dioxus::prelude::*; - use dioxus_server::prelude::*; - - fn main() { - #[cfg(feature = "web")] - dioxus_web::launch_cfg(app, dioxus_web::Config::new().hydrate(true)); - #[cfg(feature = "ssr")] - { - // Register the server function before starting the server - DoubleServer::register().unwrap(); - tokio::runtime::Runtime::new() - .unwrap() - .block_on(async move { - let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 8080)); - axum::Server::bind(&addr) - .serve( - axum::Router::new() - // Serve Dioxus application automatically recognizes server functions and adds them to the API - .serve_dioxus_application("", ServeConfigBuilder::new(app, ())) - .into_make_service(), - ) - .await - .unwrap(); - }); - } - } - - fn app(cx: Scope) -> Element { - let mut count = use_state(cx, || 0); - - cx.render(rsx! { - h1 { "High-Five counter: {count}" } - button { onclick: move |_| count += 1, "Up high!" } - button { onclick: move |_| count -= 1, "Down low!" } - button { - onclick: move |_| { - to_owned![count]; - async move { - // Call the server function just like a local async function - if let Ok(new_count) = double_server(*count.current()).await { - count.set(new_count); - } - } - }, - "Double" - } - }) - } - - #[server(DoubleServer)] - async fn double_server(number: u32) -> Result { - // Perform some expensive computation or access a database on the server - tokio::time::sleep(std::time::Duration::from_secs(1)).await; - let result = number * 2; - println!("server calculated {result}"); - Ok(result) - } - // ANCHOR_END: server_function -} diff --git a/docs/guide/examples/server_basic.rs b/docs/guide/examples/server_basic.rs new file mode 100644 index 000000000..bd6cf78e6 --- /dev/null +++ b/docs/guide/examples/server_basic.rs @@ -0,0 +1,30 @@ +#![allow(non_snake_case, unused)] +use dioxus::prelude::*; + +#[tokio::main] +async fn main() { + #[cfg(feature = "ssr")] + { + use dioxus_server::prelude::*; + + let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 8080)); + axum::Server::bind(&addr) + .serve( + axum::Router::new() + .serve_dioxus_application("", ServeConfigBuilder::new(app, ())) + .into_make_service(), + ) + .await + .unwrap(); + } +} + +fn app(cx: Scope) -> Element { + let mut count = use_state(cx, || 0); + + cx.render(rsx! { + h1 { "High-Five counter: {count}" } + button { onclick: move |_| count += 1, "Up high!" } + button { onclick: move |_| count -= 1, "Down low!" } + }) +} diff --git a/docs/guide/examples/server_function.rs b/docs/guide/examples/server_function.rs new file mode 100644 index 000000000..106c54c3f --- /dev/null +++ b/docs/guide/examples/server_function.rs @@ -0,0 +1,58 @@ +#![allow(non_snake_case, unused)] +use dioxus::prelude::*; +use dioxus_server::prelude::*; + +fn main() { + #[cfg(feature = "web")] + dioxus_web::launch_cfg(app, dioxus_web::Config::new().hydrate(true)); + #[cfg(feature = "ssr")] + { + // Register the server function before starting the server + DoubleServer::register().unwrap(); + tokio::runtime::Runtime::new() + .unwrap() + .block_on(async move { + let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 8080)); + axum::Server::bind(&addr) + .serve( + axum::Router::new() + // Serve Dioxus application automatically recognizes server functions and adds them to the API + .serve_dioxus_application("", ServeConfigBuilder::new(app, ())) + .into_make_service(), + ) + .await + .unwrap(); + }); + } +} + +fn app(cx: Scope) -> Element { + let mut count = use_state(cx, || 0); + + cx.render(rsx! { + h1 { "High-Five counter: {count}" } + button { onclick: move |_| count += 1, "Up high!" } + button { onclick: move |_| count -= 1, "Down low!" } + button { + onclick: move |_| { + to_owned![count]; + async move { + // Call the server function just like a local async function + if let Ok(new_count) = double_server(*count.current()).await { + count.set(new_count); + } + } + }, + "Double" + } + }) +} + +#[server(DoubleServer)] +async fn double_server(number: u32) -> Result { + // Perform some expensive computation or access a database on the server + tokio::time::sleep(std::time::Duration::from_secs(1)).await; + let result = number * 2; + println!("server calculated {result}"); + Ok(result) +} diff --git a/docs/guide/src/en/getting_started/fullstack.md b/docs/guide/src/en/getting_started/fullstack.md index b132de319..f01d8dd30 100644 --- a/docs/guide/src/en/getting_started/fullstack.md +++ b/docs/guide/src/en/getting_started/fullstack.md @@ -44,7 +44,7 @@ tokio = { version = "*", features = ["full"] } Now, set up your Axum app to serve the Dioxus app. ```rust -{{#include ../../../examples/server.rs:basic}} +{{#include ../../../examples/server_basic.rs}} ``` Now, run your app with `cargo run` and open `http://localhost:8080` in your browser. You should see a server-side rendered page with a counter. @@ -77,7 +77,7 @@ web = ["dioxus-web"] Next, we need to modify our `main.rs` to use either hydrate on the client or render on the server depending on the active features. ```rust -{{#include ../../../examples/server.rs:hydration}} +{{#include ../../../examples/hydration.rs}} ``` Now, build your client-side bundle with `dioxus build --features web` and run your server with `cargo run --features ssr`. You should see the same page as before, but now you can interact with the buttons! @@ -105,7 +105,7 @@ cargo add serde Next, add the server function to your `main.rs`: ```rust -{{#include ../../../examples/server.rs:server_function}} +{{#include ../../../examples/server_function.rs}} ``` Now, build your client-side bundle with `dioxus build --features web` and run your server with `cargo run --features ssr`. You should see a new button that multiplies the count by 2. diff --git a/packages/router/src/components/router.rs b/packages/router/src/components/router.rs index b027386c5..8d5365c35 100644 --- a/packages/router/src/components/router.rs +++ b/packages/router/src/components/router.rs @@ -29,8 +29,9 @@ pub struct RouterProps<'a> { pub active_class: Option<&'a str>, /// Set the initial url. - #[props(!optional, into)] - pub initial_url: Option, + // This is Option> because we want to be able to either omit the prop or pass in Option + #[props(into)] + pub initial_url: Option>, } /// A component that conditionally renders children based on the current location of the app. @@ -46,7 +47,7 @@ pub fn Router<'a>(cx: Scope<'a, RouterProps<'a>>) -> Element { RouterCfg { base_url: cx.props.base_url.map(|s| s.to_string()), active_class: cx.props.active_class.map(|s| s.to_string()), - initial_url: cx.props.initial_url.clone(), + initial_url: cx.props.initial_url.clone().flatten(), }, )) }); diff --git a/packages/server/Cargo.toml b/packages/server/Cargo.toml index 8709cb57d..18633e97a 100644 --- a/packages/server/Cargo.toml +++ b/packages/server/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["dom", "ui", "gui", "react", "ssr", "fullstack"] [dependencies] # server functions server_fn = { git = "https://github.com/leptos-rs/leptos", rev = "a9e6590b5e7f1c0b01da7db7b86719cb18a4aaa1", features = ["stable"] } -server_macro = { path = "server-macro" } +dioxus_server_macro = { path = "server-macro" } # warp warp = { version = "0.3.3", optional = true } diff --git a/packages/server/server-macro/Cargo.toml b/packages/server/server-macro/Cargo.toml index d03c5274c..45b0ec3c6 100644 --- a/packages/server/server-macro/Cargo.toml +++ b/packages/server/server-macro/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "server_macro" +name = "dioxus_server_macro" version = "0.1.0" edition = "2021" diff --git a/packages/server/src/lib.rs b/packages/server/src/lib.rs index c61b26429..df2735cf4 100644 --- a/packages/server/src/lib.rs +++ b/packages/server/src/lib.rs @@ -24,11 +24,13 @@ pub mod prelude { #[cfg(feature = "warp")] pub use crate::adapters::warp_adapter::*; #[cfg(feature = "ssr")] + pub use crate::render::SSRState; + #[cfg(feature = "ssr")] pub use crate::serve_config::{ServeConfig, ServeConfigBuilder}; pub use crate::server_context::DioxusServerContext; pub use crate::server_fn::ServerFn; #[cfg(feature = "ssr")] pub use crate::server_fn::ServerFnTraitObj; + pub use dioxus_server_macro::*; pub use server_fn::{self, ServerFn as _, ServerFnError}; - pub use server_macro::*; } diff --git a/packages/server/src/render.rs b/packages/server/src/render.rs index 22e751ea8..8328be317 100644 --- a/packages/server/src/render.rs +++ b/packages/server/src/render.rs @@ -9,7 +9,7 @@ use crate::prelude::ServeConfig; /// State used in server side rendering. This utilizes a pool of [`dioxus_ssr::Renderer`]s to cache static templates between renders. #[derive(Clone)] -pub(crate) struct SSRState { +pub struct SSRState { // We keep a pool of renderers to avoid re-creating them on every request. They are boxed to make them very cheap to move renderers: Arc>, } @@ -23,6 +23,7 @@ impl Default for SSRState { } impl SSRState { + /// Render the application to HTML. pub fn render(&self, cfg: &ServeConfig

) -> String { let ServeConfig { app, props, index, ..