From b4d17abfc1cd7f4010ee5ccd81becd8bbec940f0 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Fri, 9 Feb 2024 12:15:59 -0600 Subject: [PATCH] document all features --- .github/workflows/docs.yml | 8 +- packages/cli/src/server/mod.rs | 6 - packages/fullstack/Cargo.toml | 3 +- .../examples/axum-desktop/src/client.rs | 4 +- .../examples/axum-desktop/src/server.rs | 2 +- .../examples/static-hydrated/src/main.rs | 2 +- .../fullstack/src/adapters/axum_adapter.rs | 6 +- packages/fullstack/src/adapters/mod.rs | 4 +- .../fullstack/src/adapters/salvo_adapter.rs | 19 +- .../fullstack/src/adapters/warp_adapter.rs | 10 +- packages/fullstack/src/config.rs | 8 + packages/fullstack/src/lib.rs | 62 ++++++- packages/fullstack/src/server_context.rs | 1 + packages/fullstack/src/server_fn.rs | 22 ++- packages/hooks/src/lib.rs | 1 - packages/liveview/src/launch.rs | 4 +- packages/router/Cargo.toml | 1 - packages/router/src/components/router.rs | 78 -------- packages/router/src/history/web.rs | 168 ------------------ packages/router/src/history/web_history.rs | 42 ----- packages/router/src/router_cfg.rs | 33 ---- 21 files changed, 110 insertions(+), 374 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 61c4140df..7a365dceb 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -6,7 +6,6 @@ on: jobs: deploy: - if: github.event.pull_request.draft == false name: Build & Deploy runs-on: ubuntu-latest permissions: @@ -16,21 +15,18 @@ jobs: - uses: actions/checkout@v4 - run: sudo apt-get update - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev libxdo-dev - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@nightly - uses: Swatinem/rust-cache@v2 with: cache-all-crates: "true" save-if: ${{ github.ref == 'refs/heads/master' }} - uses: ilammy/setup-nasm@v1 - - name: cargo doc - run: cargo doc --no-deps --workspace --features dioxus-fullstack/doc + run: cargo doc --no-deps --workspace --all-features - name: Deploy uses: JamesIves/github-pages-deploy-action@v4.5.0 with: branch: gh-pages-docs folder: target/doc - #target-folder: docs - #repository-name: \ No newline at end of file diff --git a/packages/cli/src/server/mod.rs b/packages/cli/src/server/mod.rs index bd1cafdd8..3f9510839 100644 --- a/packages/cli/src/server/mod.rs +++ b/packages/cli/src/server/mod.rs @@ -112,12 +112,6 @@ async fn setup_file_watcher Result + Send + 'static>( }, web_info.clone(), ); - - #[cfg(feature = "plugin")] - let _ = PluginManager::on_serve_rebuild( - chrono::Local::now().timestamp(), - e.paths, - ); } Err(e) => { last_update_time = chrono::Local::now().timestamp(); diff --git a/packages/fullstack/Cargo.toml b/packages/fullstack/Cargo.toml index c9a57c8f8..63fde221c 100644 --- a/packages/fullstack/Cargo.toml +++ b/packages/fullstack/Cargo.toml @@ -81,4 +81,5 @@ salvo = ["dep:salvo", "server", "http-body-util"] server = ["server_fn/ssr", "dioxus_server_macro/server", "tokio", "tokio-util", "tokio-stream", "dioxus-ssr", "dioxus-ssr/incremental", "tower", "hyper", "http", "tower-layer", "anymap", "tracing-futures", "pin-project", "thiserror", "dioxus-cli-config"] default-tls = ["server_fn/default-tls"] rustls = ["server_fn/rustls"] -doc = ["thiserror"] +# This feature enables some nightly flags that make it more clear what structs/methods are available in each feature +nightly-doc = [] diff --git a/packages/fullstack/examples/axum-desktop/src/client.rs b/packages/fullstack/examples/axum-desktop/src/client.rs index da11fda25..247f2e8f2 100644 --- a/packages/fullstack/examples/axum-desktop/src/client.rs +++ b/packages/fullstack/examples/axum-desktop/src/client.rs @@ -4,10 +4,10 @@ // ``` use axum_desktop::*; -use dioxus_fullstack::prelude::server_fn::set_server_url; fn main() { // Set the url of the server where server functions are hosted. - set_server_url("http://127.0.0.1:8080"); + #[cfg(not(feature = "server"))] + dioxus::fullstack::prelude::server_fn::set_server_url("http://127.0.0.1:8080"); dioxus::desktop::launch(app) } diff --git a/packages/fullstack/examples/axum-desktop/src/server.rs b/packages/fullstack/examples/axum-desktop/src/server.rs index 0781db5fb..759d5799b 100644 --- a/packages/fullstack/examples/axum-desktop/src/server.rs +++ b/packages/fullstack/examples/axum-desktop/src/server.rs @@ -4,7 +4,7 @@ // ``` use axum_desktop::*; -use dioxus_fullstack::prelude::*; +use dioxus::prelude::*; #[tokio::main] async fn main() { diff --git a/packages/fullstack/examples/static-hydrated/src/main.rs b/packages/fullstack/examples/static-hydrated/src/main.rs index 72bd6894b..69c81b40e 100644 --- a/packages/fullstack/examples/static-hydrated/src/main.rs +++ b/packages/fullstack/examples/static-hydrated/src/main.rs @@ -27,7 +27,7 @@ async fn main() { } // Hydrate the page -#[cfg(feature = "web")] +#[cfg(all(feature = "web", not(feature = "server")))] fn main() { dioxus_web::launch_with_props( dioxus_fullstack::router::RouteWithCfg::, diff --git a/packages/fullstack/src/adapters/axum_adapter.rs b/packages/fullstack/src/adapters/axum_adapter.rs index 731b3f13e..d73edeb88 100644 --- a/packages/fullstack/src/adapters/axum_adapter.rs +++ b/packages/fullstack/src/adapters/axum_adapter.rs @@ -332,7 +332,7 @@ where } fn connect_hot_reload(self) -> Self { - #[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))] + #[cfg(all(debug_assertions, feature = "hot-reload"))] { self.nest( "/_dioxus", @@ -354,7 +354,7 @@ where .route("/hot_reload", get(hot_reload_handler)), ) } - #[cfg(not(all(debug_assertions, feature = "hot-reload", feature = "server")))] + #[cfg(not(all(debug_assertions, feature = "hot-reload")))] { self } @@ -476,7 +476,7 @@ fn report_err(e: E) -> Response { } /// A handler for Dioxus web hot reload websocket. This will send the updated static parts of the RSX to the client when they change. -#[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))] +#[cfg(all(debug_assertions, feature = "hot-reload"))] pub async fn hot_reload_handler(ws: axum::extract::WebSocketUpgrade) -> impl IntoResponse { use axum::extract::ws::Message; use futures_util::StreamExt; diff --git a/packages/fullstack/src/adapters/mod.rs b/packages/fullstack/src/adapters/mod.rs index d368b9c73..61f24bf3c 100644 --- a/packages/fullstack/src/adapters/mod.rs +++ b/packages/fullstack/src/adapters/mod.rs @@ -12,8 +12,8 @@ #[cfg(feature = "axum")] pub mod axum_adapter; -#[cfg(feature = "salvo")] -pub mod salvo_adapter; +// #[cfg(feature = "salvo")] +// pub mod salvo_adapter; #[cfg(feature = "warp")] pub mod warp_adapter; diff --git a/packages/fullstack/src/adapters/salvo_adapter.rs b/packages/fullstack/src/adapters/salvo_adapter.rs index 4c41fc4a4..a30097c9a 100644 --- a/packages/fullstack/src/adapters/salvo_adapter.rs +++ b/packages/fullstack/src/adapters/salvo_adapter.rs @@ -291,17 +291,20 @@ impl DioxusRouterExt for Router { ) -> Self { let cfg = cfg.into(); - self.serve_static_assets(cfg.assets_path) + self.serve_static_assets(cfg.assets_path.clone()) .connect_hot_reload() .register_server_fns(server_fn_path) - .push(Router::with_path("/<**any_path>").get(SSRHandler { cfg })) + .push(Router::with_path("/<**any_path>").get(SSRHandler { + config: cfg, + virtual_dom: virtual_dom_factory, + })) } fn connect_hot_reload(self) -> Self { let mut _dioxus_router = Router::with_path("_dioxus"); _dioxus_router = _dioxus_router.push(Router::with_path("hot_reload").handle(HotReloadHandler)); - #[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))] + #[cfg(all(debug_assertions, feature = "hot-reload"))] { _dioxus_router = _dioxus_router.push(Router::with_path("disconnect").handle(ignore_ws)); } @@ -485,11 +488,11 @@ fn handle_error(error: impl Error + Send + Sync, res: &mut Response) { } /// A handler for Dioxus web hot reload websocket. This will send the updated static parts of the RSX to the client when they change. -#[cfg(not(all(debug_assertions, feature = "hot-reload", feature = "server")))] +#[cfg(not(all(debug_assertions, feature = "hot-reload")))] #[derive(Default)] pub struct HotReloadHandler; -#[cfg(not(all(debug_assertions, feature = "hot-reload", feature = "server")))] +#[cfg(not(all(debug_assertions, feature = "hot-reload")))] #[handler] impl HotReloadHandler { async fn handle( @@ -503,11 +506,11 @@ impl HotReloadHandler { } /// A handler for Dioxus web hot reload websocket. This will send the updated static parts of the RSX to the client when they change. -#[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))] +#[cfg(all(debug_assertions, feature = "hot-reload"))] #[derive(Default)] pub struct HotReloadHandler; -#[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))] +#[cfg(all(debug_assertions, feature = "hot-reload"))] #[handler] impl HotReloadHandler { async fn handle( @@ -561,7 +564,7 @@ impl HotReloadHandler { } } -#[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))] +#[cfg(all(debug_assertions, feature = "hot-reload"))] #[handler] async fn ignore_ws(req: &mut Request, res: &mut Response) -> Result<(), salvo::http::StatusError> { use salvo::websocket::WebSocketUpgrade; diff --git a/packages/fullstack/src/adapters/warp_adapter.rs b/packages/fullstack/src/adapters/warp_adapter.rs index 462fce1f6..711980ec8 100644 --- a/packages/fullstack/src/adapters/warp_adapter.rs +++ b/packages/fullstack/src/adapters/warp_adapter.rs @@ -187,7 +187,7 @@ pub fn serve_dioxus_application( ) -> BoxedFilter<(impl Reply,)> { let cfg = cfg.into(); // Serve the dist folder and the index.html file - let serve_dir = warp::fs::dir(cfg.assets_path); + let serve_dir = warp::fs::dir(cfg.assets_path.clone()); let virtual_dom_factory = Arc::new(virtual_dom_factory) as Arc VirtualDom + Send + Sync + 'static>; @@ -332,13 +332,13 @@ impl warp::reject::Reject for RecieveFailed {} /// ``` pub fn connect_hot_reload() -> impl Filter + Clone { - #[cfg(not(all(debug_assertions, feature = "hot-reload", feature = "server")))] + #[cfg(not(all(debug_assertions, feature = "hot-reload")))] { warp::path!("_dioxus" / "hot_reload") .map(warp::reply) .map(|reply| warp::reply::with_status(reply, warp::http::StatusCode::NOT_FOUND)) } - #[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))] + #[cfg(all(debug_assertions, feature = "hot-reload"))] { use crate::hot_reload::HotReloadState; use futures_util::sink::SinkExt; @@ -349,7 +349,7 @@ pub fn connect_hot_reload() -> impl Filter impl Filter); impl Drop for DisconnectOnDrop { diff --git a/packages/fullstack/src/config.rs b/packages/fullstack/src/config.rs index 765108e5f..f4416b8df 100644 --- a/packages/fullstack/src/config.rs +++ b/packages/fullstack/src/config.rs @@ -53,6 +53,7 @@ impl Config { /// Set the address to serve the app on. #[cfg(feature = "server")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] pub fn addr(self, addr: impl Into) -> Self { let addr = addr.into(); Self { addr, ..self } @@ -60,6 +61,7 @@ impl Config { /// Set the route to the server functions. #[cfg(feature = "server")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] pub fn server_fn_route(self, server_fn_route: &'static str) -> Self { Self { server_fn_route, @@ -69,6 +71,7 @@ impl Config { /// Set the incremental renderer config. #[cfg(feature = "server")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] pub fn incremental(self, cfg: IncrementalRendererConfig) -> Self { Self { server_cfg: self.server_cfg.incremental(cfg), @@ -78,18 +81,21 @@ impl Config { /// Set the server config. #[cfg(feature = "server")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] pub fn server_cfg(self, server_cfg: ServeConfigBuilder) -> Self { Self { server_cfg, ..self } } /// Set the web config. #[cfg(feature = "web")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "web")))] pub fn web_cfg(self, web_cfg: dioxus_web::Config) -> Self { Self { web_cfg, ..self } } /// Set the desktop config. #[cfg(feature = "desktop")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "desktop")))] pub fn desktop_cfg(self, desktop_cfg: dioxus_desktop::Config) -> Self { Self { desktop_cfg, @@ -99,11 +105,13 @@ impl Config { /// Set the mobile config. #[cfg(feature = "mobile")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "mobile")))] pub fn mobile_cfg(self, mobile_cfg: dioxus_mobile::Config) -> Self { Self { mobile_cfg, ..self } } #[cfg(feature = "server")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] /// Launch a server application pub async fn launch_server( self, diff --git a/packages/fullstack/src/lib.rs b/packages/fullstack/src/lib.rs index b04a3cbc9..270cbc801 100644 --- a/packages/fullstack/src/lib.rs +++ b/packages/fullstack/src/lib.rs @@ -2,6 +2,7 @@ #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")] #![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")] #![deny(missing_docs)] +#![cfg_attr(any(docsrs, feature = "nightly-doc"), feature(doc_cfg))] pub use once_cell; @@ -9,8 +10,20 @@ mod html_storage; #[cfg(feature = "server")] mod adapters; +// Splitting up the glob export lets us document features required for each adapter +#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "axum")))] +#[cfg(feature = "axum")] +pub use adapters::axum_adapter; +// TODO: Compilation seems to be broken with the salvo feature enabled. Fix and add more features to checks in CI +// #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "salvo")))] +// #[cfg(feature = "salvo")] +// pub use adapters::salvo_adapter; +#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "warp")))] +#[cfg(feature = "warp")] +pub use adapters::warp_adapter; +#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] #[cfg(feature = "server")] -pub use adapters::*; +pub use adapters::{server_fn_service, ServerFnHandler}; mod config; mod hooks; #[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))] @@ -30,35 +43,57 @@ mod server_fn; /// A prelude of commonly used items in dioxus-fullstack. pub mod prelude { #[cfg(feature = "axum")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "axum")))] pub use crate::adapters::axum_adapter::*; - #[cfg(feature = "salvo")] - pub use crate::adapters::salvo_adapter::*; + // #[cfg(feature = "salvo")] + // #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "salvo")))] + // pub use crate::adapters::salvo_adapter::*; #[cfg(feature = "warp")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "warp")))] pub use crate::adapters::warp_adapter::*; use crate::hooks; #[cfg(not(feature = "server"))] + #[cfg_attr( + any(docsrs, feature = "nightly-doc"), + doc(cfg(not(feature = "server"))) + )] pub use crate::html_storage::deserialize::get_root_props_from_document; #[cfg(feature = "server")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] pub use crate::layer::{Layer, Service}; #[cfg(all(feature = "server", feature = "router"))] + #[cfg_attr( + any(docsrs, feature = "nightly-doc"), + doc(cfg(all(feature = "server", feature = "router"))) + )] pub use crate::render::pre_cache_static_routes_with_props; #[cfg(feature = "server")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] pub use crate::render::SSRState; #[cfg(feature = "router")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "router")))] pub use crate::router::FullstackRouterConfig; #[cfg(feature = "server")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] pub use crate::serve_config::{ServeConfig, ServeConfigBuilder}; #[cfg(all(feature = "server", feature = "axum"))] + #[cfg_attr( + any(docsrs, feature = "nightly-doc"), + doc(cfg(all(feature = "server", feature = "axum"))) + )] pub use crate::server_context::Axum; #[cfg(feature = "server")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] pub use crate::server_context::{ extract, server_context, DioxusServerContext, FromServerContext, ProvideServerContext, }; pub use crate::server_fn::DioxusServerFn; #[cfg(feature = "server")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] pub use crate::server_fn::{ServerFnMiddleware, ServerFnTraitObj, ServerFunction}; pub use dioxus_server_macro::*; #[cfg(feature = "server")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] pub use dioxus_ssr::incremental::IncrementalRendererConfig; pub use server_fn::{self, ServerFn as _, ServerFnError}; @@ -66,11 +101,26 @@ pub mod prelude { } // Warn users about overlapping features -#[cfg(all(feature = "server", feature = "web", not(doc)))] +#[cfg(all( + feature = "server", + feature = "web", + not(doc), + not(feature = "nightly-doc") +))] compile_error!("The `ssr` feature (enabled by `warp`, `axum`, or `salvo`) and `web` feature are overlapping. Please choose one or the other."); -#[cfg(all(feature = "server", feature = "desktop", not(doc)))] +#[cfg(all( + feature = "server", + feature = "desktop", + not(doc), + not(feature = "nightly-doc") +))] compile_error!("The `ssr` feature (enabled by `warp`, `axum`, or `salvo`) and `desktop` feature are overlapping. Please choose one or the other."); -#[cfg(all(feature = "server", feature = "mobile", not(doc)))] +#[cfg(all( + feature = "server", + feature = "mobile", + not(doc), + not(feature = "nightly-doc") +))] compile_error!("The `ssr` feature (enabled by `warp`, `axum`, or `salvo`) and `mobile` feature are overlapping. Please choose one or the other."); diff --git a/packages/fullstack/src/server_context.rs b/packages/fullstack/src/server_context.rs index 6f3b4b6c9..8d5966a7c 100644 --- a/packages/fullstack/src/server_context.rs +++ b/packages/fullstack/src/server_context.rs @@ -228,6 +228,7 @@ impl FromServerContext for FromContext { } #[cfg(feature = "axum")] +#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "axum")))] /// An adapter for axum extractors for the server context pub struct Axum; diff --git a/packages/fullstack/src/server_fn.rs b/packages/fullstack/src/server_fn.rs index e71994b92..d51e4beec 100644 --- a/packages/fullstack/src/server_fn.rs +++ b/packages/fullstack/src/server_fn.rs @@ -1,9 +1,10 @@ -#[cfg(any(feature = "server", doc))] +#[cfg(feature = "server")] +#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] #[derive(Clone)] /// A trait object for a function that be called on serializable arguments and returns a serializable result. pub struct ServerFnTraitObj(server_fn::ServerFnTraitObj<()>); -#[cfg(any(feature = "server", doc))] +#[cfg(feature = "server")] impl std::ops::Deref for ServerFnTraitObj { type Target = server_fn::ServerFnTraitObj<()>; @@ -12,14 +13,14 @@ impl std::ops::Deref for ServerFnTraitObj { } } -#[cfg(any(feature = "server", doc))] +#[cfg(feature = "server")] impl std::ops::DerefMut for ServerFnTraitObj { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } -#[cfg(any(feature = "server", doc))] +#[cfg(feature = "server")] impl ServerFnTraitObj { fn new( prefix: &'static str, @@ -40,6 +41,7 @@ impl ServerFnTraitObj { server_fn::inventory::collect!(ServerFnTraitObj); #[cfg(feature = "server")] +#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] /// Middleware for a server function pub struct ServerFnMiddleware { /// The prefix of the server function. @@ -72,7 +74,8 @@ pub(crate) static MIDDLEWARE: once_cell::sync::Lazy< #[cfg(feature = "server")] server_fn::inventory::collect!(ServerFnMiddleware); -#[cfg(any(feature = "server", doc))] +#[cfg(feature = "server")] +#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] /// A server function that can be called on serializable arguments and returns a serializable result. pub type ServerFunction = server_fn::SerializedFnTraitObj<()>; @@ -88,7 +91,8 @@ static REGISTERED_SERVER_FUNCTIONS: once_cell::sync::Lazy< std::sync::Arc::new(std::sync::RwLock::new(map)) }); -#[cfg(any(feature = "server", doc))] +#[cfg(feature = "server")] +#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] /// The registry of all Dioxus server functions. pub struct DioxusServerFnRegistry; @@ -155,7 +159,8 @@ impl server_fn::ServerFunctionRegistry<()> for DioxusServerFnRegistry { } } -#[cfg(any(feature = "server", doc))] +#[cfg(feature = "server")] +#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] /// Errors that can occur when registering a server function. #[derive(thiserror::Error, Debug, Clone, serde::Serialize, serde::Deserialize)] pub enum ServerRegistrationFnError { @@ -178,7 +183,8 @@ pub enum ServerRegistrationFnError { /// Technically, the trait is implemented on a type that describes the server function's arguments, not the function itself. pub trait DioxusServerFn: server_fn::ServerFn<()> { /// Registers the server function, allowing the client to query it by URL. - #[cfg(any(feature = "server", doc))] + #[cfg(feature = "server")] + #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))] fn register_explicit() -> Result<(), server_fn::ServerFnError> { Self::register_in_explicit::() } diff --git a/packages/hooks/src/lib.rs b/packages/hooks/src/lib.rs index 1c937ff8e..5d842b5ff 100644 --- a/packages/hooks/src/lib.rs +++ b/packages/hooks/src/lib.rs @@ -1,7 +1,6 @@ #![doc = include_str!("../README.md")] #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")] #![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")] -#![cfg_attr(feature = "nightly-features", feature(debug_refcell))] #[macro_export] /// A helper macro for using hooks and properties in async environments. diff --git a/packages/liveview/src/launch.rs b/packages/liveview/src/launch.rs index 2b2d294a8..d008e38cd 100644 --- a/packages/liveview/src/launch.rs +++ b/packages/liveview/src/launch.rs @@ -3,9 +3,9 @@ use std::any::Any; #[cfg(feature = "axum")] pub type Config = crate::Config; -#[cfg(feature = "salvo")] +#[cfg(all(feature = "salvo", not(feature = "axum")))] pub type Config = crate::Config; -#[cfg(feature = "rocket")] +#[cfg(all(feature = "rocket", not(any(feature = "axum", feature = "salvo"))))] pub type Config = crate::Config>; /// Launches the WebView and runs the event loop, with configuration and root props. diff --git a/packages/router/Cargo.toml b/packages/router/Cargo.toml index e4f68d27f..3343f1886 100644 --- a/packages/router/Cargo.toml +++ b/packages/router/Cargo.toml @@ -35,7 +35,6 @@ default = [] ssr = ["dioxus-ssr/incremental", "tokio", "dioxus-fullstack?/server"] liveview = ["dioxus-liveview", "tokio", "dep:serde", "serde_json"] wasm_test = [] -serde = ["dep:serde", "gloo-utils?/serde"] web = ["gloo", "web-sys", "wasm-bindgen", "gloo-utils", "js-sys"] fullstack = ["dioxus-fullstack"] diff --git a/packages/router/src/components/router.rs b/packages/router/src/components/router.rs index af04fdacb..88aa349ce 100644 --- a/packages/router/src/components/router.rs +++ b/packages/router/src/components/router.rs @@ -11,18 +11,6 @@ pub struct RouterConfigFactory { config: Rc RouterConfig>>>>, } -#[cfg(feature = "serde")] -impl Default for RouterConfigFactory -where - ::Err: std::fmt::Display, - R: serde::Serialize + serde::de::DeserializeOwned, -{ - fn default() -> Self { - Self::from(RouterConfig::default) - } -} - -#[cfg(not(feature = "serde"))] impl Default for RouterConfigFactory where ::Err: std::fmt::Display, @@ -40,19 +28,6 @@ impl RouterConfig + 'static> From for RouterCo } } -#[cfg(feature = "serde")] -/// The props for [`Router`]. -#[derive(Props)] -pub struct RouterProps -where - ::Err: std::fmt::Display, - R: serde::Serialize + serde::de::DeserializeOwned, -{ - #[props(default, into)] - config: RouterConfigFactory, -} - -#[cfg(not(feature = "serde"))] /// The props for [`Router`]. #[derive(Props)] pub struct RouterProps @@ -74,7 +49,6 @@ where } } -#[cfg(not(feature = "serde"))] impl Default for RouterProps where ::Err: std::fmt::Display, @@ -86,20 +60,6 @@ where } } -#[cfg(feature = "serde")] -impl Default for RouterProps -where - ::Err: std::fmt::Display, - R: serde::Serialize + serde::de::DeserializeOwned, -{ - fn default() -> Self { - Self { - config: RouterConfigFactory::default(), - } - } -} - -#[cfg(not(feature = "serde"))] impl PartialEq for RouterProps where ::Err: std::fmt::Display, @@ -110,19 +70,6 @@ where } } -#[cfg(feature = "serde")] -impl PartialEq for RouterProps -where - ::Err: std::fmt::Display, - R: serde::Serialize + serde::de::DeserializeOwned, -{ - fn eq(&self, _: &Self) -> bool { - // prevent the router from re-rendering when the initial url or config changes - true - } -} - -#[cfg(not(feature = "serde"))] /// A component that renders the current route. pub fn Router(props: RouterProps) -> Element where @@ -148,28 +95,3 @@ where rsx! { Outlet:: {} } } - -#[cfg(feature = "serde")] -/// A component that renders the current route. -pub fn Router(cx: ScopeState>) -> Element -where - ::Err: std::fmt::Display, - R: serde::Serialize + serde::de::DeserializeOwned, -{ - use_context_provider(|| { - RouterContext::new( - (cx.props - .config - .config - .take() - .expect("use_context_provider ran twice"))(), - cx.schedule_update_any(), - ) - }); - use_context_provider(|| OutletContext:: { - current_level: 0, - _marker: std::marker::PhantomData, - }); - - rsx! { Outlet:: {} } -} diff --git a/packages/router/src/history/web.rs b/packages/router/src/history/web.rs index a0f677e24..180840d2d 100644 --- a/packages/router/src/history/web.rs +++ b/packages/router/src/history/web.rs @@ -23,7 +23,6 @@ fn base_path() -> Option<&'static str> { base_path } -#[cfg(not(feature = "serde"))] #[allow(clippy::extra_unused_type_parameters)] fn update_scroll(window: &Window, history: &History) { let scroll = ScrollPosition::of_window(window); @@ -32,27 +31,6 @@ fn update_scroll(window: &Window, history: &History) { } } -#[cfg(feature = "serde")] -fn update_scroll( - window: &Window, - history: &History, -) { - if let Some(WebHistoryState { state, .. }) = get_current::>(history) { - let scroll = ScrollPosition::of_window(window); - let state = WebHistoryState { state, scroll }; - if let Err(err) = replace_state_with_url(history, &state, None) { - error!(err); - } - } -} - -#[cfg(feature = "serde")] -#[derive(serde::Deserialize, serde::Serialize)] -struct WebHistoryState { - state: R, - scroll: ScrollPosition, -} - /// A [`HistoryProvider`] that integrates with a browser via the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API). /// /// # Prefix @@ -75,7 +53,6 @@ pub struct WebHistory { phantom: std::marker::PhantomData, } -#[cfg(not(feature = "serde"))] impl Default for WebHistory where ::Err: std::fmt::Display, @@ -85,19 +62,7 @@ where } } -#[cfg(feature = "serde")] -impl Default for WebHistory -where - ::Err: std::fmt::Display, - R: serde::Serialize + serde::de::DeserializeOwned, -{ - fn default() -> Self { - Self::new(None, true) - } -} - impl WebHistory { - #[cfg(not(feature = "serde"))] /// Create a new [`WebHistory`]. /// /// If `do_scroll_restoration` is [`true`], [`WebHistory`] will take control of the history @@ -116,47 +81,6 @@ impl WebHistory { myself } - #[cfg(feature = "serde")] - /// Create a new [`WebHistory`]. - /// - /// If `do_scroll_restoration` is [`true`], [`WebHistory`] will take control of the history - /// state. It'll also set the browsers scroll restoration to `manual`. - pub fn new(prefix: Option, do_scroll_restoration: bool) -> Self - where - ::Err: std::fmt::Display, - R: serde::Serialize + serde::de::DeserializeOwned, - { - let w = window().expect("access to `window`"); - let h = w.history().expect("`window` has access to `history`"); - let document = w.document().expect("`window` has access to `document`"); - - let myself = Self::new_inner( - prefix, - do_scroll_restoration, - EventListener::new(&document, "scroll", { - let mut last_updated = 0.0; - move |evt| { - // the time stamp in milliseconds - let time_stamp = evt.time_stamp(); - // throttle the scroll event to 100ms - if (time_stamp - last_updated) < 100.0 { - return; - } - update_scroll::(&w, &h); - last_updated = time_stamp; - } - }), - ); - - let current_route = myself.current_route(); - tracing::trace!("initial route: {:?}", current_route); - let current_url = current_route.to_string(); - let state = myself.create_state(current_route); - let _ = replace_state_with_url(&myself.history, &state, Some(¤t_url)); - - myself - } - fn new_inner(prefix: Option, do_scroll_restoration: bool) -> Self where ::Err: std::fmt::Display, @@ -191,17 +115,10 @@ impl WebHistory { .unwrap_or_default() } - #[cfg(not(feature = "serde"))] fn create_state(&self, _state: R) -> [f64; 2] { let scroll = self.scroll_pos(); [scroll.x, scroll.y] } - - #[cfg(feature = "serde")] - fn create_state(&self, state: R) -> WebHistoryState { - let scroll = self.scroll_pos(); - WebHistoryState { state, scroll } - } } impl WebHistory @@ -254,91 +171,6 @@ where } } -#[cfg(feature = "serde")] -impl HistoryProvider - for WebHistory -where - ::Err: std::fmt::Display, -{ - fn current_route(&self) -> R { - match get_current::>(&self.history) { - // Try to get the route from the history state - Some(route) => route.state, - // If that fails, get the route from the current URL - None => self.route_from_location(), - } - } - - fn current_prefix(&self) -> Option { - self.prefix.clone() - } - - fn go_back(&mut self) { - if let Err(e) = self.history.back() { - error!("failed to go back: ", e) - } - } - - fn go_forward(&mut self) { - if let Err(e) = self.history.forward() { - error!("failed to go forward: ", e) - } - } - - fn push(&mut self, state: R) { - use gloo_utils::format::JsValueSerdeExt; - if JsValue::from_serde(&state) != JsValue::from_serde(&self.current_route()) { - // don't push the same state twice - return; - } - - let w = window().expect("access to `window`"); - let h = w.history().expect("`window` has access to `history`"); - - // update the scroll position before pushing the new state - update_scroll::(&w, &h); - - let path = self.full_path(&state); - - let state = self.create_state(state); - - self.handle_nav(push_state_and_url(&self.history, &state, path)); - } - - fn replace(&mut self, state: R) { - let path = match &self.prefix { - None => format!("{state}"), - Some(prefix) => format!("{prefix}{state}"), - }; - - let state = self.create_state(state); - - self.handle_nav(replace_state_with_url(&self.history, &state, Some(&path))); - } - - fn external(&mut self, url: String) -> bool { - self.navigate_external(url) - } - - fn updater(&mut self, callback: std::sync::Arc) { - let w = self.window.clone(); - let h = self.history.clone(); - let s = self.listener_animation_frame.clone(); - let d = self.do_scroll_restoration; - - self.listener_navigation = Some(EventListener::new(&self.window, "popstate", move |_| { - (*callback)(); - if d { - let mut s = s.lock().expect("unpoisoned scroll mutex"); - if let Some(current_state) = get_current::>(&h) { - *s = Some(current_state.scroll.scroll_to(w.clone())); - } - } - })); - } -} - -#[cfg(not(feature = "serde"))] impl HistoryProvider for WebHistory where ::Err: std::fmt::Display, diff --git a/packages/router/src/history/web_history.rs b/packages/router/src/history/web_history.rs index 25a7063b4..df5219874 100644 --- a/packages/router/src/history/web_history.rs +++ b/packages/router/src/history/web_history.rs @@ -1,10 +1,7 @@ use gloo::console::error; -#[cfg(feature = "serde")] -use gloo_utils::format::JsValueSerdeExt; use wasm_bindgen::JsValue; use web_sys::History; -#[cfg(not(feature = "serde"))] pub(crate) fn replace_state_with_url( history: &History, value: &[f64; 2], @@ -17,18 +14,6 @@ pub(crate) fn replace_state_with_url( history.replace_state_with_url(&position, "", url) } -#[cfg(feature = "serde")] -pub(crate) fn replace_state_with_url( - history: &History, - value: &V, - url: Option<&str>, -) -> Result<(), JsValue> { - let position = JsValue::from_serde(value).unwrap(); - - history.replace_state_with_url(&position, "", url) -} - -#[cfg(not(feature = "serde"))] pub(crate) fn push_state_and_url( history: &History, value: &[f64; 2], @@ -41,33 +26,6 @@ pub(crate) fn push_state_and_url( history.push_state_with_url(&position, "", Some(&url)) } -#[cfg(feature = "serde")] -pub(crate) fn push_state_and_url( - history: &History, - value: &V, - url: String, -) -> Result<(), JsValue> { - let position = JsValue::from_serde(value).unwrap(); - - history.push_state_with_url(&position, "", Some(&url)) -} - -#[cfg(feature = "serde")] -pub(crate) fn get_current(history: &History) -> Option { - let state = history.state(); - if let Err(err) = &state { - error!(err); - } - state.ok().and_then(|state| { - let deserialized = state.into_serde(); - if let Err(err) = &deserialized { - error!(format!("{}", err)); - } - deserialized.ok() - }) -} - -#[cfg(not(feature = "serde"))] pub(crate) fn get_current(history: &History) -> Option<[f64; 2]> { use wasm_bindgen::JsCast; diff --git a/packages/router/src/router_cfg.rs b/packages/router/src/router_cfg.rs index 0c81faae1..30dcac10f 100644 --- a/packages/router/src/router_cfg.rs +++ b/packages/router/src/router_cfg.rs @@ -31,21 +31,6 @@ pub struct RouterConfig { pub(crate) initial_route: Option, } -#[cfg(feature = "serde")] -impl Default for RouterConfig -where - ::Err: std::fmt::Display, - R: serde::Serialize + serde::de::DeserializeOwned, -{ - fn default() -> Self { - Self { - failure_external_navigation: FailureExternalNavigation::, - history: None, - on_update: None, - } - } -} - macro_rules! default_history { ($initial_route:ident) => { { @@ -83,24 +68,6 @@ macro_rules! default_history { }; } -#[cfg(feature = "serde")] -impl RouterConfig -where - ::Err: std::fmt::Display, - R: serde::Serialize + serde::de::DeserializeOwned, -{ - pub(crate) fn get_history(self) -> Box> { - #[allow(unused)] - let initial_route = self.initial_route.clone().unwrap_or("/".parse().unwrap_or_else(|err| - panic!("index route does not exist:\n{}\n use MemoryHistory::with_initial_path or RouterConfig::initial_route to set a custom path", err) - )); - self.history - .take() - .unwrap_or_else(|| default_history!(initial_route)) - } -} - -#[cfg(not(feature = "serde"))] impl Default for RouterConfig where ::Err: std::fmt::Display,