diff --git a/.cargo/config.toml b/.cargo/config.toml
new file mode 100644
index 000000000..464189e01
--- /dev/null
+++ b/.cargo/config.toml
@@ -0,0 +1,5 @@
+# All of these variables are used in the `openid_connect_demo` example, they are set here for the CI to work, they are set here because as stated here for now: `https://doc.rust-lang.org/cargo/reference/config.html` the .cargo/config.toml of the inner workspaces are not read when being invoked from the root workspace.
+[env]
+DIOXUS_FRONT_ISSUER_URL = ""
+DIOXUS_FRONT_CLIENT_ID = ""
+DIOXUS_FRONT_URL = ""
diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml
index 500d41564..cb5a1f1bb 100644
--- a/.github/workflows/playwright.yml
+++ b/.github/workflows/playwright.yml
@@ -20,7 +20,7 @@ jobs:
steps:
# Do our best to cache the toolchain and node install steps
- uses: actions/checkout@v4
- - uses: actions/setup-node@v3
+ - uses: actions/setup-node@v4
with:
node-version: 16
- name: Install Rust
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index b056a9590..000000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,171 +0,0 @@
-# Changelog
-
-All notable changes to this project will be documented in this file.
-
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
-and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-
-## Unreleased
-
-### Commit Statistics
-
-
-
- - 1 commit contributed to the release over the course of 7 calendar days.
- - 0 commits where understood as [conventional](https://www.conventionalcommits.org).
- - 0 issues like '(#ID)' where seen in commit messages
-
-### Commit Details
-
-
-
-view details
-
- * **Uncategorized**
- - Fix various typos and grammar nits ([`9e4ec43`](https://github.comgit//DioxusLabs/dioxus/commit/9e4ec43b1e78d355c56a38e4c092170b2b01b20d))
-
-
-## v0.1.7 (2022-01-08)
-
-### Bug Fixes
-
- - tests
-
-### Commit Statistics
-
-
-
- - 1 commit contributed to the release over the course of 2 calendar days.
- - 1 commit where understood as [conventional](https://www.conventionalcommits.org).
- - 0 issues like '(#ID)' where seen in commit messages
-
-### Commit Details
-
-
-
-view details
-
- * **Uncategorized**
- - tests ([`bd341f5`](https://github.comgit//DioxusLabs/dioxus/commit/bd341f5571580cdf5e495379b49ca988fd9211c3))
-
-
-## v0.1.1 (2021-12-15)
-
-### Documentation
-
- - update local examples and docs to support new syntaxes
- - improve docs
- - big updates to the reference
- - lib.rs docs
- - move around examples
-
-### New Features
-
- - it compiles once more
- - massage lifetimes
- - amazingly awesome error handling
- - svgs working in webview
- - mvoe away from compound context
- - more suspended nodes!
- - add aria
- - enable arbitrary body in rsx! macro
-
-## v0.1.0 (2021-12-15)
-
-### Documentation
-
- - update local examples and docs to support new syntaxes
- - improve docs
- - big updates to the reference
- - lib.rs docs
- - move around examples
-
-### New Features
-
- - it compiles once more
- - massage lifetimes
- - amazingly awesome error handling
- - svgs working in webview
- - mvoe away from compound context
- - more suspended nodes!
- - add aria
- - enable arbitrary body in rsx! macro
-
-## v0.0.1 (2022-01-03)
-
-### Documentation
-
- - improve docs
- - update local examples and docs to support new syntaxes
- - big updates to the reference
- - lib.rs docs
- - move around examples
-
-### New Features
-
- - it compiles once more
- - massage lifetimes
- - amazingly awesome error handling
- - svgs working in webview
- - mvoe away from compound context
- - more suspended nodes!
- - add aria
- - enable arbitrary body in rsx! macro
-
-### Commit Statistics
-
-
-
- - 40 commits contributed to the release over the course of 193 calendar days.
- - 38 commits where understood as [conventional](https://www.conventionalcommits.org).
- - 0 issues like '(#ID)' where seen in commit messages
-
-### Commit Details
-
-
-
-view details
-
- * **Uncategorized**
- - remove runner on hook and then update docs ([`d156045`](https://github.comgit//DioxusLabs/dioxus/commit/d1560450bac55f9566e00e00ea405bd1c70b57e5))
- - polish some more things ([`1496102`](https://github.comgit//DioxusLabs/dioxus/commit/14961023f927b3a8bde83cfc7883aa8bfcca9e85))
- - upgrade hooks ([`b3ac2ee`](https://github.comgit//DioxusLabs/dioxus/commit/b3ac2ee3f76549cd1c7b6f9eee7e3382b07d873c))
- - docs ([`8814977`](https://github.comgit//DioxusLabs/dioxus/commit/8814977eeebe06748a3b9677a8070e42a037ebd7))
- - prepare to change our fragment pattern. Add some more docs ([`2c3a046`](https://github.comgit//DioxusLabs/dioxus/commit/2c3a0464264fa11e8100df025d863931f9606cdb))
- - it compiles once more ([`8acdd2e`](https://github.comgit//DioxusLabs/dioxus/commit/8acdd2ea830b995b608d8bac2ef527db8d40e662))
- - some docs and suspense ([`93d4b8c`](https://github.comgit//DioxusLabs/dioxus/commit/93d4b8ca7c1b133e5dba2a8dc9a310dbe1357001))
- - docs and router ([`a5f05d7`](https://github.comgit//DioxusLabs/dioxus/commit/a5f05d73acc0e47b05cff64a373482519414bc7c))
- - Merge branch 'master' into jk/remove_node_safety ([`db00047`](https://github.comgit//DioxusLabs/dioxus/commit/db0004758c77331cc3b93ea8cf227c060028e12e))
- - improve docs ([`7800744`](https://github.comgit//DioxusLabs/dioxus/commit/78007445f944f259170307d840e0f16242b7b4b6))
- - Various typos/grammar/rewording ([`5747e00`](https://github.comgit//DioxusLabs/dioxus/commit/5747e00b27b1b69c4f9c2820e7e78030feaff71e))
- - bubbling in progress ([`a21020e`](https://github.comgit//DioxusLabs/dioxus/commit/a21020ea575e467ba0d608737269fe1b0792dba7))
- - update local examples and docs to support new syntaxes ([`4de16c4`](https://github.comgit//DioxusLabs/dioxus/commit/4de16c4779648e591b3869b5df31271ae603c812))
- - massage lifetimes ([`9726a06`](https://github.comgit//DioxusLabs/dioxus/commit/9726a065b0d4fb1ede5b53a2ddd58c855e51539f))
- - major cleanups to scheduler ([`2933e4b`](https://github.comgit//DioxusLabs/dioxus/commit/2933e4bc11b3074c2bde8d76ec55364fca841988))
- - threadsafe ([`82953f2`](https://github.comgit//DioxusLabs/dioxus/commit/82953f2ac37913f83a822333acd0c47e20777d31))
- - move macro crate out of core ([`7bdad1e`](https://github.comgit//DioxusLabs/dioxus/commit/7bdad1e2e6f67e74c9f67dde2150140cf8a090e8))
- - amazingly awesome error handling ([`4a72b31`](https://github.comgit//DioxusLabs/dioxus/commit/4a72b3140bd244da602deada1eeecded65ff5848))
- - some ideas ([`05c909f`](https://github.comgit//DioxusLabs/dioxus/commit/05c909f320765aec1bf4c1c55ca59ffd5525a2c7))
- - big updates to the reference ([`583fdfa`](https://github.comgit//DioxusLabs/dioxus/commit/583fdfa5618e11d660985b97e570d4503be2ff49))
- - docs, html! macro, more ([`caf772c`](https://github.comgit//DioxusLabs/dioxus/commit/caf772cf249d2f56c8d0b0fa2737ad48e32c6e82))
- - cleanup workspace ([`8f0bb5d`](https://github.comgit//DioxusLabs/dioxus/commit/8f0bb5dc5bfa3e775af567c4b569622cdd932af1))
- - svgs working in webview ([`3bedcb9`](https://github.comgit//DioxusLabs/dioxus/commit/3bedcb93cacec5bdf134adc38ff02eadbf96c1c6))
- - mvoe away from compound context ([`a2c7d17`](https://github.comgit//DioxusLabs/dioxus/commit/a2c7d17b0595769f60bc1c2bbf7cbe32cec37486))
- - more suspended nodes! ([`de9f61b`](https://github.comgit//DioxusLabs/dioxus/commit/de9f61bcf48c0d6e35e46c337b72a713c9f9f7d2))
- - add aria ([`4091846`](https://github.comgit//DioxusLabs/dioxus/commit/4091846934b4b3b2bc03d3ca8aaf7712aebd4e36))
- - more examples ([`56e7eb8`](https://github.comgit//DioxusLabs/dioxus/commit/56e7eb83a97ebd6d5bcd23464cfb9d718e5ac26d))
- - more refactor for async ([`975fa56`](https://github.comgit//DioxusLabs/dioxus/commit/975fa566f9809f8fa2bb0bdb07fbfc7f855dcaeb))
- - enable arbitrary body in rsx! macro ([`7aec40d`](https://github.comgit//DioxusLabs/dioxus/commit/7aec40d57e78ec13ff3a90ca8149521cbf1d9ff2))
- - move CLI into its own "studio" app ([`fd79335`](https://github.comgit//DioxusLabs/dioxus/commit/fd7933561fe81922e4d5d77f6ac3b6f19efb5a90))
- - move some examples around ([`98a0933`](https://github.comgit//DioxusLabs/dioxus/commit/98a09339fd3190799ea4dd316908f0a53fdf2413))
- - fix issues with lifetimes ([`a38a81e`](https://github.comgit//DioxusLabs/dioxus/commit/a38a81e1290375cae685f7c49d3745e4298fab26))
- - more examples ([`11f89e5`](https://github.comgit//DioxusLabs/dioxus/commit/11f89e5d338d14a7aeece0a6275c24ae65913ce7))
- - lib.rs docs ([`bf21c82`](https://github.comgit//DioxusLabs/dioxus/commit/bf21c82de04e25daee60a06232b9a16b640508f2))
- - rename ctx to cx ([`81382e7`](https://github.comgit//DioxusLabs/dioxus/commit/81382e7044fb3dba61d4abb1e6086b7b29143116))
- - move around examples ([`70cd46d`](https://github.comgit//DioxusLabs/dioxus/commit/70cd46dbb2a689ae2d512e142b8aee9c80798430))
- - start moving events to rc ([`b9ff95f`](https://github.comgit//DioxusLabs/dioxus/commit/b9ff95fa12c46365fe73b64a4926a506d5da2342))
- - rename recoil to atoms ([`36ea39a`](https://github.comgit//DioxusLabs/dioxus/commit/36ea39ae30aa3f1fb2d718c0fdf08850c6bfd3ac))
- - more examples and docs ([`7fbaf69`](https://github.comgit//DioxusLabs/dioxus/commit/7fbaf69cabbdde712bb3fd9e4b2a5dc18b9390e9))
- - docs ([`f5683a2`](https://github.comgit//DioxusLabs/dioxus/commit/f5683a23464992ecace463a61414795b5a2c58c8))
-
-
diff --git a/Cargo.toml b/Cargo.toml
index e6b07eb8c..d687d74d0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -41,6 +41,7 @@ members = [
"examples/tailwind",
"examples/PWA-example",
"examples/query_segments_demo",
+ "examples/openid_connect_demo",
# Playwright tests
"playwright-tests/liveview",
"playwright-tests/web",
@@ -87,7 +88,7 @@ slab = "0.4.2"
futures-channel = "0.3.21"
futures-util = { version = "0.3", default-features = false }
rustc-hash = "1.1.0"
-wasm-bindgen = "0.2.87"
+wasm-bindgen = "0.2.88"
html_parser = "0.7.0"
thiserror = "1.0.40"
prettyplease = { package = "prettier-please", version = "0.2", features = [
diff --git a/README.md b/README.md
index 5b6a99ad3..d1ec98019 100644
--- a/README.md
+++ b/README.md
@@ -159,6 +159,7 @@ So... Dioxus is great, but why won't it work for me?
## Contributing
+- Check out the website [section on contributing](https://dioxuslabs.com/learn/0.4/contributing).
- Report issues on our [issue tracker](https://github.com/dioxuslabs/dioxus/issues).
- Join the discord and ask questions!
diff --git a/examples/mobile_demo/.gitignore b/examples/mobile_demo/.gitignore
index 419513ee1..e1e084c4b 100644
--- a/examples/mobile_demo/.gitignore
+++ b/examples/mobile_demo/.gitignore
@@ -2,7 +2,7 @@
target/
**/*.rs.bk
-# tauri-mobile
+# cargo-mobile2
.cargo/
/gen
diff --git a/examples/mobile_demo/README.md b/examples/mobile_demo/README.md
index 7ea4303b8..178b2f733 100644
--- a/examples/mobile_demo/README.md
+++ b/examples/mobile_demo/README.md
@@ -4,7 +4,7 @@
Right now, Dioxus supports mobile targets including iOS and Android. However, our tooling is not mature enough to include the build commands directly.
-This project was generated using [tauri-mobile](https://github.com/tauri-apps/tauri-mobile). We have yet to integrate this generation into the Dioxus-CLI. The open issue for this is [#1157](https://github.com/DioxusLabs/dioxus/issues/1157).
+This project was generated using [cargo-mobile2](https://github.com/tauri-apps/cargo-mobile2). We have yet to integrate this generation into the Dioxus-CLI. The open issue for this is [#1157](https://github.com/DioxusLabs/dioxus/issues/1157).
## Running on iOS
diff --git a/examples/openid_connect_demo/.gitignore b/examples/openid_connect_demo/.gitignore
new file mode 100644
index 000000000..919c8ee55
--- /dev/null
+++ b/examples/openid_connect_demo/.gitignore
@@ -0,0 +1,3 @@
+/target
+/dist
+.env
diff --git a/examples/openid_connect_demo/Cargo.toml b/examples/openid_connect_demo/Cargo.toml
new file mode 100644
index 000000000..4c5f47061
--- /dev/null
+++ b/examples/openid_connect_demo/Cargo.toml
@@ -0,0 +1,24 @@
+[package]
+name = "openid_auth_demo"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+console_error_panic_hook = "0.1"
+dioxus-logger = "0.4.1"
+dioxus = { path = "../../packages/dioxus", version = "*" }
+dioxus-router = { path = "../../packages/router", version = "*" }
+dioxus-web = { path = "../../packages/web", version = "*" }
+fermi = { path = "../../packages/fermi", version = "*" }
+form_urlencoded = "1.2.0"
+gloo-storage = "0.3.0"
+log = "0.4"
+openidconnect = "3.4.0"
+reqwest = "0.11.20"
+serde = { version = "1.0.188", features = ["derive"] }
+serde_json = "1.0.105"
+thiserror = "1.0.48"
+uuid = "1.4"
+web-sys = { version = "0.3", features = ["Request", "Document"] }
diff --git a/examples/openid_connect_demo/Dioxus.toml b/examples/openid_connect_demo/Dioxus.toml
new file mode 100644
index 000000000..483dfe957
--- /dev/null
+++ b/examples/openid_connect_demo/Dioxus.toml
@@ -0,0 +1,47 @@
+[application]
+
+# dioxus project name
+name = "OpenID Connect authentication demo"
+
+# default platfrom
+# you can also use `dioxus serve/build --platform XXX` to use other platform
+# value: web | desktop
+default_platform = "web"
+
+# Web `build` & `serve` dist path
+out_dir = "dist"
+
+# resource (static) file folder
+asset_dir = "public"
+
+[web.app]
+
+# HTML title tag content
+title = "OpenID Connect authentication demo"
+
+[web.watcher]
+
+index_on_404 = true
+
+watch_path = ["src"]
+
+# include `assets` in web platform
+[web.resource]
+
+# CSS style file
+style = []
+
+# Javascript code file
+script = []
+
+[web.resource.dev]
+
+# Javascript code file
+# serve: [dev-server] only
+script = []
+
+[application.plugins]
+
+available = true
+
+required = []
diff --git a/examples/openid_connect_demo/README.md b/examples/openid_connect_demo/README.md
new file mode 100644
index 000000000..e16467ddf
--- /dev/null
+++ b/examples/openid_connect_demo/README.md
@@ -0,0 +1,13 @@
+# OpenID Connect example to show how to authenticate an user
+
+The environment variables in `.cargo/config.toml` must be set in order for this example to work(if this example is just being compiled from the root workspace, the `.cargo/config.toml` from the root workspace must be set as stated in the [Cargo book](https://doc.rust-lang.org/cargo/reference/config.html)).
+
+Once they are set, you can run `dx serve`
+
+### Environment variables summary
+
+```DIOXUS_FRONT_ISSUER_URL``` The openid-connect's issuer url
+
+```DIOXUS_FRONT_CLIENT_ID``` The openid-connect's client id
+
+```DIOXUS_FRONT_URL``` The url the frontend is supposed to be running on, it could be for example `http://localhost:8080`
\ No newline at end of file
diff --git a/examples/openid_connect_demo/src/constants.rs b/examples/openid_connect_demo/src/constants.rs
new file mode 100644
index 000000000..0a0b4950a
--- /dev/null
+++ b/examples/openid_connect_demo/src/constants.rs
@@ -0,0 +1,2 @@
+pub const DIOXUS_FRONT_AUTH_TOKEN: &str = "auth_token";
+pub const DIOXUS_FRONT_AUTH_REQUEST: &str = "auth_request";
diff --git a/examples/openid_connect_demo/src/errors.rs b/examples/openid_connect_demo/src/errors.rs
new file mode 100644
index 000000000..2b7e3f145
--- /dev/null
+++ b/examples/openid_connect_demo/src/errors.rs
@@ -0,0 +1,20 @@
+use openidconnect::{core::CoreErrorResponseType, url, RequestTokenError, StandardErrorResponse};
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum Error {
+ #[error("Discovery error: {0}")]
+ OpenIdConnect(
+ #[from] openidconnect::DiscoveryError>,
+ ),
+ #[error("Parsing error: {0}")]
+ Parse(#[from] url::ParseError),
+ #[error("Request token error: {0}")]
+ RequestToken(
+ #[from]
+ RequestTokenError<
+ openidconnect::reqwest::Error,
+ StandardErrorResponse,
+ >,
+ ),
+}
diff --git a/examples/openid_connect_demo/src/main.rs b/examples/openid_connect_demo/src/main.rs
new file mode 100644
index 000000000..7ed8db8a9
--- /dev/null
+++ b/examples/openid_connect_demo/src/main.rs
@@ -0,0 +1,60 @@
+#![allow(non_snake_case)]
+use dioxus::prelude::*;
+use fermi::*;
+use gloo_storage::{LocalStorage, Storage};
+use log::LevelFilter;
+pub(crate) mod constants;
+pub(crate) mod errors;
+pub(crate) mod model;
+pub(crate) mod oidc;
+pub(crate) mod props;
+pub(crate) mod router;
+pub(crate) mod storage;
+pub(crate) mod views;
+use oidc::{AuthRequestState, AuthTokenState};
+use router::Route;
+
+use dioxus_router::prelude::*;
+
+use crate::{
+ constants::{DIOXUS_FRONT_AUTH_REQUEST, DIOXUS_FRONT_AUTH_TOKEN},
+ oidc::ClientState,
+};
+pub static FERMI_CLIENT: fermi::AtomRef = AtomRef(|_| ClientState::default());
+
+// An option is required to prevent the component from being constantly refreshed
+pub static FERMI_AUTH_TOKEN: fermi::AtomRef> = AtomRef(|_| None);
+pub static FERMI_AUTH_REQUEST: fermi::AtomRef > = AtomRef(|_| None);
+
+pub static DIOXUS_FRONT_ISSUER_URL: &str = env!("DIOXUS_FRONT_ISSUER_URL");
+pub static DIOXUS_FRONT_CLIENT_ID: &str = env!("DIOXUS_FRONT_CLIENT_ID");
+pub static DIOXUS_FRONT_URL: &str = env!("DIOXUS_FRONT_URL");
+
+fn App(cx: Scope) -> Element {
+ use_init_atom_root(cx);
+
+ // Retrieve the value stored in the browser's storage
+ let stored_auth_token = LocalStorage::get(DIOXUS_FRONT_AUTH_TOKEN)
+ .ok()
+ .unwrap_or(AuthTokenState::default());
+ let fermi_auth_token = use_atom_ref(cx, &FERMI_AUTH_TOKEN);
+ if fermi_auth_token.read().is_none() {
+ *fermi_auth_token.write() = Some(stored_auth_token);
+ }
+
+ let stored_auth_request = LocalStorage::get(DIOXUS_FRONT_AUTH_REQUEST)
+ .ok()
+ .unwrap_or(AuthRequestState::default());
+ let fermi_auth_request = use_atom_ref(cx, &FERMI_AUTH_REQUEST);
+ if fermi_auth_request.read().is_none() {
+ *fermi_auth_request.write() = Some(stored_auth_request);
+ }
+ render! { Router:: {} }
+}
+
+fn main() {
+ dioxus_logger::init(LevelFilter::Info).expect("failed to init logger");
+ console_error_panic_hook::set_once();
+ log::info!("starting app");
+ dioxus_web::launch(App);
+}
diff --git a/examples/openid_connect_demo/src/model/mod.rs b/examples/openid_connect_demo/src/model/mod.rs
new file mode 100644
index 000000000..68a79f5c0
--- /dev/null
+++ b/examples/openid_connect_demo/src/model/mod.rs
@@ -0,0 +1 @@
+pub(crate) mod user;
diff --git a/examples/openid_connect_demo/src/model/user.rs b/examples/openid_connect_demo/src/model/user.rs
new file mode 100644
index 000000000..b1005fdd2
--- /dev/null
+++ b/examples/openid_connect_demo/src/model/user.rs
@@ -0,0 +1,7 @@
+use uuid::Uuid;
+
+#[derive(PartialEq)]
+pub struct User {
+ pub id: Uuid,
+ pub name: String,
+}
diff --git a/examples/openid_connect_demo/src/oidc.rs b/examples/openid_connect_demo/src/oidc.rs
new file mode 100644
index 000000000..7fa96c14b
--- /dev/null
+++ b/examples/openid_connect_demo/src/oidc.rs
@@ -0,0 +1,125 @@
+use openidconnect::{
+ core::{CoreClient, CoreErrorResponseType, CoreIdToken, CoreResponseType, CoreTokenResponse},
+ reqwest::async_http_client,
+ url::Url,
+ AuthenticationFlow, AuthorizationCode, ClaimsVerificationError, ClientId, CsrfToken, IssuerUrl,
+ LogoutRequest, Nonce, ProviderMetadataWithLogout, RedirectUrl, RefreshToken, RequestTokenError,
+ StandardErrorResponse,
+};
+use serde::{Deserialize, Serialize};
+
+use crate::{props::client::ClientProps, DIOXUS_FRONT_CLIENT_ID};
+
+#[derive(Clone, Debug, Default)]
+pub struct ClientState {
+ pub oidc_client: Option,
+}
+
+/// State that holds the nonce and authorization url and the nonce generated to log in an user
+#[derive(Clone, Deserialize, Serialize, Default)]
+pub struct AuthRequestState {
+ pub auth_request: Option,
+}
+
+#[derive(Clone, Deserialize, Serialize)]
+pub struct AuthRequest {
+ pub nonce: Nonce,
+ pub authorize_url: String,
+}
+
+/// State the tokens returned once the user is authenticated
+#[derive(Debug, Deserialize, Serialize, Default, Clone)]
+pub struct AuthTokenState {
+ /// Token used to identify the user
+ pub id_token: Option,
+ /// Token used to refresh the tokens if they expire
+ pub refresh_token: Option,
+}
+
+pub fn email(
+ client: CoreClient,
+ id_token: CoreIdToken,
+ nonce: Nonce,
+) -> Result {
+ match id_token.claims(&client.id_token_verifier(), &nonce) {
+ Ok(claims) => Ok(claims.clone().email().unwrap().to_string()),
+ Err(error) => Err(error),
+ }
+}
+
+pub fn authorize_url(client: CoreClient) -> AuthRequest {
+ let (authorize_url, _csrf_state, nonce) = client
+ .authorize_url(
+ AuthenticationFlow::::AuthorizationCode,
+ CsrfToken::new_random,
+ Nonce::new_random,
+ )
+ .add_scope(openidconnect::Scope::new("email".to_string()))
+ .add_scope(openidconnect::Scope::new("profile".to_string()))
+ .url();
+ AuthRequest {
+ authorize_url: authorize_url.to_string(),
+ nonce,
+ }
+}
+
+pub async fn init_provider_metadata() -> Result {
+ let issuer_url = IssuerUrl::new(crate::DIOXUS_FRONT_ISSUER_URL.to_string())?;
+ Ok(ProviderMetadataWithLogout::discover_async(issuer_url, async_http_client).await?)
+}
+
+pub async fn init_oidc_client() -> Result<(ClientId, CoreClient), crate::errors::Error> {
+ let client_id = ClientId::new(crate::DIOXUS_FRONT_CLIENT_ID.to_string());
+ let provider_metadata = init_provider_metadata().await?;
+ let client_secret = None;
+ let redirect_url = RedirectUrl::new(format!("{}/login", crate::DIOXUS_FRONT_URL))?;
+
+ Ok((
+ client_id.clone(),
+ CoreClient::from_provider_metadata(provider_metadata, client_id, client_secret)
+ .set_redirect_uri(redirect_url),
+ ))
+}
+
+///TODO: Add pkce_pacifier
+pub async fn token_response(
+ oidc_client: CoreClient,
+ code: String,
+) -> Result {
+ // let (pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256();
+ Ok(oidc_client
+ .exchange_code(AuthorizationCode::new(code.clone()))
+ // .set_pkce_verifier(pkce_verifier)
+ .request_async(async_http_client)
+ .await?)
+}
+
+pub async fn exchange_refresh_token(
+ oidc_client: CoreClient,
+ refresh_token: RefreshToken,
+) -> Result<
+ CoreTokenResponse,
+ RequestTokenError<
+ openidconnect::reqwest::Error,
+ StandardErrorResponse,
+ >,
+> {
+ oidc_client
+ .exchange_refresh_token(&refresh_token)
+ .request_async(async_http_client)
+ .await
+}
+
+pub async fn log_out_url(id_token_hint: CoreIdToken) -> Result {
+ let provider_metadata = init_provider_metadata().await?;
+ let end_session_url = provider_metadata
+ .additional_metadata()
+ .clone()
+ .end_session_endpoint
+ .unwrap();
+ let logout_request: LogoutRequest = LogoutRequest::from(end_session_url);
+ Ok(logout_request
+ .set_client_id(ClientId::new(DIOXUS_FRONT_CLIENT_ID.to_string()))
+ .set_id_token_hint(&id_token_hint)
+ .http_get_url())
+}
diff --git a/examples/openid_connect_demo/src/props/client.rs b/examples/openid_connect_demo/src/props/client.rs
new file mode 100644
index 000000000..2e02111e1
--- /dev/null
+++ b/examples/openid_connect_demo/src/props/client.rs
@@ -0,0 +1,20 @@
+use dioxus::prelude::*;
+use openidconnect::{core::CoreClient, ClientId};
+
+#[derive(Props, Clone, Debug)]
+pub struct ClientProps {
+ pub client: CoreClient,
+ pub client_id: ClientId,
+}
+
+impl PartialEq for ClientProps {
+ fn eq(&self, other: &Self) -> bool {
+ self.client_id == other.client_id
+ }
+}
+
+impl ClientProps {
+ pub fn new(client_id: ClientId, client: CoreClient) -> Self {
+ ClientProps { client_id, client }
+ }
+}
diff --git a/examples/openid_connect_demo/src/props/mod.rs b/examples/openid_connect_demo/src/props/mod.rs
new file mode 100644
index 000000000..1d3313153
--- /dev/null
+++ b/examples/openid_connect_demo/src/props/mod.rs
@@ -0,0 +1 @@
+pub(crate) mod client;
diff --git a/examples/openid_connect_demo/src/router.rs b/examples/openid_connect_demo/src/router.rs
new file mode 100644
index 000000000..0bb80afbb
--- /dev/null
+++ b/examples/openid_connect_demo/src/router.rs
@@ -0,0 +1,17 @@
+use crate::views::{header::AuthHeader, home::Home, login::Login, not_found::NotFound};
+use dioxus::prelude::*;
+use dioxus_router::prelude::*;
+
+#[derive(Routable, Clone)]
+pub enum Route {
+ #[layout(AuthHeader)]
+ #[route("/")]
+ Home {},
+
+ // https://dioxuslabs.com/learn/0.4/router/reference/routes#query-segments
+ #[route("/login?:query_string")]
+ Login { query_string: String },
+ #[end_layout]
+ #[route("/:..route")]
+ NotFound { route: Vec },
+}
diff --git a/examples/openid_connect_demo/src/storage.rs b/examples/openid_connect_demo/src/storage.rs
new file mode 100644
index 000000000..402740cdf
--- /dev/null
+++ b/examples/openid_connect_demo/src/storage.rs
@@ -0,0 +1,38 @@
+use fermi::UseAtomRef;
+use gloo_storage::{LocalStorage, Storage};
+use serde::{Deserialize, Serialize};
+
+use crate::{
+ constants::{DIOXUS_FRONT_AUTH_REQUEST, DIOXUS_FRONT_AUTH_TOKEN},
+ oidc::{AuthRequestState, AuthTokenState},
+};
+
+#[derive(Serialize, Deserialize, Clone)]
+pub struct StorageEntry {
+ pub key: String,
+ pub value: T,
+}
+
+pub trait PersistentWrite {
+ fn persistent_set(atom_ref: &UseAtomRef>, entry: Option);
+}
+
+impl PersistentWrite for AuthTokenState {
+ fn persistent_set(
+ atom_ref: &UseAtomRef>,
+ entry: Option,
+ ) {
+ *atom_ref.write() = entry.clone();
+ LocalStorage::set(DIOXUS_FRONT_AUTH_TOKEN, entry).unwrap();
+ }
+}
+
+impl PersistentWrite for AuthRequestState {
+ fn persistent_set(
+ atom_ref: &UseAtomRef>,
+ entry: Option,
+ ) {
+ *atom_ref.write() = entry.clone();
+ LocalStorage::set(DIOXUS_FRONT_AUTH_REQUEST, entry).unwrap();
+ }
+}
diff --git a/examples/openid_connect_demo/src/views/header.rs b/examples/openid_connect_demo/src/views/header.rs
new file mode 100644
index 000000000..1f2c6e057
--- /dev/null
+++ b/examples/openid_connect_demo/src/views/header.rs
@@ -0,0 +1,250 @@
+use crate::{
+ oidc::{
+ authorize_url, email, exchange_refresh_token, init_oidc_client, log_out_url,
+ AuthRequestState, AuthTokenState, ClientState,
+ },
+ props::client::ClientProps,
+ router::Route,
+ storage::PersistentWrite,
+ FERMI_AUTH_REQUEST, FERMI_AUTH_TOKEN, FERMI_CLIENT,
+};
+use dioxus::prelude::*;
+use dioxus_router::prelude::{Link, Outlet};
+use fermi::*;
+use openidconnect::{url::Url, OAuth2TokenResponse, TokenResponse};
+
+#[component]
+pub fn LogOut(cx: Scope) -> Element {
+ let fermi_auth_token = use_atom_ref(cx, &FERMI_AUTH_TOKEN);
+ let fermi_auth_token_read = fermi_auth_token.read().clone();
+ let log_out_url_state = use_state(cx, || None::>>);
+ cx.render(match fermi_auth_token_read {
+ Some(fermi_auth_token_read) => match fermi_auth_token_read.id_token.clone() {
+ Some(id_token) => match log_out_url_state.get() {
+ Some(log_out_url_result) => match log_out_url_result {
+ Some(uri) => match uri {
+ Ok(uri) => {
+ rsx! {
+ Link {
+ onclick: move |_| {
+ {
+ AuthTokenState::persistent_set(
+ fermi_auth_token,
+ Some(AuthTokenState::default()),
+ );
+ }
+ },
+ to: uri.to_string(),
+ "Log out"
+ }
+ }
+ }
+ Err(error) => {
+ rsx! {
+ div { format!{"Failed to load disconnection url: {:?}", error} }
+ }
+ }
+ },
+ None => {
+ rsx! { div { "Loading... Please wait" } }
+ }
+ },
+ None => {
+ let logout_url_task = move || {
+ cx.spawn({
+ let log_out_url_state = log_out_url_state.to_owned();
+ async move {
+ let logout_url = log_out_url(id_token).await;
+ let logout_url_option = Some(logout_url);
+ log_out_url_state.set(Some(logout_url_option));
+ }
+ })
+ };
+ logout_url_task();
+ rsx! { div{"Loading log out url... Please wait"}}
+ }
+ },
+ None => {
+ rsx! {{}}
+ }
+ },
+ None => {
+ rsx! {{}}
+ }
+ })
+}
+
+#[component]
+pub fn RefreshToken(cx: Scope) -> Element {
+ let fermi_auth_token = use_atom_ref(cx, &FERMI_AUTH_TOKEN);
+ let fermi_auth_request = use_atom_ref(cx, &FERMI_AUTH_REQUEST);
+ let fermi_auth_token_read = fermi_auth_token.read().clone();
+ cx.render(match fermi_auth_token_read {
+ Some(fermi_auth_client_read) => match fermi_auth_client_read.refresh_token {
+ Some(refresh_token) => {
+ let fermi_auth_token = fermi_auth_token.to_owned();
+ let fermi_auth_request = fermi_auth_request.to_owned();
+ let client = cx.props.client.clone();
+ let exchange_refresh_token_spawn = move || {
+ cx.spawn({
+ async move {
+ let exchange_refresh_token =
+ exchange_refresh_token(client, refresh_token).await;
+ match exchange_refresh_token {
+ Ok(response_token) => {
+ AuthTokenState::persistent_set(
+ &fermi_auth_token,
+ Some(AuthTokenState {
+ id_token: response_token.id_token().cloned(),
+ refresh_token: response_token.refresh_token().cloned(),
+ }),
+ );
+ }
+ Err(_error) => {
+ AuthTokenState::persistent_set(
+ &fermi_auth_token,
+ Some(AuthTokenState::default()),
+ );
+ AuthRequestState::persistent_set(
+ &fermi_auth_request,
+ Some(AuthRequestState::default()),
+ );
+ }
+ }
+ }
+ })
+ };
+ exchange_refresh_token_spawn();
+ rsx! { div { "Refreshing session, please wait" } }
+ }
+ None => {
+ rsx! { div { "Id token expired and no refresh token found" } }
+ }
+ },
+ None => {
+ rsx! {{}}
+ }
+ })
+}
+
+#[component]
+pub fn LoadClient(cx: Scope) -> Element {
+ let init_client_future = use_future(cx, (), |_| async move { init_oidc_client().await });
+ let fermi_client: &UseAtomRef = use_atom_ref(cx, &FERMI_CLIENT);
+ cx.render(match init_client_future.value() {
+ Some(client_props) => match client_props {
+ Ok((client_id, client)) => {
+ *fermi_client.write() = ClientState {
+ oidc_client: Some(ClientProps::new(client_id.clone(), client.clone())),
+ };
+ rsx! {
+ div { "Client successfully loaded" }
+ Outlet:: {}
+ }
+ }
+ Err(error) => {
+ rsx! {
+ div { format!{"Failed to load client: {:?}", error} }
+ log::info!{"Failed to load client: {:?}", error},
+ Outlet:: {}
+ }
+ }
+ },
+ None => {
+ rsx! {
+ div {
+ div { "Loading client, please wait" }
+ Outlet:: {}
+ }
+ }
+ }
+ })
+}
+
+#[component]
+pub fn AuthHeader(cx: Scope) -> Element {
+ let auth_token = use_atom_ref(cx, &FERMI_AUTH_TOKEN);
+ let fermi_auth_request = use_atom_ref(cx, &FERMI_AUTH_REQUEST);
+ let fermi_client: &UseAtomRef = use_atom_ref(cx, &FERMI_CLIENT);
+ let client = fermi_client.read().oidc_client.clone();
+ let auth_request_read = fermi_auth_request.read().clone();
+ let auth_token_read = auth_token.read().clone();
+ cx.render(match (client, auth_request_read, auth_token_read) {
+ // We have everything we need to attempt to authenticate the user
+ (Some(client_props), Some(auth_request), Some(auth_token)) => {
+ match auth_request.auth_request {
+ Some(auth_request) => {
+ match auth_token.id_token {
+ Some(id_token) => {
+ match email(
+ client_props.client.clone(),
+ id_token.clone(),
+ auth_request.nonce.clone(),
+ ) {
+ Ok(email) => {
+ rsx! {
+ div {
+ div { email }
+ LogOut { client_id: client_props.client_id, client: client_props.client }
+ Outlet:: {}
+ }
+ }
+ }
+ // Id token failed to be decoded
+ Err(error) => match error {
+ // Id token failed to be decoded because it expired, we refresh it
+ openidconnect::ClaimsVerificationError::Expired(_message) => {
+ log::info!("Token expired");
+ rsx! {
+ div {
+ RefreshToken {client_id: client_props.client_id, client: client_props.client}
+ Outlet:: {}
+ }
+ }
+ }
+ // Other issue with token decoding
+ _ => {
+ log::info!("Other issue with token");
+ rsx! {
+ div {
+ div { error.to_string() }
+ Outlet:: {}
+ }
+ }
+ }
+ },
+ }
+ }
+ // User is not logged in
+ None => {
+ rsx! {
+ div {
+ Link { to: auth_request.authorize_url.clone(), "Log in" }
+ Outlet:: {}
+ }
+ }
+ }
+ }
+ }
+ None => {
+ let auth_request = authorize_url(client_props.client);
+ AuthRequestState::persistent_set(
+ fermi_auth_request,
+ Some(AuthRequestState {
+ auth_request: Some(auth_request),
+ }),
+ );
+ rsx! { div { "Loading nonce" } }
+ }
+ }
+ }
+ // Client is not initialized yet, we need it for everything
+ (None, _, _) => {
+ rsx! { LoadClient {} }
+ }
+ // We need everything loaded before doing anything
+ (_client, _auth_request, _auth_token) => {
+ rsx! {{}}
+ }
+ })
+}
diff --git a/examples/openid_connect_demo/src/views/home.rs b/examples/openid_connect_demo/src/views/home.rs
new file mode 100644
index 000000000..f39695302
--- /dev/null
+++ b/examples/openid_connect_demo/src/views/home.rs
@@ -0,0 +1,5 @@
+use dioxus::prelude::*;
+
+pub fn Home(cx: Scope) -> Element {
+ render! { div { "Hello world" } }
+}
diff --git a/examples/openid_connect_demo/src/views/login.rs b/examples/openid_connect_demo/src/views/login.rs
new file mode 100644
index 000000000..2583503de
--- /dev/null
+++ b/examples/openid_connect_demo/src/views/login.rs
@@ -0,0 +1,86 @@
+use crate::{
+ oidc::{token_response, AuthRequestState, AuthTokenState},
+ router::Route,
+ storage::PersistentWrite,
+ DIOXUS_FRONT_URL, FERMI_AUTH_REQUEST, FERMI_AUTH_TOKEN, FERMI_CLIENT,
+};
+use dioxus::prelude::*;
+use dioxus_router::prelude::{Link, NavigationTarget};
+use fermi::*;
+use openidconnect::{OAuth2TokenResponse, TokenResponse};
+
+#[component]
+pub fn Login(cx: Scope, query_string: String) -> Element {
+ let fermi_client = use_atom_ref(cx, &FERMI_CLIENT);
+ let fermi_auth_token = use_atom_ref(cx, &FERMI_AUTH_TOKEN);
+ let home_url: NavigationTarget = DIOXUS_FRONT_URL.parse().unwrap();
+ let fermi_auth_request = use_atom_ref(cx, &FERMI_AUTH_REQUEST);
+ let client = fermi_client.read().oidc_client.clone();
+ let auth_token_read = fermi_auth_token.read().clone();
+ cx.render(match (client, auth_token_read) {
+ (Some(client_props), Some(auth_token_read)) => {
+ match (auth_token_read.id_token, auth_token_read.refresh_token) {
+ (Some(_id_token), Some(_refresh_token)) => {
+ rsx! {
+ div { "Sign in successful" }
+ Link { to: home_url, "Go back home" }
+ }
+ }
+ // If the refresh token is set but not the id_token, there was an error, we just go back home and reset their value
+ (None, Some(_)) | (Some(_), None) => {
+ rsx! {
+ div { "Error while attempting to log in" }
+ Link {
+ to: home_url,
+ onclick: move |_| {
+ AuthTokenState::persistent_set(fermi_auth_token, Some(AuthTokenState::default()));
+ AuthRequestState::persistent_set(
+ fermi_auth_request,
+ Some(AuthRequestState::default()),
+ );
+ },
+ "Go back home"
+ }
+ }
+ }
+ (None, None) => {
+ let mut query_pairs = form_urlencoded::parse(query_string.as_bytes());
+ let code_pair = query_pairs.find(|(key, _value)| key == "code");
+ match code_pair {
+ Some((_key, code)) => {
+ let auth_code = code.to_string();
+ let token_response_spawn = move ||{
+ cx.spawn({
+ let fermi_auth_token = fermi_auth_token.to_owned();
+ async move {
+ let token_response_result = token_response(client_props.client, auth_code).await;
+ match token_response_result{
+ Ok(token_response) => {
+ let id_token = token_response.id_token().unwrap();
+ AuthTokenState::persistent_set(&fermi_auth_token, Some(AuthTokenState {
+ id_token: Some(id_token.clone()),
+ refresh_token: token_response.refresh_token().cloned()
+ }));
+ }
+ Err(error) => {
+ log::warn!{"{error}"};
+ }
+ }
+ }
+ })
+ };
+ token_response_spawn();
+ rsx!{ div {} }
+ }
+ None => {
+ rsx! { div { "No code provided" } }
+ }
+ }
+ }
+ }
+ }
+ (_, _) => {
+ rsx! {{}}
+ }
+ })
+}
diff --git a/examples/openid_connect_demo/src/views/mod.rs b/examples/openid_connect_demo/src/views/mod.rs
new file mode 100644
index 000000000..1b8e08a58
--- /dev/null
+++ b/examples/openid_connect_demo/src/views/mod.rs
@@ -0,0 +1,4 @@
+pub(crate) mod header;
+pub(crate) mod home;
+pub(crate) mod login;
+pub(crate) mod not_found;
diff --git a/examples/openid_connect_demo/src/views/not_found.rs b/examples/openid_connect_demo/src/views/not_found.rs
new file mode 100644
index 000000000..6321dc9fc
--- /dev/null
+++ b/examples/openid_connect_demo/src/views/not_found.rs
@@ -0,0 +1,7 @@
+use dioxus::prelude::*;
+
+#[component]
+pub fn NotFound(cx: Scope, route: Vec) -> Element {
+ let routes = route.join("");
+ render! {rsx! {div{routes}}}
+}
diff --git a/examples/query_segments_demo/src/main.rs b/examples/query_segments_demo/src/main.rs
index d9f5f83ef..aafcc0f43 100644
--- a/examples/query_segments_demo/src/main.rs
+++ b/examples/query_segments_demo/src/main.rs
@@ -35,7 +35,7 @@ impl Display for BlogQuerySegments {
}
}
-/// The query segment is anything that implements https://docs.rs/dioxus-router/latest/dioxus_router/routable/trait.FromQuery.html. You can implement that trait for a struct if you want to parse multiple query parameters.
+/// The query segment is anything that implements . You can implement that trait for a struct if you want to parse multiple query parameters.
impl FromQuery for BlogQuerySegments {
fn from_query(query: &str) -> Self {
let mut name = None;
diff --git a/examples/signals.rs b/examples/signals.rs
index bc627fa8f..0faac0af4 100644
--- a/examples/signals.rs
+++ b/examples/signals.rs
@@ -6,11 +6,17 @@ fn main() {
}
fn app(cx: Scope) -> Element {
+ let running = dioxus_signals::use_signal(cx, || true);
let mut count = dioxus_signals::use_signal(cx, || 0);
+ let saved_values = dioxus_signals::use_signal(cx, || vec![0.to_string()]);
+ // Signals can be used in async functions without an explicit clone since they're 'static and Copy
+ // Signals are backed by a runtime that is designed to deeply integrate with Dioxus apps
use_future!(cx, || async move {
loop {
- count += 1;
+ if running.value() {
+ count += 1;
+ }
tokio::time::sleep(Duration::from_millis(400)).await;
}
});
@@ -19,9 +25,25 @@ fn app(cx: Scope) -> Element {
h1 { "High-Five counter: {count}" }
button { onclick: move |_| count += 1, "Up high!" }
button { onclick: move |_| count -= 1, "Down low!" }
+ button { onclick: move |_| running.toggle(), "Toggle counter" }
+ button { onclick: move |_| saved_values.push(count.value().to_string()), "Save this value" }
+ button { onclick: move |_| saved_values.write().clear(), "Clear saved values" }
+ // We can do boolean operations on the current signal value
if count.value() > 5 {
rsx!{ h2 { "High five!" } }
}
+
+ // We can cleanly map signals with iterators
+ for value in saved_values.read().iter() {
+ h3 { "Saved value: {value}" }
+ }
+
+ // We can also use the signal value as a slice
+ if let [ref first, .., ref last] = saved_values.read().as_slice() {
+ rsx! { li { "First and last: {first}, {last}" } }
+ } else {
+ rsx! { "No saved values" }
+ }
})
}
diff --git a/examples/todomvc.rs b/examples/todomvc.rs
index 4b25507a5..9ec2dc228 100644
--- a/examples/todomvc.rs
+++ b/examples/todomvc.rs
@@ -24,8 +24,6 @@ pub struct TodoItem {
pub fn app(cx: Scope<()>) -> Element {
let todos = use_state(cx, im_rc::HashMap::::default);
let filter = use_state(cx, || FilterState::All);
- let draft = use_state(cx, || "".to_string());
- let todo_id = use_state(cx, || 0);
// Filter the todos based on the filter state
let mut filtered_todos = todos
@@ -47,42 +45,11 @@ pub fn app(cx: Scope<()>) -> Element {
let show_clear_completed = todos.values().any(|todo| todo.checked);
- let selected = |state| {
- if *filter == state {
- "selected"
- } else {
- "false"
- }
- };
-
cx.render(rsx! {
section { class: "todoapp",
style { include_str!("./assets/todomvc.css") }
- header { class: "header",
- h1 {"todos"}
- input {
- class: "new-todo",
- placeholder: "What needs to be done?",
- value: "{draft}",
- autofocus: "true",
- oninput: move |evt| {
- draft.set(evt.value.clone());
- },
- onkeydown: move |evt| {
- if evt.key() == Key::Enter && !draft.is_empty() {
- todos.make_mut().insert(
- **todo_id,
- TodoItem {
- id: **todo_id,
- checked: false,
- contents: draft.to_string(),
- },
- );
- *todo_id.make_mut() += 1;
- draft.set("".to_string());
- }
- }
- }
+ TodoHeader {
+ todos: todos,
}
section {
class: "main",
@@ -111,44 +78,56 @@ pub fn app(cx: Scope<()>) -> Element {
}))
}
(!todos.is_empty()).then(|| rsx!(
- footer { class: "footer",
- span { class: "todo-count",
- strong {"{active_todo_count} "}
- span {"{active_todo_text} left"}
- }
- ul { class: "filters",
- for (state, state_text, url) in [
- (FilterState::All, "All", "#/"),
- (FilterState::Active, "Active", "#/active"),
- (FilterState::Completed, "Completed", "#/completed"),
- ] {
- li {
- a {
- href: url,
- class: selected(state),
- onclick: move |_| filter.set(state),
- prevent_default: "onclick",
- state_text
- }
- }
- }
- }
- show_clear_completed.then(|| rsx!(
- button {
- class: "clear-completed",
- onclick: move |_| todos.make_mut().retain(|_, todo| !todo.checked),
- "Clear completed"
- }
- ))
+ ListFooter {
+ active_todo_count: active_todo_count,
+ active_todo_text: active_todo_text,
+ show_clear_completed: show_clear_completed,
+ todos: todos,
+ filter: filter,
}
))
}
}
- footer { class: "info",
- p { "Double-click to edit a todo" }
- p { "Created by ", a { href: "http://github.com/jkelleyrtp/", "jkelleyrtp" }}
- p { "Part of ", a { href: "http://todomvc.com", "TodoMVC" }}
+ PageFooter {}
+ })
+}
+
+#[derive(Props)]
+pub struct TodoHeaderProps<'a> {
+ todos: &'a UseState>,
+}
+
+pub fn TodoHeader<'a>(cx: Scope<'a, TodoHeaderProps<'a>>) -> Element {
+ let draft = use_state(cx, || "".to_string());
+ let todo_id = use_state(cx, || 0);
+
+ cx.render(rsx! {
+ header { class: "header",
+ h1 {"todos"}
+ input {
+ class: "new-todo",
+ placeholder: "What needs to be done?",
+ value: "{draft}",
+ autofocus: "true",
+ oninput: move |evt| {
+ draft.set(evt.value.clone());
+ },
+ onkeydown: move |evt| {
+ if evt.key() == Key::Enter && !draft.is_empty() {
+ cx.props.todos.make_mut().insert(
+ **todo_id,
+ TodoItem {
+ id: **todo_id,
+ checked: false,
+ contents: draft.to_string(),
+ },
+ );
+ *todo_id.make_mut() += 1;
+ draft.set("".to_string());
+ }
+ }
}
+ }
})
}
@@ -209,3 +188,70 @@ pub fn TodoEntry<'a>(cx: Scope<'a, TodoEntryProps<'a>>) -> Element {
}
})
}
+
+#[derive(Props)]
+pub struct ListFooterProps<'a> {
+ todos: &'a UseState>,
+ active_todo_count: usize,
+ active_todo_text: &'a str,
+ show_clear_completed: bool,
+ filter: &'a UseState,
+}
+
+pub fn ListFooter<'a>(cx: Scope<'a, ListFooterProps<'a>>) -> Element {
+ let active_todo_count = cx.props.active_todo_count;
+ let active_todo_text = cx.props.active_todo_text;
+
+ let selected = |state| {
+ if *cx.props.filter == state {
+ "selected"
+ } else {
+ "false"
+ }
+ };
+
+ cx.render(rsx! {
+ footer { class: "footer",
+ span { class: "todo-count",
+ strong {"{active_todo_count} "}
+ span {"{active_todo_text} left"}
+ }
+ ul { class: "filters",
+ for (state, state_text, url) in [
+ (FilterState::All, "All", "#/"),
+ (FilterState::Active, "Active", "#/active"),
+ (FilterState::Completed, "Completed", "#/completed"),
+ ] {
+ li {
+ a {
+ href: url,
+ class: selected(state),
+ onclick: move |_| cx.props.filter.set(state),
+ prevent_default: "onclick",
+ state_text
+ }
+ }
+ }
+ }
+ if cx.props.show_clear_completed {
+ cx.render(rsx! {
+ button {
+ class: "clear-completed",
+ onclick: move |_| cx.props.todos.make_mut().retain(|_, todo| !todo.checked),
+ "Clear completed"
+ }
+ })
+ }
+ }
+ })
+}
+
+pub fn PageFooter(cx: Scope) -> Element {
+ cx.render(rsx! {
+ footer { class: "info",
+ p { "Double-click to edit a todo" }
+ p { "Created by ", a { href: "http://github.com/jkelleyrtp/", "jkelleyrtp" }}
+ p { "Part of ", a { href: "http://todomvc.com", "TodoMVC" }}
+ }
+ })
+}
diff --git a/packages/autofmt/src/lib.rs b/packages/autofmt/src/lib.rs
index 8ec33f0f0..64a342885 100644
--- a/packages/autofmt/src/lib.rs
+++ b/packages/autofmt/src/lib.rs
@@ -1,3 +1,7 @@
+#![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")]
+
use std::fmt::{Display, Write};
use crate::writer::*;
diff --git a/packages/check/Cargo.toml b/packages/check/Cargo.toml
index 90422780a..52b98cc44 100644
--- a/packages/check/Cargo.toml
+++ b/packages/check/Cargo.toml
@@ -11,13 +11,10 @@ keywords = ["dom", "ui", "gui", "react"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-dioxus-rsx = { workspace = true }
proc-macro2 = { version = "1.0.6", features = ["span-locations"] }
quote = "1.0"
syn = { version = "1.0.11", features = ["full", "extra-traits", "visit"] }
-serde = { version = "1.0.136", features = ["derive"] }
owo-colors = { version = "3.5.0", features = ["supports-colors"] }
-prettyplease = { workspace = true }
[dev-dependencies]
indoc = "2.0.3"
diff --git a/packages/check/README.md b/packages/check/README.md
index 0bb6ce0a4..6375a8316 100644
--- a/packages/check/README.md
+++ b/packages/check/README.md
@@ -6,7 +6,7 @@
[![Discord chat][discord-badge]][discord-url]
[crates-badge]: https://img.shields.io/crates/v/dioxus-autofmt.svg
-[crates-url]: https://crates.io/crates/dioxus-autofmt
+[crates-url]: https://crates.io/crates/dioxus-check
[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
[mit-url]: https://github.com/dioxuslabs/dioxus/blob/master/LICENSE
[actions-badge]: https://github.com/dioxuslabs/dioxus/actions/workflows/main.yml/badge.svg
@@ -16,7 +16,7 @@
[Website](https://dioxuslabs.com) |
[Guides](https://dioxuslabs.com/learn/0.4/) |
-[API Docs](https://docs.rs/dioxus-autofmt/latest/dioxus_autofmt) |
+[API Docs](https://docs.rs/dioxus-check) |
[Chat](https://discord.gg/XgGxMSkvUM)
## Overview
diff --git a/packages/check/src/lib.rs b/packages/check/src/lib.rs
index 3870fb610..43a164514 100644
--- a/packages/check/src/lib.rs
+++ b/packages/check/src/lib.rs
@@ -1,3 +1,7 @@
+#![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")]
+
mod check;
mod issues;
mod metadata;
diff --git a/packages/cli/.github/workflows/build.yml b/packages/cli/.github/workflows/build.yml
deleted file mode 100644
index f0765e951..000000000
--- a/packages/cli/.github/workflows/build.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-# .github/workflows/build.yml
-
-on:
- release:
- types: [created]
-
-jobs:
- release:
- name: release ${{ matrix.target }}
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- include:
- - target: x86_64-unknown-linux-gnu
- archive: tar.gz tar.xz
- - target: x86_64-unknown-linux-musl
- archive: tar.gz tar.xz
- - target: x86_64-apple-darwin
- archive: tar.gz tar.xz
- - target: x86_64-pc-windows-gnu
- archive: zip
-
- steps:
- - uses: actions/checkout@master
- - name: Compile and release
- uses: rust-build/rust-build.action@latest
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- RUSTTARGET: ${{ matrix.target }}
- ARCHIVE_TYPES: ${{ matrix.archive }}
diff --git a/packages/cli/.github/workflows/docs.yml b/packages/cli/.github/workflows/docs.yml
deleted file mode 100644
index d8765cac8..000000000
--- a/packages/cli/.github/workflows/docs.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-name: github pages
-
-on:
- push:
- paths:
- - docs/**
- branches:
- - master
-
-jobs:
- deploy:
- runs-on: ubuntu-20.04
- concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- steps:
- - uses: actions/checkout@v2
-
- - name: Setup mdBook
- uses: peaceiris/actions-mdbook@v1
- with:
- mdbook-version: '0.4.10'
- # mdbook-version: 'latest'
-
- - run: cd docs && mdbook build
-
- - name: Deploy 🚀
- uses: JamesIves/github-pages-deploy-action@v4.2.3
- with:
- branch: gh-pages # The branch the action should deploy to.
- folder: docs/book # The folder the action should deploy.
- target-folder: docs/nightly/cli
- repository-name: dioxuslabs/docsite
- clean: false
- token: ${{ secrets.DEPLOY_KEY }} # let's pretend I don't need it for now
diff --git a/packages/cli/.github/workflows/main.yml b/packages/cli/.github/workflows/main.yml
deleted file mode 100644
index b22f78eae..000000000
--- a/packages/cli/.github/workflows/main.yml
+++ /dev/null
@@ -1,52 +0,0 @@
-on: [push, pull_request]
-
-name: Rust CI
-
-jobs:
- check:
- name: Check
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - name: Install Rust
- uses: dtolnay/rust-toolchain@stable
- - uses: Swatinem/rust-cache@v1
- - run: cargo check
-
- test:
- name: Test Suite
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - name: Install Rust
- uses: dtolnay/rust-toolchain@stable
- - uses: Swatinem/rust-cache@v1
- - run: cargo test
-
- fmt:
- name: Rustfmt
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - name: Install Rust
- uses: dtolnay/rust-toolchain@stable
- - uses: Swatinem/rust-cache@v1
- - run: rustup component add rustfmt
- - run: cargo fmt --all -- --check
-
- # clippy:
- # name: Clippy
- # runs-on: ubuntu-latest
- # steps:
- # - uses: actions/checkout@v2
- # - uses: actions-rs/toolchain@v1
- # with:
- # profile: minimal
- # toolchain: stable
- # override: true
- # - uses: Swatinem/rust-cache@v1
- # - run: rustup component add clippy
- # - uses: actions-rs/cargo@v1
- # with:
- # command: clippy
- # args: -- -D warnings
diff --git a/packages/cli/Cargo.lock b/packages/cli/Cargo.lock
deleted file mode 100644
index 707a02b6e..000000000
--- a/packages/cli/Cargo.lock
+++ /dev/null
@@ -1,4778 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "addr2line"
-version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"
-dependencies = [
- "gimli",
-]
-
-[[package]]
-name = "adler"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
-
-[[package]]
-name = "aes"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
-dependencies = [
- "cfg-if",
- "cipher",
- "cpufeatures",
-]
-
-[[package]]
-name = "ahash"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
-dependencies = [
- "getrandom 0.2.10",
- "once_cell",
- "version_check",
-]
-
-[[package]]
-name = "ahash"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
-dependencies = [
- "cfg-if",
- "const-random",
- "getrandom 0.2.10",
- "once_cell",
- "version_check",
-]
-
-[[package]]
-name = "aho-corasick"
-version = "0.7.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "aho-corasick"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "aligned"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80a21b9440a626c7fc8573a9e3d3a06b75c7c97754c2949bc7857b90353ca655"
-dependencies = [
- "as-slice",
-]
-
-[[package]]
-name = "alloc-no-stdlib"
-version = "2.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
-
-[[package]]
-name = "alloc-stdlib"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
-dependencies = [
- "alloc-no-stdlib",
-]
-
-[[package]]
-name = "android-tzdata"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
-
-[[package]]
-name = "android_system_properties"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "anstream"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163"
-dependencies = [
- "anstyle",
- "anstyle-parse",
- "anstyle-query",
- "anstyle-wincon",
- "colorchoice",
- "is-terminal",
- "utf8parse",
-]
-
-[[package]]
-name = "anstyle"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd"
-
-[[package]]
-name = "anstyle-parse"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
-dependencies = [
- "utf8parse",
-]
-
-[[package]]
-name = "anstyle-query"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
-dependencies = [
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "anstyle-wincon"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
-dependencies = [
- "anstyle",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "anyhow"
-version = "1.0.71"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
-
-[[package]]
-name = "anymap2"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c"
-
-[[package]]
-name = "arrayref"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
-
-[[package]]
-name = "arrayvec"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
-
-[[package]]
-name = "as-slice"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516"
-dependencies = [
- "stable_deref_trait",
-]
-
-[[package]]
-name = "async-compression"
-version = "0.3.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a"
-dependencies = [
- "brotli",
- "flate2",
- "futures-core",
- "memchr",
- "pin-project-lite",
- "tokio",
-]
-
-[[package]]
-name = "async-trait"
-version = "0.1.68"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-dependencies = [
- "hermit-abi 0.1.19",
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "autocfg"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
-
-[[package]]
-name = "axum"
-version = "0.5.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acee9fd5073ab6b045a275b3e709c163dd36c90685219cb21804a147b58dba43"
-dependencies = [
- "async-trait",
- "axum-core",
- "base64 0.13.1",
- "bitflags",
- "bytes",
- "futures-util",
- "headers",
- "http",
- "http-body",
- "hyper",
- "itoa",
- "matchit",
- "memchr",
- "mime",
- "percent-encoding",
- "pin-project-lite",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "sha-1",
- "sync_wrapper",
- "tokio",
- "tokio-tungstenite",
- "tower",
- "tower-http 0.3.5",
- "tower-layer",
- "tower-service",
-]
-
-[[package]]
-name = "axum-core"
-version = "0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37e5939e02c56fecd5c017c37df4238c0a839fa76b7f97acdd7efb804fd181cc"
-dependencies = [
- "async-trait",
- "bytes",
- "futures-util",
- "http",
- "http-body",
- "mime",
- "tower-layer",
- "tower-service",
-]
-
-[[package]]
-name = "backtrace"
-version = "0.3.67"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca"
-dependencies = [
- "addr2line",
- "cc",
- "cfg-if",
- "libc",
- "miniz_oxide 0.6.2",
- "object",
- "rustc-demangle",
-]
-
-[[package]]
-name = "base64"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
-dependencies = [
- "byteorder",
- "safemem",
-]
-
-[[package]]
-name = "base64"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
-
-[[package]]
-name = "base64"
-version = "0.21.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
-
-[[package]]
-name = "base64ct"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
-
-[[package]]
-name = "binary-install"
-version = "0.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b5bc5f8c50dd6a80d0b303ddab79f42ddcb52fd43d68107ecf622c551fd4cd4"
-dependencies = [
- "curl",
- "dirs 1.0.5",
- "failure",
- "flate2",
- "hex 0.3.2",
- "is_executable",
- "siphasher",
- "tar",
- "zip 0.5.13",
-]
-
-[[package]]
-name = "bitflags"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
-
-[[package]]
-name = "blake2b_simd"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
-dependencies = [
- "arrayref",
- "arrayvec",
- "constant_time_eq",
-]
-
-[[package]]
-name = "block-buffer"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
-dependencies = [
- "generic-array",
-]
-
-[[package]]
-name = "brotli"
-version = "3.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68"
-dependencies = [
- "alloc-no-stdlib",
- "alloc-stdlib",
- "brotli-decompressor",
-]
-
-[[package]]
-name = "brotli-decompressor"
-version = "2.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744"
-dependencies = [
- "alloc-no-stdlib",
- "alloc-stdlib",
-]
-
-[[package]]
-name = "bstr"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "bstr"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5"
-dependencies = [
- "memchr",
- "once_cell",
- "regex-automata",
- "serde",
-]
-
-[[package]]
-name = "btoi"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9dd6407f73a9b8b6162d8a2ef999fe6afd7cc15902ebf42c5cd296addf17e0ad"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
-name = "bumpalo"
-version = "3.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
-
-[[package]]
-name = "bumpslab"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e5816c875b50b9866d759fa24d46159dccab0d7942c0ccbfd700b4f45dd961e"
-dependencies = [
- "bumpalo",
-]
-
-[[package]]
-name = "byteorder"
-version = "1.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
-
-[[package]]
-name = "bytes"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
-
-[[package]]
-name = "bzip2"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
-dependencies = [
- "bzip2-sys",
- "libc",
-]
-
-[[package]]
-name = "bzip2-sys"
-version = "0.1.11+1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
-dependencies = [
- "cc",
- "libc",
- "pkg-config",
-]
-
-[[package]]
-name = "camino"
-version = "1.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "cargo-generate"
-version = "0.18.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7b2f627381dc7523340c606559dddf6083cb2e6134368381da5778638f906d8"
-dependencies = [
- "anyhow",
- "clap",
- "console",
- "dialoguer",
- "env_logger",
- "git2",
- "gix-config",
- "heck 0.4.1",
- "home",
- "ignore",
- "indicatif",
- "liquid",
- "liquid-core",
- "liquid-derive",
- "liquid-lib",
- "log",
- "names",
- "paste",
- "path-absolutize",
- "regex",
- "remove_dir_all",
- "rhai",
- "sanitize-filename",
- "semver",
- "serde",
- "tempfile",
- "thiserror",
- "toml 0.7.5",
- "walkdir",
-]
-
-[[package]]
-name = "cargo-platform"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "cargo_metadata"
-version = "0.15.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a"
-dependencies = [
- "camino",
- "cargo-platform",
- "semver",
- "serde",
- "serde_json",
- "thiserror",
-]
-
-[[package]]
-name = "cargo_toml"
-version = "0.11.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e72c3ff59e3b7d24630206bb63a73af65da4ed5df1f76ee84dfafb9fee2ba60e"
-dependencies = [
- "serde",
- "serde_derive",
- "toml 0.5.11",
-]
-
-[[package]]
-name = "cc"
-version = "1.0.79"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
-dependencies = [
- "jobserver",
-]
-
-[[package]]
-name = "cfg-expr"
-version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bbc13bf6290a6b202cc3efb36f7ec2b739a80634215630c8053a313edf6abef"
-dependencies = [
- "smallvec",
-]
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "chrono"
-version = "0.4.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
-dependencies = [
- "android-tzdata",
- "iana-time-zone",
- "js-sys",
- "num-traits",
- "time 0.1.45",
- "wasm-bindgen",
- "winapi",
-]
-
-[[package]]
-name = "cipher"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
-dependencies = [
- "crypto-common",
- "inout",
-]
-
-[[package]]
-name = "clap"
-version = "4.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938"
-dependencies = [
- "clap_builder",
- "clap_derive",
- "once_cell",
-]
-
-[[package]]
-name = "clap_builder"
-version = "4.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd"
-dependencies = [
- "anstream",
- "anstyle",
- "bitflags",
- "clap_lex",
- "strsim",
-]
-
-[[package]]
-name = "clap_derive"
-version = "4.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4"
-dependencies = [
- "heck 0.4.1",
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "clap_lex"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1"
-
-[[package]]
-name = "colorchoice"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
-
-[[package]]
-name = "colored"
-version = "1.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59"
-dependencies = [
- "atty",
- "lazy_static",
- "winapi",
-]
-
-[[package]]
-name = "colored"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
-dependencies = [
- "atty",
- "lazy_static",
- "winapi",
-]
-
-[[package]]
-name = "console"
-version = "0.15.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
-dependencies = [
- "encode_unicode",
- "lazy_static",
- "libc",
- "unicode-width",
- "windows-sys 0.45.0",
-]
-
-[[package]]
-name = "const-random"
-version = "0.1.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "368a7a772ead6ce7e1de82bfb04c485f3db8ec744f72925af5735e29a22cc18e"
-dependencies = [
- "const-random-macro",
- "proc-macro-hack",
-]
-
-[[package]]
-name = "const-random-macro"
-version = "0.1.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d7d6ab3c3a2282db210df5f02c4dab6e0a7057af0fb7ebd4070f30fe05c0ddb"
-dependencies = [
- "getrandom 0.2.10",
- "once_cell",
- "proc-macro-hack",
- "tiny-keccak",
-]
-
-[[package]]
-name = "constant_time_eq"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
-
-[[package]]
-name = "convert_case"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8"
-
-[[package]]
-name = "core-foundation"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "core-foundation-sys"
-version = "0.8.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
-
-[[package]]
-name = "cpufeatures"
-version = "0.2.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "crc32fast"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "crunchy"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
-
-[[package]]
-name = "crypto-common"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
-dependencies = [
- "generic-array",
- "typenum",
-]
-
-[[package]]
-name = "ctrlc"
-version = "3.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e"
-dependencies = [
- "nix",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "curl"
-version = "0.4.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22"
-dependencies = [
- "curl-sys",
- "libc",
- "openssl-probe",
- "openssl-sys",
- "schannel",
- "socket2 0.4.9",
- "winapi",
-]
-
-[[package]]
-name = "curl-sys"
-version = "0.4.63+curl-8.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aeb0fef7046022a1e2ad67a004978f0e3cacb9e3123dc62ce768f92197b771dc"
-dependencies = [
- "cc",
- "libc",
- "libz-sys",
- "openssl-sys",
- "pkg-config",
- "vcpkg",
- "winapi",
-]
-
-[[package]]
-name = "cvt"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2ae9bf77fbf2d39ef573205d554d87e86c12f1994e9ea335b0651b9b278bcf1"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "darling"
-version = "0.20.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944"
-dependencies = [
- "darling_core",
- "darling_macro",
-]
-
-[[package]]
-name = "darling_core"
-version = "0.20.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb"
-dependencies = [
- "fnv",
- "ident_case",
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "darling_macro"
-version = "0.20.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a"
-dependencies = [
- "darling_core",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "data-encoding"
-version = "2.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
-
-[[package]]
-name = "dialoguer"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87"
-dependencies = [
- "console",
- "shell-words",
- "tempfile",
- "zeroize",
-]
-
-[[package]]
-name = "digest"
-version = "0.10.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
-dependencies = [
- "block-buffer",
- "crypto-common",
- "subtle",
-]
-
-[[package]]
-name = "dioxus-autofmt"
-version = "0.3.0"
-source = "git+https://github.com/DioxusLabs/dioxus#11c9abcf7ce731ccb4a44c52de383c090ab319af"
-dependencies = [
- "dioxus-rsx",
- "prettier-please",
- "proc-macro2",
- "quote",
- "serde",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "dioxus-cli"
-version = "0.3.1"
-dependencies = [
- "anyhow",
- "atty",
- "axum",
- "binary-install",
- "cargo-generate",
- "cargo_metadata",
- "cargo_toml",
- "chrono",
- "clap",
- "colored 2.0.0",
- "convert_case",
- "ctrlc",
- "dioxus-autofmt",
- "dioxus-core",
- "dioxus-html",
- "dioxus-rsx",
- "dirs 4.0.0",
- "fern",
- "flate2",
- "fs_extra",
- "futures",
- "gitignore",
- "headers",
- "html_parser",
- "hyper",
- "hyper-rustls 0.23.2",
- "indicatif",
- "lazy_static",
- "log",
- "mlua",
- "notify",
- "open",
- "proc-macro2",
- "regex",
- "reqwest",
- "rsx-rosetta",
- "serde",
- "serde_json",
- "subprocess",
- "syn 1.0.109",
- "tar",
- "thiserror",
- "tokio",
- "toml 0.5.11",
- "toml_edit",
- "tower",
- "tower-http 0.2.5",
- "walkdir",
- "wasm-bindgen-cli-support",
- "zip 0.6.6",
-]
-
-[[package]]
-name = "dioxus-core"
-version = "0.3.3"
-source = "git+https://github.com/DioxusLabs/dioxus#11c9abcf7ce731ccb4a44c52de383c090ab319af"
-dependencies = [
- "bumpalo",
- "bumpslab",
- "futures-channel",
- "futures-util",
- "indexmap 1.9.3",
- "log",
- "longest-increasing-subsequence",
- "rustc-hash",
- "serde",
- "slab",
- "smallbox",
-]
-
-[[package]]
-name = "dioxus-html"
-version = "0.3.1"
-source = "git+https://github.com/DioxusLabs/dioxus#11c9abcf7ce731ccb4a44c52de383c090ab319af"
-dependencies = [
- "async-trait",
- "dioxus-core",
- "dioxus-rsx",
- "enumset",
- "euclid",
- "keyboard-types",
- "serde",
- "serde-value",
- "serde_repr",
-]
-
-[[package]]
-name = "dioxus-rsx"
-version = "0.0.3"
-source = "git+https://github.com/DioxusLabs/dioxus#11c9abcf7ce731ccb4a44c52de383c090ab319af"
-dependencies = [
- "dioxus-core",
- "internment",
- "krates",
- "proc-macro2",
- "quote",
- "serde",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "dirs"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
-dependencies = [
- "libc",
- "redox_users 0.3.5",
- "winapi",
-]
-
-[[package]]
-name = "dirs"
-version = "4.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
-dependencies = [
- "dirs-sys",
-]
-
-[[package]]
-name = "dirs-sys"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
-dependencies = [
- "libc",
- "redox_users 0.4.3",
- "winapi",
-]
-
-[[package]]
-name = "doc-comment"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
-
-[[package]]
-name = "either"
-version = "1.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
-
-[[package]]
-name = "encode_unicode"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
-
-[[package]]
-name = "encoding_rs"
-version = "0.8.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "enum-as-inner"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116"
-dependencies = [
- "heck 0.4.1",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "enumset"
-version = "1.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb"
-dependencies = [
- "enumset_derive",
-]
-
-[[package]]
-name = "enumset_derive"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af"
-dependencies = [
- "darling",
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "env_logger"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
-dependencies = [
- "humantime",
- "is-terminal",
- "log",
- "regex",
- "termcolor",
-]
-
-[[package]]
-name = "equivalent"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1"
-
-[[package]]
-name = "errno"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
-dependencies = [
- "errno-dragonfly",
- "libc",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "errno-dragonfly"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
-dependencies = [
- "cc",
- "libc",
-]
-
-[[package]]
-name = "euclid"
-version = "0.22.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87f253bc5c813ca05792837a0ff4b3a580336b224512d48f7eda1d7dd9210787"
-dependencies = [
- "num-traits",
- "serde",
-]
-
-[[package]]
-name = "failure"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
-dependencies = [
- "backtrace",
- "failure_derive",
-]
-
-[[package]]
-name = "failure_derive"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
- "synstructure",
-]
-
-[[package]]
-name = "fastrand"
-version = "1.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
-dependencies = [
- "instant",
-]
-
-[[package]]
-name = "fern"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee"
-dependencies = [
- "colored 1.9.3",
- "log",
-]
-
-[[package]]
-name = "filetime"
-version = "0.2.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153"
-dependencies = [
- "cfg-if",
- "libc",
- "redox_syscall 0.2.16",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "fixedbitset"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
-
-[[package]]
-name = "flate2"
-version = "1.0.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
-dependencies = [
- "crc32fast",
- "miniz_oxide 0.7.1",
-]
-
-[[package]]
-name = "fnv"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
-
-[[package]]
-name = "foreign-types"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
-dependencies = [
- "foreign-types-shared",
-]
-
-[[package]]
-name = "foreign-types-shared"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
-
-[[package]]
-name = "form_urlencoded"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
-dependencies = [
- "percent-encoding",
-]
-
-[[package]]
-name = "fs_at"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15550ecca96ea332ec143fb450701074143b70d358e50b32b1f847ccff2e1cf7"
-dependencies = [
- "aligned",
- "cfg-if",
- "cvt",
- "libc",
- "nix",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "fs_extra"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
-
-[[package]]
-name = "fsevent-sys"
-version = "4.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "futures"
-version = "0.3.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-channel"
-version = "0.3.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
-dependencies = [
- "futures-core",
- "futures-sink",
-]
-
-[[package]]
-name = "futures-core"
-version = "0.3.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
-
-[[package]]
-name = "futures-executor"
-version = "0.3.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
-dependencies = [
- "futures-core",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-io"
-version = "0.3.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
-
-[[package]]
-name = "futures-macro"
-version = "0.3.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "futures-sink"
-version = "0.3.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
-
-[[package]]
-name = "futures-task"
-version = "0.3.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
-
-[[package]]
-name = "futures-util"
-version = "0.3.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-macro",
- "futures-sink",
- "futures-task",
- "memchr",
- "pin-project-lite",
- "pin-utils",
- "slab",
-]
-
-[[package]]
-name = "generic-array"
-version = "0.14.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
-dependencies = [
- "typenum",
- "version_check",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.1.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
-dependencies = [
- "cfg-if",
- "libc",
- "wasi 0.9.0+wasi-snapshot-preview1",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.2.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
-dependencies = [
- "cfg-if",
- "libc",
- "wasi 0.11.0+wasi-snapshot-preview1",
-]
-
-[[package]]
-name = "gimli"
-version = "0.27.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
-
-[[package]]
-name = "git2"
-version = "0.17.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b989d6a7ca95a362cf2cfc5ad688b3a467be1f87e480b8dad07fee8c79b0044"
-dependencies = [
- "bitflags",
- "libc",
- "libgit2-sys",
- "log",
- "openssl-probe",
- "openssl-sys",
- "url",
-]
-
-[[package]]
-name = "gitignore"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d051488d9a601181a9b90c9ad8ae7e8251d642ddd2463008f2f5019d255bd89"
-dependencies = [
- "glob",
-]
-
-[[package]]
-name = "gix-actor"
-version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc22b0cdc52237667c301dd7cdc6ead8f8f73c9f824e9942c8ebd6b764f6c0bf"
-dependencies = [
- "bstr 1.5.0",
- "btoi",
- "gix-date",
- "itoa",
- "nom",
- "thiserror",
-]
-
-[[package]]
-name = "gix-config"
-version = "0.20.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fbad5ce54a8fc997acc50febd89ec80fa6e97cb7f8d0654cb229936407489d8"
-dependencies = [
- "bstr 1.5.0",
- "gix-config-value",
- "gix-features 0.28.1",
- "gix-glob",
- "gix-path",
- "gix-ref",
- "gix-sec",
- "log",
- "memchr",
- "nom",
- "once_cell",
- "smallvec",
- "thiserror",
- "unicode-bom",
-]
-
-[[package]]
-name = "gix-config-value"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d09154c0c8677e4da0ec35e896f56ee3e338e741b9599fae06075edd83a4081c"
-dependencies = [
- "bitflags",
- "bstr 1.5.0",
- "gix-path",
- "libc",
- "thiserror",
-]
-
-[[package]]
-name = "gix-date"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b96271912ce39822501616f177dea7218784e6c63be90d5f36322ff3a722aae2"
-dependencies = [
- "bstr 1.5.0",
- "itoa",
- "thiserror",
- "time 0.3.22",
-]
-
-[[package]]
-name = "gix-features"
-version = "0.28.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b76f9a80f6dd7be66442ae86e1f534effad9546676a392acc95e269d0c21c22"
-dependencies = [
- "gix-hash 0.10.4",
- "libc",
- "sha1_smol",
- "walkdir",
-]
-
-[[package]]
-name = "gix-features"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf69b0f5c701cc3ae22d3204b671907668f6437ca88862d355eaf9bc47a4f897"
-dependencies = [
- "gix-hash 0.11.3",
- "libc",
-]
-
-[[package]]
-name = "gix-fs"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b37a1832f691fdc09910bd267f9a2e413737c1f9ec68c6e31f9e802616278a9"
-dependencies = [
- "gix-features 0.29.0",
-]
-
-[[package]]
-name = "gix-glob"
-version = "0.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93e43efd776bc543f46f0fd0ca3d920c37af71a764a16f2aebd89765e9ff2993"
-dependencies = [
- "bitflags",
- "bstr 1.5.0",
-]
-
-[[package]]
-name = "gix-hash"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a258595457bc192d1f1c59d0d168a1e34e2be9b97a614e14995416185de41a7"
-dependencies = [
- "hex 0.4.3",
- "thiserror",
-]
-
-[[package]]
-name = "gix-hash"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0dd58cdbe7ffa4032fc111864c80d5f8cecd9a2c9736c97ae7e5be834188272"
-dependencies = [
- "hex 0.4.3",
- "thiserror",
-]
-
-[[package]]
-name = "gix-lock"
-version = "5.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c693d7f05730fa74a7c467150adc7cea393518410c65f0672f80226b8111555"
-dependencies = [
- "gix-tempfile",
- "gix-utils",
- "thiserror",
-]
-
-[[package]]
-name = "gix-object"
-version = "0.28.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8df068db9180ee935fbb70504848369e270bdcb576b05c0faa8b9fd3b86fc017"
-dependencies = [
- "bstr 1.5.0",
- "btoi",
- "gix-actor",
- "gix-features 0.28.1",
- "gix-hash 0.10.4",
- "gix-validate",
- "hex 0.4.3",
- "itoa",
- "nom",
- "smallvec",
- "thiserror",
-]
-
-[[package]]
-name = "gix-path"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32370dce200bb951df013e03dff35b4233fc7a89458642b047629b91734a7e19"
-dependencies = [
- "bstr 1.5.0",
- "thiserror",
-]
-
-[[package]]
-name = "gix-ref"
-version = "0.27.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4e909396ed3b176823991ccc391c276ae2a015e54edaafa3566d35123cfac9d"
-dependencies = [
- "gix-actor",
- "gix-features 0.28.1",
- "gix-hash 0.10.4",
- "gix-lock",
- "gix-object",
- "gix-path",
- "gix-tempfile",
- "gix-validate",
- "memmap2",
- "nom",
- "thiserror",
-]
-
-[[package]]
-name = "gix-sec"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8ffa5bf0772f9b01de501c035b6b084cf9b8bb07dec41e3afc6a17336a65f47"
-dependencies = [
- "bitflags",
- "dirs 4.0.0",
- "gix-path",
- "libc",
- "windows 0.43.0",
-]
-
-[[package]]
-name = "gix-tempfile"
-version = "5.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d71a0d32f34e71e86586124225caefd78dabc605d0486de580d717653addf182"
-dependencies = [
- "gix-fs",
- "libc",
- "once_cell",
- "parking_lot",
- "tempfile",
-]
-
-[[package]]
-name = "gix-utils"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ca284c260845bc0724050aec59c7a596407678342614cdf5a1d69e044f29a36"
-dependencies = [
- "fastrand",
-]
-
-[[package]]
-name = "gix-validate"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d092b594c8af00a3a31fe526d363ee8a51a6f29d8496cdb991ed2f01ec0ec13"
-dependencies = [
- "bstr 1.5.0",
- "thiserror",
-]
-
-[[package]]
-name = "glob"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
-
-[[package]]
-name = "globset"
-version = "0.4.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc"
-dependencies = [
- "aho-corasick 0.7.20",
- "bstr 1.5.0",
- "fnv",
- "log",
- "regex",
-]
-
-[[package]]
-name = "h2"
-version = "0.3.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049"
-dependencies = [
- "bytes",
- "fnv",
- "futures-core",
- "futures-sink",
- "futures-util",
- "http",
- "indexmap 1.9.3",
- "slab",
- "tokio",
- "tokio-util",
- "tracing",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-dependencies = [
- "ahash 0.7.6",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
-
-[[package]]
-name = "headers"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584"
-dependencies = [
- "base64 0.13.1",
- "bitflags",
- "bytes",
- "headers-core",
- "http",
- "httpdate",
- "mime",
- "sha1",
-]
-
-[[package]]
-name = "headers-core"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
-dependencies = [
- "http",
-]
-
-[[package]]
-name = "heck"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
-dependencies = [
- "unicode-segmentation",
-]
-
-[[package]]
-name = "heck"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
-
-[[package]]
-name = "hex"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
-
-[[package]]
-name = "hex"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
-
-[[package]]
-name = "hmac"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
-dependencies = [
- "digest",
-]
-
-[[package]]
-name = "home"
-version = "0.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
-dependencies = [
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "hostname"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
-dependencies = [
- "libc",
- "match_cfg",
- "winapi",
-]
-
-[[package]]
-name = "html_parser"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec016cabcf7c9c48f9d5fdc6b03f273585bfce640a0f47a69552039e92b1959a"
-dependencies = [
- "pest",
- "pest_derive",
- "serde",
- "serde_derive",
- "serde_json",
- "thiserror",
-]
-
-[[package]]
-name = "http"
-version = "0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
-dependencies = [
- "bytes",
- "fnv",
- "itoa",
-]
-
-[[package]]
-name = "http-body"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
-dependencies = [
- "bytes",
- "http",
- "pin-project-lite",
-]
-
-[[package]]
-name = "http-range-header"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
-
-[[package]]
-name = "httparse"
-version = "1.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
-
-[[package]]
-name = "httpdate"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
-
-[[package]]
-name = "humantime"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
-
-[[package]]
-name = "hyper"
-version = "0.14.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
-dependencies = [
- "bytes",
- "futures-channel",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "httparse",
- "httpdate",
- "itoa",
- "pin-project-lite",
- "socket2 0.4.9",
- "tokio",
- "tower-service",
- "tracing",
- "want",
-]
-
-[[package]]
-name = "hyper-rustls"
-version = "0.23.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c"
-dependencies = [
- "http",
- "hyper",
- "log",
- "rustls 0.20.8",
- "rustls-native-certs",
- "tokio",
- "tokio-rustls 0.23.4",
-]
-
-[[package]]
-name = "hyper-rustls"
-version = "0.24.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7"
-dependencies = [
- "http",
- "hyper",
- "rustls 0.21.2",
- "tokio",
- "tokio-rustls 0.24.1",
-]
-
-[[package]]
-name = "hyper-tls"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
-dependencies = [
- "bytes",
- "hyper",
- "native-tls",
- "tokio",
- "tokio-native-tls",
-]
-
-[[package]]
-name = "iana-time-zone"
-version = "0.1.57"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"
-dependencies = [
- "android_system_properties",
- "core-foundation-sys",
- "iana-time-zone-haiku",
- "js-sys",
- "wasm-bindgen",
- "windows 0.48.0",
-]
-
-[[package]]
-name = "iana-time-zone-haiku"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "id-arena"
-version = "2.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
-
-[[package]]
-name = "ident_case"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
-
-[[package]]
-name = "idna"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
-dependencies = [
- "matches",
- "unicode-bidi",
- "unicode-normalization",
-]
-
-[[package]]
-name = "idna"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
-dependencies = [
- "unicode-bidi",
- "unicode-normalization",
-]
-
-[[package]]
-name = "ignore"
-version = "0.4.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492"
-dependencies = [
- "globset",
- "lazy_static",
- "log",
- "memchr",
- "regex",
- "same-file",
- "thread_local",
- "walkdir",
- "winapi-util",
-]
-
-[[package]]
-name = "indexmap"
-version = "1.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
-dependencies = [
- "autocfg",
- "hashbrown 0.12.3",
-]
-
-[[package]]
-name = "indexmap"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
-dependencies = [
- "equivalent",
- "hashbrown 0.14.0",
-]
-
-[[package]]
-name = "indicatif"
-version = "0.17.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057"
-dependencies = [
- "console",
- "instant",
- "number_prefix",
- "portable-atomic",
- "unicode-width",
-]
-
-[[package]]
-name = "inotify"
-version = "0.9.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
-dependencies = [
- "bitflags",
- "inotify-sys",
- "libc",
-]
-
-[[package]]
-name = "inotify-sys"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "inout"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
-dependencies = [
- "generic-array",
-]
-
-[[package]]
-name = "instant"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "internment"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "161079c3ad892faa215fcfcf3fd7a6a3c9288df2b06a2c2bad7fbfad4f01d69d"
-dependencies = [
- "hashbrown 0.12.3",
- "parking_lot",
-]
-
-[[package]]
-name = "io-lifetimes"
-version = "1.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
-dependencies = [
- "hermit-abi 0.3.1",
- "libc",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "ipconfig"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f"
-dependencies = [
- "socket2 0.5.3",
- "widestring",
- "windows-sys 0.48.0",
- "winreg 0.50.0",
-]
-
-[[package]]
-name = "ipnet"
-version = "2.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
-
-[[package]]
-name = "iri-string"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f0f7638c1e223529f1bfdc48c8b133b9e0b434094d1d28473161ee48b235f78"
-dependencies = [
- "nom",
-]
-
-[[package]]
-name = "is-docker"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3"
-dependencies = [
- "once_cell",
-]
-
-[[package]]
-name = "is-terminal"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
-dependencies = [
- "hermit-abi 0.3.1",
- "io-lifetimes",
- "rustix",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "is-wsl"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5"
-dependencies = [
- "is-docker",
- "once_cell",
-]
-
-[[package]]
-name = "is_executable"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "302d553b8abc8187beb7d663e34c065ac4570b273bc9511a50e940e99409c577"
-dependencies = [
- "winapi",
-]
-
-[[package]]
-name = "itertools"
-version = "0.10.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
-dependencies = [
- "either",
-]
-
-[[package]]
-name = "itoa"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
-
-[[package]]
-name = "jobserver"
-version = "0.1.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "js-sys"
-version = "0.3.64"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
-dependencies = [
- "wasm-bindgen",
-]
-
-[[package]]
-name = "keyboard-types"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7668b7cff6a51fe61cdde64cd27c8a220786f399501b57ebe36f7d8112fd68"
-dependencies = [
- "bitflags",
- "serde",
- "unicode-segmentation",
-]
-
-[[package]]
-name = "kqueue"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98"
-dependencies = [
- "kqueue-sys",
- "libc",
-]
-
-[[package]]
-name = "kqueue-sys"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587"
-dependencies = [
- "bitflags",
- "libc",
-]
-
-[[package]]
-name = "krates"
-version = "0.12.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "942c43a6cba1c201dfe81a943c89fa5c9140b34993e0c027f542c80b92e319a7"
-dependencies = [
- "cargo_metadata",
- "cfg-expr",
- "petgraph",
- "semver",
-]
-
-[[package]]
-name = "kstring"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747"
-dependencies = [
- "serde",
- "static_assertions",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
-[[package]]
-name = "leb128"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
-
-[[package]]
-name = "libc"
-version = "0.2.147"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
-
-[[package]]
-name = "libgit2-sys"
-version = "0.15.2+1.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a80df2e11fb4a61f4ba2ab42dbe7f74468da143f1a75c74e11dee7c813f694fa"
-dependencies = [
- "cc",
- "libc",
- "libssh2-sys",
- "libz-sys",
- "openssl-sys",
- "pkg-config",
-]
-
-[[package]]
-name = "libssh2-sys"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee"
-dependencies = [
- "cc",
- "libc",
- "libz-sys",
- "openssl-sys",
- "pkg-config",
- "vcpkg",
-]
-
-[[package]]
-name = "libz-sys"
-version = "1.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db"
-dependencies = [
- "cc",
- "libc",
- "pkg-config",
- "vcpkg",
-]
-
-[[package]]
-name = "linked-hash-map"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
-
-[[package]]
-name = "linux-raw-sys"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
-
-[[package]]
-name = "liquid"
-version = "0.26.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69f68ae1011499ae2ef879f631891f21c78e309755f4a5e483c4a8f12e10b609"
-dependencies = [
- "doc-comment",
- "liquid-core",
- "liquid-derive",
- "liquid-lib",
- "serde",
-]
-
-[[package]]
-name = "liquid-core"
-version = "0.26.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79e0724dfcaad5cfb7965ea0f178ca0870b8d7315178f4a7179f5696f7f04d5f"
-dependencies = [
- "anymap2",
- "itertools",
- "kstring",
- "liquid-derive",
- "num-traits",
- "pest",
- "pest_derive",
- "regex",
- "serde",
- "time 0.3.22",
-]
-
-[[package]]
-name = "liquid-derive"
-version = "0.26.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc2fb41a9bb4257a3803154bdf7e2df7d45197d1941c9b1a90ad815231630721"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "liquid-lib"
-version = "0.26.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2a17e273a6fb1fb6268f7a5867ddfd0bd4683c7e19b51084f3d567fad4348c0"
-dependencies = [
- "itertools",
- "liquid-core",
- "once_cell",
- "percent-encoding",
- "regex",
- "time 0.3.22",
- "unicode-segmentation",
-]
-
-[[package]]
-name = "lock_api"
-version = "0.4.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
-dependencies = [
- "autocfg",
- "scopeguard",
-]
-
-[[package]]
-name = "log"
-version = "0.4.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
-
-[[package]]
-name = "longest-increasing-subsequence"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86"
-
-[[package]]
-name = "lru-cache"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
-dependencies = [
- "linked-hash-map",
-]
-
-[[package]]
-name = "lua-src"
-version = "546.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cb00c1380f1b4b4928dd211c07301ffa34872a239e590bd3219d9e5b213face"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "luajit-src"
-version = "210.4.5+resty2cf5186"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27b7992a40e602786272d84c6f2beca44a588ededcfd57b48ec6f82008a7cb97"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "match_cfg"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
-
-[[package]]
-name = "matches"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
-
-[[package]]
-name = "matchit"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb"
-
-[[package]]
-name = "memchr"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
-
-[[package]]
-name = "memmap2"
-version = "0.5.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "mime"
-version = "0.3.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
-
-[[package]]
-name = "mime_guess"
-version = "2.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
-dependencies = [
- "mime",
- "unicase",
-]
-
-[[package]]
-name = "minimal-lexical"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
-
-[[package]]
-name = "miniz_oxide"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
-dependencies = [
- "adler",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
-dependencies = [
- "adler",
-]
-
-[[package]]
-name = "mio"
-version = "0.8.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
-dependencies = [
- "libc",
- "log",
- "wasi 0.11.0+wasi-snapshot-preview1",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "mlua"
-version = "0.8.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07366ed2cd22a3b000aed076e2b68896fb46f06f1f5786c5962da73c0af01577"
-dependencies = [
- "bstr 0.2.17",
- "cc",
- "futures-core",
- "futures-task",
- "futures-util",
- "lua-src",
- "luajit-src",
- "mlua_derive",
- "num-traits",
- "once_cell",
- "pkg-config",
- "rustc-hash",
-]
-
-[[package]]
-name = "mlua_derive"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9214e60d3cf1643013b107330fcd374ccec1e4ba1eef76e7e5da5e8202e71c0"
-dependencies = [
- "itertools",
- "once_cell",
- "proc-macro-error",
- "proc-macro2",
- "quote",
- "regex",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "names"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7bddcd3bf5144b6392de80e04c347cd7fab2508f6df16a85fc496ecd5cec39bc"
-dependencies = [
- "rand",
-]
-
-[[package]]
-name = "native-tls"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
-dependencies = [
- "lazy_static",
- "libc",
- "log",
- "openssl",
- "openssl-probe",
- "openssl-sys",
- "schannel",
- "security-framework",
- "security-framework-sys",
- "tempfile",
-]
-
-[[package]]
-name = "nix"
-version = "0.26.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
-dependencies = [
- "bitflags",
- "cfg-if",
- "libc",
- "static_assertions",
-]
-
-[[package]]
-name = "nom"
-version = "7.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
-dependencies = [
- "memchr",
- "minimal-lexical",
-]
-
-[[package]]
-name = "normpath"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5"
-dependencies = [
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "notify"
-version = "5.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486"
-dependencies = [
- "bitflags",
- "crossbeam-channel",
- "filetime",
- "fsevent-sys",
- "inotify",
- "kqueue",
- "libc",
- "mio",
- "serde",
- "walkdir",
- "windows-sys 0.45.0",
-]
-
-[[package]]
-name = "num-traits"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
-dependencies = [
- "hermit-abi 0.2.6",
- "libc",
-]
-
-[[package]]
-name = "num_threads"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "number_prefix"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
-
-[[package]]
-name = "object"
-version = "0.30.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "once_cell"
-version = "1.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
-
-[[package]]
-name = "open"
-version = "4.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a083c0c7e5e4a8ec4176346cf61f67ac674e8bfb059d9226e1c54a96b377c12"
-dependencies = [
- "is-wsl",
- "libc",
- "pathdiff",
-]
-
-[[package]]
-name = "openssl"
-version = "0.10.55"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d"
-dependencies = [
- "bitflags",
- "cfg-if",
- "foreign-types",
- "libc",
- "once_cell",
- "openssl-macros",
- "openssl-sys",
-]
-
-[[package]]
-name = "openssl-macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "openssl-probe"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
-
-[[package]]
-name = "openssl-sys"
-version = "0.9.90"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6"
-dependencies = [
- "cc",
- "libc",
- "pkg-config",
- "vcpkg",
-]
-
-[[package]]
-name = "ordered-float"
-version = "2.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
-name = "parking_lot"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
-dependencies = [
- "lock_api",
- "parking_lot_core",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.9.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
-dependencies = [
- "cfg-if",
- "libc",
- "redox_syscall 0.3.5",
- "smallvec",
- "windows-targets 0.48.0",
-]
-
-[[package]]
-name = "password-hash"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
-dependencies = [
- "base64ct",
- "rand_core",
- "subtle",
-]
-
-[[package]]
-name = "paste"
-version = "1.0.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
-
-[[package]]
-name = "path-absolutize"
-version = "3.0.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f1d4993b16f7325d90c18c3c6a3327db7808752db8d208cea0acee0abd52c52"
-dependencies = [
- "path-dedot",
-]
-
-[[package]]
-name = "path-dedot"
-version = "3.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d55e486337acb9973cdea3ec5638c1b3bcb22e573b2b7b41969e0c744d5a15e"
-dependencies = [
- "once_cell",
-]
-
-[[package]]
-name = "pathdiff"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
-
-[[package]]
-name = "pbkdf2"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
-dependencies = [
- "digest",
- "hmac",
- "password-hash",
- "sha2",
-]
-
-[[package]]
-name = "percent-encoding"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
-
-[[package]]
-name = "pest"
-version = "2.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f73935e4d55e2abf7f130186537b19e7a4abc886a0252380b59248af473a3fc9"
-dependencies = [
- "thiserror",
- "ucd-trie",
-]
-
-[[package]]
-name = "pest_derive"
-version = "2.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aef623c9bbfa0eedf5a0efba11a5ee83209c326653ca31ff019bec3a95bfff2b"
-dependencies = [
- "pest",
- "pest_generator",
-]
-
-[[package]]
-name = "pest_generator"
-version = "2.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3e8cba4ec22bada7fc55ffe51e2deb6a0e0db2d0b7ab0b103acc80d2510c190"
-dependencies = [
- "pest",
- "pest_meta",
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "pest_meta"
-version = "2.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a01f71cb40bd8bb94232df14b946909e14660e33fc05db3e50ae2a82d7ea0ca0"
-dependencies = [
- "once_cell",
- "pest",
- "sha2",
-]
-
-[[package]]
-name = "petgraph"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4"
-dependencies = [
- "fixedbitset",
- "indexmap 1.9.3",
-]
-
-[[package]]
-name = "pin-project"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead"
-dependencies = [
- "pin-project-internal",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "pin-project-lite"
-version = "0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
-
-[[package]]
-name = "pin-utils"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
-[[package]]
-name = "pkg-config"
-version = "0.3.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
-
-[[package]]
-name = "portable-atomic"
-version = "1.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794"
-
-[[package]]
-name = "ppv-lite86"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
-
-[[package]]
-name = "prettier-please"
-version = "0.1.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be31b7957122175fcf33c6d8f54489a5262176020bf096026a86b308b7fa5b23"
-dependencies = [
- "proc-macro2",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "proc-macro-error"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
-dependencies = [
- "proc-macro-error-attr",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro-error-attr"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
-dependencies = [
- "proc-macro2",
- "quote",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro-hack"
-version = "0.5.20+deprecated"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.63"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "quick-error"
-version = "1.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
-
-[[package]]
-name = "quote"
-version = "1.0.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "rand"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
-dependencies = [
- "libc",
- "rand_chacha",
- "rand_core",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
-dependencies = [
- "ppv-lite86",
- "rand_core",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
-dependencies = [
- "getrandom 0.2.10",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.1.57"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
-
-[[package]]
-name = "redox_syscall"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
-name = "redox_users"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
-dependencies = [
- "getrandom 0.1.16",
- "redox_syscall 0.1.57",
- "rust-argon2",
-]
-
-[[package]]
-name = "redox_users"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
-dependencies = [
- "getrandom 0.2.10",
- "redox_syscall 0.2.16",
- "thiserror",
-]
-
-[[package]]
-name = "regex"
-version = "1.8.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
-dependencies = [
- "aho-corasick 1.0.2",
- "memchr",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
-
-[[package]]
-name = "regex-syntax"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
-
-[[package]]
-name = "remove_dir_all"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23895cfadc1917fed9c6ed76a8c2903615fa3704f7493ff82b364c6540acc02b"
-dependencies = [
- "aligned",
- "cfg-if",
- "cvt",
- "fs_at",
- "lazy_static",
- "libc",
- "normpath",
- "windows-sys 0.45.0",
-]
-
-[[package]]
-name = "reqwest"
-version = "0.11.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55"
-dependencies = [
- "base64 0.21.2",
- "bytes",
- "encoding_rs",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "hyper",
- "hyper-rustls 0.24.0",
- "hyper-tls",
- "ipnet",
- "js-sys",
- "log",
- "mime",
- "native-tls",
- "once_cell",
- "percent-encoding",
- "pin-project-lite",
- "rustls 0.21.2",
- "rustls-pemfile",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "tokio",
- "tokio-native-tls",
- "tokio-rustls 0.24.1",
- "tokio-util",
- "tower-service",
- "trust-dns-resolver",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "wasm-streams",
- "web-sys",
- "webpki-roots",
- "winreg 0.10.1",
-]
-
-[[package]]
-name = "resolv-conf"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
-dependencies = [
- "hostname",
- "quick-error",
-]
-
-[[package]]
-name = "rhai"
-version = "1.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd29fa1f740be6dc91982013957e08c3c4232d7efcfe19e12da87d50bad47758"
-dependencies = [
- "ahash 0.8.3",
- "bitflags",
- "instant",
- "num-traits",
- "rhai_codegen",
- "smallvec",
- "smartstring",
-]
-
-[[package]]
-name = "rhai_codegen"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db74e3fdd29d969a0ec1f8e79171a6f0f71d0429293656901db382d248c4c021"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "ring"
-version = "0.16.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
-dependencies = [
- "cc",
- "libc",
- "once_cell",
- "spin",
- "untrusted",
- "web-sys",
- "winapi",
-]
-
-[[package]]
-name = "rsx-rosetta"
-version = "0.3.0"
-source = "git+https://github.com/DioxusLabs/dioxus#11c9abcf7ce731ccb4a44c52de383c090ab319af"
-dependencies = [
- "convert_case",
- "dioxus-autofmt",
- "dioxus-rsx",
- "html_parser",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "rust-argon2"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
-dependencies = [
- "base64 0.13.1",
- "blake2b_simd",
- "constant_time_eq",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "rustc-demangle"
-version = "0.1.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
-
-[[package]]
-name = "rustc-hash"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
-
-[[package]]
-name = "rustix"
-version = "0.37.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
-dependencies = [
- "bitflags",
- "errno",
- "io-lifetimes",
- "libc",
- "linux-raw-sys",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "rustls"
-version = "0.20.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f"
-dependencies = [
- "log",
- "ring",
- "sct",
- "webpki",
-]
-
-[[package]]
-name = "rustls"
-version = "0.21.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f"
-dependencies = [
- "log",
- "ring",
- "rustls-webpki",
- "sct",
-]
-
-[[package]]
-name = "rustls-native-certs"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
-dependencies = [
- "openssl-probe",
- "rustls-pemfile",
- "schannel",
- "security-framework",
-]
-
-[[package]]
-name = "rustls-pemfile"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
-dependencies = [
- "base64 0.21.2",
-]
-
-[[package]]
-name = "rustls-webpki"
-version = "0.100.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b"
-dependencies = [
- "ring",
- "untrusted",
-]
-
-[[package]]
-name = "ryu"
-version = "1.0.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
-
-[[package]]
-name = "safemem"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
-
-[[package]]
-name = "same-file"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
-name = "sanitize-filename"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c502bdb638f1396509467cb0580ef3b29aa2a45c5d43e5d84928241280296c"
-dependencies = [
- "lazy_static",
- "regex",
-]
-
-[[package]]
-name = "schannel"
-version = "0.1.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
-dependencies = [
- "windows-sys 0.42.0",
-]
-
-[[package]]
-name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-
-[[package]]
-name = "sct"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
-dependencies = [
- "ring",
- "untrusted",
-]
-
-[[package]]
-name = "security-framework"
-version = "2.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8"
-dependencies = [
- "bitflags",
- "core-foundation",
- "core-foundation-sys",
- "libc",
- "security-framework-sys",
-]
-
-[[package]]
-name = "security-framework-sys"
-version = "2.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "semver"
-version = "1.0.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "serde"
-version = "1.0.164"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde-value"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
-dependencies = [
- "ordered-float",
- "serde",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.164"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.99"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
-dependencies = [
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "serde_repr"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "serde_spanned"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "serde_urlencoded"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
-dependencies = [
- "form_urlencoded",
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "sha-1"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "digest",
-]
-
-[[package]]
-name = "sha1"
-version = "0.10.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "digest",
-]
-
-[[package]]
-name = "sha1_smol"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
-
-[[package]]
-name = "sha2"
-version = "0.10.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "digest",
-]
-
-[[package]]
-name = "shell-words"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
-
-[[package]]
-name = "signal-hook-registry"
-version = "1.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "siphasher"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
-
-[[package]]
-name = "slab"
-version = "0.4.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "smallbox"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4679d6eef28b85020158619fc09769de89e90886c5de7157587d87cb72648faa"
-
-[[package]]
-name = "smallvec"
-version = "1.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
-
-[[package]]
-name = "smartstring"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
-dependencies = [
- "autocfg",
- "static_assertions",
- "version_check",
-]
-
-[[package]]
-name = "socket2"
-version = "0.4.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
-dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "socket2"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877"
-dependencies = [
- "libc",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "spin"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
-
-[[package]]
-name = "stable_deref_trait"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
-
-[[package]]
-name = "static_assertions"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
-
-[[package]]
-name = "strsim"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
-
-[[package]]
-name = "subprocess"
-version = "0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c2e86926081dda636c546d8c5e641661049d7562a68f5488be4a1f7f66f6086"
-dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "subtle"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
-
-[[package]]
-name = "syn"
-version = "1.0.109"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "syn"
-version = "2.0.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "sync_wrapper"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
-
-[[package]]
-name = "synstructure"
-version = "0.12.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
- "unicode-xid",
-]
-
-[[package]]
-name = "tar"
-version = "0.4.38"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6"
-dependencies = [
- "filetime",
- "libc",
- "xattr",
-]
-
-[[package]]
-name = "tempfile"
-version = "3.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
-dependencies = [
- "cfg-if",
- "fastrand",
- "redox_syscall 0.3.5",
- "rustix",
- "windows-sys 0.45.0",
-]
-
-[[package]]
-name = "termcolor"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
-name = "thiserror"
-version = "1.0.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
-dependencies = [
- "thiserror-impl",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "1.0.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "thread_local"
-version = "1.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
-dependencies = [
- "cfg-if",
- "once_cell",
-]
-
-[[package]]
-name = "time"
-version = "0.1.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
-dependencies = [
- "libc",
- "wasi 0.10.0+wasi-snapshot-preview1",
- "winapi",
-]
-
-[[package]]
-name = "time"
-version = "0.3.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd"
-dependencies = [
- "itoa",
- "libc",
- "num_threads",
- "serde",
- "time-core",
- "time-macros",
-]
-
-[[package]]
-name = "time-core"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
-
-[[package]]
-name = "time-macros"
-version = "0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b"
-dependencies = [
- "time-core",
-]
-
-[[package]]
-name = "tiny-keccak"
-version = "2.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
-dependencies = [
- "crunchy",
-]
-
-[[package]]
-name = "tinyvec"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
-dependencies = [
- "tinyvec_macros",
-]
-
-[[package]]
-name = "tinyvec_macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
-
-[[package]]
-name = "tokio"
-version = "1.28.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2"
-dependencies = [
- "autocfg",
- "bytes",
- "libc",
- "mio",
- "num_cpus",
- "parking_lot",
- "pin-project-lite",
- "signal-hook-registry",
- "socket2 0.4.9",
- "tokio-macros",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "tokio-macros"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "tokio-native-tls"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
-dependencies = [
- "native-tls",
- "tokio",
-]
-
-[[package]]
-name = "tokio-rustls"
-version = "0.23.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
-dependencies = [
- "rustls 0.20.8",
- "tokio",
- "webpki",
-]
-
-[[package]]
-name = "tokio-rustls"
-version = "0.24.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
-dependencies = [
- "rustls 0.21.2",
- "tokio",
-]
-
-[[package]]
-name = "tokio-tungstenite"
-version = "0.17.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181"
-dependencies = [
- "futures-util",
- "log",
- "tokio",
- "tungstenite",
-]
-
-[[package]]
-name = "tokio-util"
-version = "0.7.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
-dependencies = [
- "bytes",
- "futures-core",
- "futures-sink",
- "pin-project-lite",
- "tokio",
- "tracing",
-]
-
-[[package]]
-name = "toml"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "toml"
-version = "0.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240"
-dependencies = [
- "serde",
- "serde_spanned",
- "toml_datetime",
- "toml_edit",
-]
-
-[[package]]
-name = "toml_datetime"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.19.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7"
-dependencies = [
- "indexmap 2.0.0",
- "serde",
- "serde_spanned",
- "toml_datetime",
- "winnow",
-]
-
-[[package]]
-name = "tower"
-version = "0.4.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
-dependencies = [
- "futures-core",
- "futures-util",
- "pin-project",
- "pin-project-lite",
- "tokio",
- "tower-layer",
- "tower-service",
- "tracing",
-]
-
-[[package]]
-name = "tower-http"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aba3f3efabf7fb41fae8534fc20a817013dd1c12cb45441efb6c82e6556b4cd8"
-dependencies = [
- "async-compression",
- "base64 0.13.1",
- "bitflags",
- "bytes",
- "futures-core",
- "futures-util",
- "http",
- "http-body",
- "http-range-header",
- "httpdate",
- "iri-string",
- "mime",
- "mime_guess",
- "percent-encoding",
- "pin-project-lite",
- "tokio",
- "tokio-util",
- "tower",
- "tower-layer",
- "tower-service",
- "tracing",
-]
-
-[[package]]
-name = "tower-http"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858"
-dependencies = [
- "bitflags",
- "bytes",
- "futures-core",
- "futures-util",
- "http",
- "http-body",
- "http-range-header",
- "pin-project-lite",
- "tower",
- "tower-layer",
- "tower-service",
-]
-
-[[package]]
-name = "tower-layer"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
-
-[[package]]
-name = "tower-service"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
-
-[[package]]
-name = "tracing"
-version = "0.1.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
-dependencies = [
- "cfg-if",
- "log",
- "pin-project-lite",
- "tracing-attributes",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-attributes"
-version = "0.1.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.22",
-]
-
-[[package]]
-name = "tracing-core"
-version = "0.1.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
-dependencies = [
- "once_cell",
-]
-
-[[package]]
-name = "trust-dns-proto"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26"
-dependencies = [
- "async-trait",
- "cfg-if",
- "data-encoding",
- "enum-as-inner",
- "futures-channel",
- "futures-io",
- "futures-util",
- "idna 0.2.3",
- "ipnet",
- "lazy_static",
- "rand",
- "smallvec",
- "thiserror",
- "tinyvec",
- "tokio",
- "tracing",
- "url",
-]
-
-[[package]]
-name = "trust-dns-resolver"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe"
-dependencies = [
- "cfg-if",
- "futures-util",
- "ipconfig",
- "lazy_static",
- "lru-cache",
- "parking_lot",
- "resolv-conf",
- "smallvec",
- "thiserror",
- "tokio",
- "tracing",
- "trust-dns-proto",
-]
-
-[[package]]
-name = "try-lock"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
-
-[[package]]
-name = "tungstenite"
-version = "0.17.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0"
-dependencies = [
- "base64 0.13.1",
- "byteorder",
- "bytes",
- "http",
- "httparse",
- "log",
- "rand",
- "sha-1",
- "thiserror",
- "url",
- "utf-8",
-]
-
-[[package]]
-name = "typenum"
-version = "1.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
-
-[[package]]
-name = "ucd-trie"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
-
-[[package]]
-name = "unicase"
-version = "2.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
-dependencies = [
- "version_check",
-]
-
-[[package]]
-name = "unicode-bidi"
-version = "0.3.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
-
-[[package]]
-name = "unicode-bom"
-version = "1.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63ec69f541d875b783ca40184d655f2927c95f0bffd486faa83cd3ac3529ec32"
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
-
-[[package]]
-name = "unicode-normalization"
-version = "0.1.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
-dependencies = [
- "tinyvec",
-]
-
-[[package]]
-name = "unicode-segmentation"
-version = "1.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
-
-[[package]]
-name = "unicode-width"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
-
-[[package]]
-name = "untrusted"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
-
-[[package]]
-name = "url"
-version = "2.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
-dependencies = [
- "form_urlencoded",
- "idna 0.4.0",
- "percent-encoding",
-]
-
-[[package]]
-name = "utf-8"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
-
-[[package]]
-name = "utf8parse"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
-
-[[package]]
-name = "vcpkg"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
-
-[[package]]
-name = "version_check"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
-
-[[package]]
-name = "walkdir"
-version = "2.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
-dependencies = [
- "same-file",
- "winapi-util",
-]
-
-[[package]]
-name = "walrus"
-version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4eb08e48cde54c05f363d984bb54ce374f49e242def9468d2e1b6c2372d291f8"
-dependencies = [
- "anyhow",
- "id-arena",
- "leb128",
- "log",
- "walrus-macro",
- "wasmparser",
-]
-
-[[package]]
-name = "walrus-macro"
-version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a6e5bd22c71e77d60140b0bd5be56155a37e5bd14e24f5f87298040d0cc40d7"
-dependencies = [
- "heck 0.3.3",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "want"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
-dependencies = [
- "try-lock",
-]
-
-[[package]]
-name = "wasi"
-version = "0.9.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
-
-[[package]]
-name = "wasi"
-version = "0.10.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
-
-[[package]]
-name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
-
-[[package]]
-name = "wasm-bindgen"
-version = "0.2.87"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
-dependencies = [
- "cfg-if",
- "wasm-bindgen-macro",
-]
-
-[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.87"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
-dependencies = [
- "bumpalo",
- "log",
- "once_cell",
- "proc-macro2",
- "quote",
- "syn 2.0.22",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-cli-support"
-version = "0.2.87"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d21c60239a09bf9bab8dfa752be4e6c637db22296b9ded493800090448692da9"
-dependencies = [
- "anyhow",
- "base64 0.9.3",
- "log",
- "rustc-demangle",
- "serde_json",
- "tempfile",
- "unicode-ident",
- "walrus",
- "wasm-bindgen-externref-xform",
- "wasm-bindgen-multi-value-xform",
- "wasm-bindgen-shared",
- "wasm-bindgen-threads-xform",
- "wasm-bindgen-wasm-conventions",
- "wasm-bindgen-wasm-interpreter",
-]
-
-[[package]]
-name = "wasm-bindgen-externref-xform"
-version = "0.2.87"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bafbe1984f67cc12645f12ab65e6145e8ddce1ab265d0be58435f25bb0ce2608"
-dependencies = [
- "anyhow",
- "walrus",
-]
-
-[[package]]
-name = "wasm-bindgen-futures"
-version = "0.4.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
-dependencies = [
- "cfg-if",
- "js-sys",
- "wasm-bindgen",
- "web-sys",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.87"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.87"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.22",
- "wasm-bindgen-backend",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-multi-value-xform"
-version = "0.2.87"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "581419e3995571a1d2d066e360ca1c0c09da097f5a53c98e6f00d96eddaf0ffe"
-dependencies = [
- "anyhow",
- "walrus",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.87"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
-
-[[package]]
-name = "wasm-bindgen-threads-xform"
-version = "0.2.87"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e05d272073981137e8426cf2a6830d43d1f84f988a050b2f8b210f0e266b8983"
-dependencies = [
- "anyhow",
- "walrus",
- "wasm-bindgen-wasm-conventions",
-]
-
-[[package]]
-name = "wasm-bindgen-wasm-conventions"
-version = "0.2.87"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e9c65b1ff5041ea824ca24c519948aec16fb6611c617d601623c0657dfcd47b"
-dependencies = [
- "anyhow",
- "walrus",
-]
-
-[[package]]
-name = "wasm-bindgen-wasm-interpreter"
-version = "0.2.87"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c5c796220738ab5d44666f37205728a74141c0039d1166bcf8110b26bafaa1e"
-dependencies = [
- "anyhow",
- "log",
- "walrus",
- "wasm-bindgen-wasm-conventions",
-]
-
-[[package]]
-name = "wasm-streams"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078"
-dependencies = [
- "futures-util",
- "js-sys",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
-]
-
-[[package]]
-name = "wasmparser"
-version = "0.77.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fe3d5405e9ea6c1317a656d6e0820912d8b7b3607823a7596117c8f666daf6f"
-
-[[package]]
-name = "web-sys"
-version = "0.3.64"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "webpki"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
-dependencies = [
- "ring",
- "untrusted",
-]
-
-[[package]]
-name = "webpki-roots"
-version = "0.22.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
-dependencies = [
- "webpki",
-]
-
-[[package]]
-name = "widestring"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8"
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-util"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
-dependencies = [
- "winapi",
-]
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
-name = "windows"
-version = "0.43.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244"
-dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
-]
-
-[[package]]
-name = "windows"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
-dependencies = [
- "windows-targets 0.48.0",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.42.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
-dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.45.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
-dependencies = [
- "windows-targets 0.42.2",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
-dependencies = [
- "windows-targets 0.48.0",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
-dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
-dependencies = [
- "windows_aarch64_gnullvm 0.48.0",
- "windows_aarch64_msvc 0.48.0",
- "windows_i686_gnu 0.48.0",
- "windows_i686_msvc 0.48.0",
- "windows_x86_64_gnu 0.48.0",
- "windows_x86_64_gnullvm 0.48.0",
- "windows_x86_64_msvc 0.48.0",
-]
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
-
-[[package]]
-name = "winnow"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "winreg"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
-dependencies = [
- "winapi",
-]
-
-[[package]]
-name = "winreg"
-version = "0.50.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
-dependencies = [
- "cfg-if",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "xattr"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "zeroize"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
-
-[[package]]
-name = "zip"
-version = "0.5.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815"
-dependencies = [
- "byteorder",
- "bzip2",
- "crc32fast",
- "flate2",
- "thiserror",
- "time 0.1.45",
-]
-
-[[package]]
-name = "zip"
-version = "0.6.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
-dependencies = [
- "aes",
- "byteorder",
- "bzip2",
- "constant_time_eq",
- "crc32fast",
- "crossbeam-utils",
- "flate2",
- "hmac",
- "pbkdf2",
- "sha1",
- "time 0.3.22",
- "zstd",
-]
-
-[[package]]
-name = "zstd"
-version = "0.11.2+zstd.1.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
-dependencies = [
- "zstd-safe",
-]
-
-[[package]]
-name = "zstd-safe"
-version = "5.0.2+zstd.1.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
-dependencies = [
- "libc",
- "zstd-sys",
-]
-
-[[package]]
-name = "zstd-sys"
-version = "2.0.8+zstd.1.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c"
-dependencies = [
- "cc",
- "libc",
- "pkg-config",
-]
diff --git a/packages/cli/Cargo.toml b/packages/cli/Cargo.toml
index f325430aa..adb0239f2 100644
--- a/packages/cli/Cargo.toml
+++ b/packages/cli/Cargo.toml
@@ -22,16 +22,13 @@ serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0.79"
toml = "0.5.8"
fs_extra = "1.2.0"
-cargo_toml = "0.11.4"
+cargo_toml = "0.16.0"
futures = "0.3.21"
notify = { version = "5.0.0-pre.16", features = ["serde"] }
html_parser = { workspace = true }
-binary-install = "0.0.2"
-convert_case = "0.5.0"
cargo_metadata = "0.15.0"
-tokio = { version = "1.16.1", features = ["full"] }
+tokio = { version = "1.16.1", features = ["fs", "sync", "rt", "macros"] }
atty = "0.2.14"
-regex = "1.5.4"
chrono = "0.4.19"
anyhow = "1.0.53"
hyper = "0.14.17"
@@ -59,7 +56,6 @@ tar = "0.4.38"
zip = "0.6.2"
tower = "0.4.12"
syn = { version = "2.0", features = ["full", "extra-traits"] }
-proc-macro2 = { version = "1.0", features = ["span-locations"] }
lazy_static = "1.4.0"
# plugin packages
@@ -71,7 +67,6 @@ mlua = { version = "0.8.1", features = [
"macros",
], optional = true }
ctrlc = "3.2.3"
-gitignore = "1.0.7"
open = "4.1.0"
cargo-generate = "0.18"
toml_edit = "0.19.11"
diff --git a/packages/cli/README.md b/packages/cli/README.md
index d868b1c9d..8379f22cc 100644
--- a/packages/cli/README.md
+++ b/packages/cli/README.md
@@ -4,14 +4,14 @@
The **dioxus-cli** (inspired by wasm-pack and webpack) is a tool for getting Dioxus projects up and running.
-It handles all building, bundling, development and publishing to simplify development.
+It handles building, bundling, development and publishing to simplify development.
## Installation
### Install the stable version (recommended)
```
-cargo install dioxus-cli --locked
+cargo install dioxus-cli
```
### Install the latest development build through git
diff --git a/packages/cli/docs/.gitignore b/packages/cli/docs/.gitignore
deleted file mode 100644
index 7585238ef..000000000
--- a/packages/cli/docs/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-book
diff --git a/packages/cli/docs/book.toml b/packages/cli/docs/book.toml
deleted file mode 100644
index a1e57f634..000000000
--- a/packages/cli/docs/book.toml
+++ /dev/null
@@ -1,6 +0,0 @@
-[book]
-authors = ["YuKun Liu"]
-language = "en"
-multilingual = false
-src = "src"
-title = "Dioxus CLI"
diff --git a/packages/cli/docs/src/SUMMARY.md b/packages/cli/docs/src/SUMMARY.md
deleted file mode 100644
index 98a66ae21..000000000
--- a/packages/cli/docs/src/SUMMARY.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Summary
-
-- [Introduction](./introduction.md)
-- [Installation](./installation.md)
-- [Create a project](./creating.md)
-- [Configure a project](./configure.md)
-- [Plugin development](./plugin/README.md)
- - [API.Log](plugin/interface/log.md)
- - [API.Command](plugin/interface/command.md)
- - [API.OS](plugin/interface/os.md)
- - [API.Directories](plugin/interface/dirs.md)
- - [API.Network](plugin/interface/network.md)
- - [API.Path](plugin/interface/path.md)
\ No newline at end of file
diff --git a/packages/cli/docs/src/configure.md b/packages/cli/docs/src/configure.md
deleted file mode 100644
index 3b9f6189b..000000000
--- a/packages/cli/docs/src/configure.md
+++ /dev/null
@@ -1,197 +0,0 @@
-# Configure Project
-
-This chapter will teach you how to configure the CLI with the `Dioxus.toml` file.
-There's an [example](#config-example) which has comments to describe individual keys.
-You can copy that or view this documentation for a more complete learning experience.
-
-"🔒" indicates a mandatory item. Some headers are mandatory, but none of the keys inside them are. It might look weird, but it's normal. Simply don't include any keys.
-
-## Structure
-
-Each header has it's TOML form directly under it.
-
-### Application 🔒
-
-```toml
-[application]
-```
-
-Application-wide configuration. Applies to both web and desktop.
-
-1. **name** 🔒 - Project name & title.
- ```toml
- name = "my_project"
- ```
-
-2. **default_platform** 🔒 - The platform this project targets
- ```toml
- # Currently supported platforms: web, desktop
- default_platform = "web"
- ```
-
-3. **out_dir** - The directory to place the build artifacts from `dx build` or `dx serve` into. This is also where the `assets` directory will be copied into.
- ```toml
- out_dir = "dist"
- ```
-
-4. **asset_dir** - The directory with your static assets. The CLI will automatically copy these assets into the **out_dir** after a build/serve.
- ```toml
- asset_dir = "public"
- ```
-
-5. **sub_package** - The sub package in the workspace to build by default.
- ```toml
- sub_package = "my-crate"
- ```
-
-### Web.App 🔒
-
-```toml
-[web.app]
-```
-
-Web-specific configuration.
-
-1. **title** - The title of the web page.
- ```toml
- # HTML title tag content
- title = "project_name"
- ```
-
-2. **base_path** - The base path to build the application for serving at. This can be useful when serving your application in a subdirectory under a domain. For example when building a site to be served on GitHub Pages.
- ```toml
- # The application will be served at domain.com/my_application/, so we need to modify the base_path to the path where the application will be served
- base_path = "my_application"
- ```
-
-### Web.Watcher ✍
-
-```toml
-[web.watcher]
-```
-
-Development server configuration.
-
-1. **reload_html** - If this is true, the cli will rebuild the index.html file every time the application is rebuilt
- ```toml
- reload_html = true
- ```
-
-2. **watch_path** - The files & directories to monitor for changes
- ```toml
- watch_path = ["src", "public"]
- ```
-
-3. **index_on_404** - If enabled, Dioxus will serve the root page when a route is not found.
-*This is needed when serving an application that uses the router*.
-However, when serving your app using something else than Dioxus (e.g. GitHub Pages), you will have to check how to configure it on that platform.
-In GitHub Pages, you can make a copy of `index.html` named `404.html` in the same directory.
- ```toml
- index_on_404 = true
- ```
-
-### Web.Resource 🔒
-
-```toml
-[web.resource]
-```
-
-Static resource configuration.
-
-1. **style** - CSS files to include in your application.
- ```toml
- style = [
- # Include from public_dir.
- "./assets/style.css",
- # Or some asset from online cdn.
- "https://cdn.jsdelivr.net/npm/bootstrap/dist/css/bootstrap.css"
- ]
- ```
-
-2. **script** - JavaScript files to include in your application.
- ```toml
- script = [
- # Include from asset_dir.
- "./public/index.js",
- # Or from an online CDN.
- "https://cdn.jsdelivr.net/npm/bootstrap/dist/js/bootstrap.js"
- ]
- ```
-
-### Web.Resource.Dev 🔒
-
-```toml
-[web.resource.dev]
-```
-
-This is the same as [`[web.resource]`](#webresource-), but it only works in development servers.
-For example, if you want to include a file in a `dx serve` server, but not a `dx serve --release` server, put it here.
-
-### Web.Proxy
-
-```toml
-[[web.proxy]]
-```
-
-Configuration related to any proxies your application requires during development. Proxies will forward requests to a new service.
-
-1. **backend** - The URL to the server to proxy. The CLI will forward any requests under the backend relative route to the backend instead of returning 404
- ```toml
- backend = "http://localhost:8000/api/"
- ```
- This will cause any requests made to the dev server with prefix /api/ to be redirected to the backend server at http://localhost:8000. The path and query parameters will be passed on as-is (path rewriting is currently not supported).
-
-## Config example
-
-This includes all fields, mandatory or not.
-
-```toml
-[application]
-
-# App name
-name = "project_name"
-
-# The Dioxus platform to default to
-default_platform = "web"
-
-# `build` & `serve` output path
-out_dir = "dist"
-
-# The static resource path
-asset_dir = "public"
-
-[web.app]
-
-# HTML title tag content
-title = "project_name"
-
-[web.watcher]
-
-# When watcher is triggered, regenerate the `index.html`
-reload_html = true
-
-# Which files or dirs will be monitored
-watch_path = ["src", "public"]
-
-# Include style or script assets
-[web.resource]
-
-# CSS style file
-style = []
-
-# Javascript code file
-script = []
-
-[web.resource.dev]
-
-# Same as [web.resource], but for development servers
-
-# CSS style file
-style = []
-
-# JavaScript files
-script = []
-
-[[web.proxy]]
-backend = "http://localhost:8000/api/"
-```
diff --git a/packages/cli/docs/src/creating.md b/packages/cli/docs/src/creating.md
deleted file mode 100644
index 4c594dfd8..000000000
--- a/packages/cli/docs/src/creating.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Create a Project
-
-Once you have the Dioxus CLI installed, you can use it to create your own project!
-
-## Initializing a default project
-
-First, run the `dx create` command to create a new project:
-```
-dx create hello-dioxus
-```
-
-> It will clone this [template](https://github.com/DioxusLabs/dioxus-template).
-> This default template is used for `web` platform application.
->
-> You can choose to create your project from a different template by passing the `template` argument:
-> ```
-> dx init hello-dioxus --template=gh:dioxuslabs/dioxus-template
-> ```
-
-Next, navigate into your new project:
-
-```
-cd hello-dioxus
-```
-
-> Make sure the WASM target is installed before running the projects.
-> You can install the WASM target for rust using rustup:
-> ```
-> rustup target add wasm32-unknown-unknown
-> ```
-
-Finally, serve your project:
-```
-dx serve
-```
-
-By default, the CLI serves your website at [`http://127.0.0.1:8080/`](http://127.0.0.1:8080/).
diff --git a/packages/cli/docs/src/installation.md b/packages/cli/docs/src/installation.md
deleted file mode 100644
index 22803be61..000000000
--- a/packages/cli/docs/src/installation.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Installation
-
-## Install the latest development build through git
-
-To get the latest bug fixes and features, you can install the development version from git.
-
-```
-cargo install --git https://github.com/Dioxuslabs/cli
-```
-
-This will download `Dioxus-CLI` source from GitHub master branch,
-and install it in Cargo's global binary directory (`~/.cargo/bin/` by default).
-
-## Install stable through `crates.io`
-
-The published version of the Dioxus CLI is updated less often, but is more stable than the git version.
-
-```
-cargo install dioxus-cli --locked
-```
-
-Run `dx --help` for a list of all the available commands.
-Furthermore, you can run `dx --help` to get help with a specific command.
diff --git a/packages/cli/docs/src/introduction.md b/packages/cli/docs/src/introduction.md
deleted file mode 100644
index 8b10b0546..000000000
--- a/packages/cli/docs/src/introduction.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Introduction
-
-The 📦✨ **Dioxus CLI** is a tool to help get Dioxus projects off the ground.
-
-## Features
-
-* Build and pack a Dioxus project
-* `html` to `rsx` conversion tool
-* Hot Reload for `web` platform
-* Create a Dioxus project from `git` repo
-* And more!
-
\ No newline at end of file
diff --git a/packages/cli/docs/src/plugin/README.md b/packages/cli/docs/src/plugin/README.md
deleted file mode 100644
index fe7375618..000000000
--- a/packages/cli/docs/src/plugin/README.md
+++ /dev/null
@@ -1,140 +0,0 @@
-# CLI Plugin development
-
-**IMPORTANT: Ignore this documentation. Plugins are yet to be released and chances are it won't work for you. This is just what plugins *could* look like.**
-
-In the past we used `dx tool` to use and install tools, but it was a flawed system.
-Tools were hard-coded by us, but people want more tools than we could code, so this plugin system was made to let
-anyone develop plugins and use them in Dioxus projects.
-
-Plugin resources:
-* [Source code](https://github.com/DioxusLabs/dioxus/tree/master/packages/cli/src/plugin)
-* [Unofficial Dioxus plugin community](https://github.com/DioxusPluginCommunity). Contains certain plugins you can use right now.
-
-### Why Lua?
-
-We chose Lua `5.4` to be the plugin developing language,
-because it's extremely lightweight, embeddable and easy to learn.
-We installed Lua into the CLI, so you don't need to do it yourself.
-
-Lua resources:
-* [Official website](https://www.lua.org/). You can basically find everything here.
-* [Awesome Lua](https://github.com/LewisJEllis/awesome-lua). Additional resources (such as Lua plugins for your favorite IDE), and other *awesome* tools!
-
-
-## Creating a plugin
-
-A plugin is just an `init.lua` file.
-You can include other files using `dofile(path)`.
-You need to have a plugin and a manager instance, which you can get using `require`:
-```lua
-local plugin = require("plugin")
-local manager = require("manager")
-```
-
-You need to set some `manager` fields and then initialize the plugin:
-```lua
-manager.name = "My first plugin"
-manager.repository = "https://github.com/john-doe/my-first-plugin" -- The repository URL.
-manager.author = "John Doe "
-manager.version = "0.1.0"
-plugin.init(manager)
-```
-
-You also need to return the `manager`, which basically represents your plugin:
-```lua
--- Your code here.
--- End of file.
-
-manager.serve.interval = 1000
-return manager
-```
-
-And you're ready to go. Now, go and have a look at the stuff below and the API documentation.
-
-### Plugin info
-
-You will encounter this type in the events below. The keys are as follows:
-* `name: string` - The name of the plugin.
-* `repository: string` - The plugin repository URL.
-* `author: string` - The author of the plugin.
-* `version: string` - The plugin version.
-
-### Event management
-
-The plugin library has certain events that you can subscribe to.
-
-* `manager.on_init` - Triggers the first time the plugin is loaded.
-* `manager.build.on_start(info)` - Triggers before the build process. E.g., before `dx build`.
-* `manager.build.on_finish(info)` - Triggers after the build process. E.g., after `dx build`.
-* `manager.serve.on_start(info)` - Triggers before the serving process. E.g., before `dx serve`.
-* `manager.serve.on_rebuild_start(info)` - Triggers before the server rebuilds the web with hot reload.
-* `manager.serve.on_rebuild_end(info)` - Triggers after the server rebuilds the web with hot reload.
-* `manager.serve.on_shutdown` - Triggers when the server is shutdown. E.g., when the `dx serve` process is terminated.
-
-To subscribe to an event, you simply need to assign it to a function:
-
-```lua
-manager.build.on_start = function (info)
- log.info("[plugin] Build starting: " .. info.name)
-end
-```
-
-### Plugin template
-
-```lua
-package.path = library_dir .. "/?.lua"
-
-local plugin = require("plugin")
-local manager = require("manager")
-
--- deconstruct api functions
-local log = plugin.log
-
--- plugin information
-manager.name = "Hello Dixous Plugin"
-manager.repository = "https://github.com/mrxiaozhuox/hello-dioxus-plugin"
-manager.author = "YuKun Liu "
-manager.version = "0.0.1"
-
--- init manager info to plugin api
-plugin.init(manager)
-
-manager.on_init = function ()
- -- when the first time plugin been load, this function will be execute.
- -- system will create a `dcp.json` file to verify init state.
- log.info("[plugin] Start to init plugin: " .. manager.name)
-end
-
----@param info BuildInfo
-manager.build.on_start = function (info)
- -- before the build work start, system will execute this function.
- log.info("[plugin] Build starting: " .. info.name)
-end
-
----@param info BuildInfo
-manager.build.on_finish = function (info)
- -- when the build work is done, system will execute this function.
- log.info("[plugin] Build finished: " .. info.name)
-end
-
----@param info ServeStartInfo
-manager.serve.on_start = function (info)
- -- this function will after clean & print to run, so you can print some thing.
- log.info("[plugin] Serve start: " .. info.name)
-end
-
----@param info ServeRebuildInfo
-manager.serve.on_rebuild = function (info)
- -- this function will after clean & print to run, so you can print some thing.
- local files = plugin.tool.dump(info.changed_files)
- log.info("[plugin] Serve rebuild: '" .. files .. "'")
-end
-
-manager.serve.on_shutdown = function ()
- log.info("[plugin] Serve shutdown")
-end
-
-manager.serve.interval = 1000
-
-return manager
-```
diff --git a/packages/cli/docs/src/plugin/interface/command.md b/packages/cli/docs/src/plugin/interface/command.md
deleted file mode 100644
index 2882e5153..000000000
--- a/packages/cli/docs/src/plugin/interface/command.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Command Functions
-
-You can use command functions to execute code and scripts.
-
-Type definition:
-```
-Stdio: "Inherit" | "Piped" | "Null"
-```
-
-### `exec(commands: [string], stdout: Stdio, stderr: Stdio)`
-
-You can use this function to run some commands on the current system.
-
-```lua
-local cmd = plugin.command
-
-manager.test = function ()
- cmd.exec({"git", "clone", "https://github.com/DioxusLabs/cli-plugin-library"})
-end
-```
-> Warning: This function doesn't catch exceptions.
\ No newline at end of file
diff --git a/packages/cli/docs/src/plugin/interface/dirs.md b/packages/cli/docs/src/plugin/interface/dirs.md
deleted file mode 100644
index 9984802ff..000000000
--- a/packages/cli/docs/src/plugin/interface/dirs.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# Dirs Functions
-
-Dirs functions are for getting various directory paths. Not to be confused with `plugin.path`.
-
-### `plugin_dir() -> string`
-
-Get the plugin's root directory path.
-
-```lua
-local path = plugin.dirs.plugin_dir()
--- example: ~/Development/DioxusCli/plugin/test-plugin/
-```
-
-### `bin_dir() -> string`
-
-Get the plugin's binary directory path. Put binary files like `tailwind-cli` or `sass-cli` in this directory.
-
-```lua
-local path = plugin.dirs.bin_dir()
--- example: ~/Development/DioxusCli/plugin/test-plugin/bin/
-```
-
-### `temp_dir() -> string`
-
-Get the plugin's temporary directory path. Put any temporary files here.
-
-```lua
-local path = plugin.dirs.bin_dir()
--- example: ~/Development/DioxusCli/plugin/test-plugin/temp/
-```
\ No newline at end of file
diff --git a/packages/cli/docs/src/plugin/interface/log.md b/packages/cli/docs/src/plugin/interface/log.md
deleted file mode 100644
index ee437b77a..000000000
--- a/packages/cli/docs/src/plugin/interface/log.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# Log Functions
-
-You can use log functions to print various logging information.
-
-### `trace(info: string)`
-
-Print trace log info.
-
-```lua
-local log = plugin.log
-log.trace("trace information")
-```
-
-### `debug(info: string)`
-
-Print debug log info.
-
-```lua
-local log = plugin.log
-log.debug("debug information")
-```
-
-### `info(info: string)`
-
-Print info log info.
-
-```lua
-local log = plugin.log
-log.info("info information")
-```
-
-### `warn(info: string)`
-
-Print warning log info.
-
-```lua
-local log = plugin.log
-log.warn("warn information")
-```
-
-### `error(info: string)`
-
-Print error log info.
-
-```lua
-local log = plugin.log
-log.error("error information")
-```
\ No newline at end of file
diff --git a/packages/cli/docs/src/plugin/interface/network.md b/packages/cli/docs/src/plugin/interface/network.md
deleted file mode 100644
index 566bc5073..000000000
--- a/packages/cli/docs/src/plugin/interface/network.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Network Functions
-
-You can use Network functions to download & read some data from the internet.
-
-### `download_file(url: string, path: string) -> boolean`
-
-Downloads a file from the specified URL,
-and returns a `boolean` that represents the download status (true: success, false: failure).
-
-You need to pass a target URL and a local path (where you want to save this file).
-
-```lua
--- this file will download to plugin temp directory
-local status = plugin.network.download_file(
- "http://xxx.com/xxx.zip",
- plugin.dirs.temp_dir()
-)
-if status != true then
- log.error("Download Failed")
-end
-```
-
-### `clone_repo(url: string, path: string) -> boolean`
-
-Clone a repository from the given URL into the given path.
-Returns a `boolean` that represents the clone status (true: success, false: failure).
-The system executing this function must have git installed.
-
-```lua
-local status = plugin.network.clone_repo(
- "http://github.com/mrxiaozhuox/dioxus-starter",
- plugin.dirs.bin_dir()
-)
-if status != true then
- log.error("Clone Failed")
-end
-```
\ No newline at end of file
diff --git a/packages/cli/docs/src/plugin/interface/os.md b/packages/cli/docs/src/plugin/interface/os.md
deleted file mode 100644
index 84f4697b8..000000000
--- a/packages/cli/docs/src/plugin/interface/os.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# OS Functions
-
-OS functions are for getting system information.
-
-### `current_platform() -> string ("windows" | "macos" | "linux")`
-
-Get the current OS platform.
-
-```lua
-local platform = plugin.os.current_platform()
-```
\ No newline at end of file
diff --git a/packages/cli/docs/src/plugin/interface/path.md b/packages/cli/docs/src/plugin/interface/path.md
deleted file mode 100644
index a5bee1eb9..000000000
--- a/packages/cli/docs/src/plugin/interface/path.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# Path Functions
-
-You can use path functions to perform operations on valid path strings.
-
-### `join(path: string, extra: string) -> string`
-
-
-Extend a path; you can extend both directory and file paths.
-
-```lua
-local current_path = "~/hello/dioxus"
-local new_path = plugin.path.join(current_path, "world")
--- new_path = "~/hello/dioxus/world"
-```
-
-### `parent(path: string) -> string`
-
-Return the parent path of the specified path. The parent path is always a directory.
-
-```lua
-local current_path = "~/hello/dioxus"
-local new_path = plugin.path.parent(current_path)
--- new_path = "~/hello/"
-```
-
-### `exists(path: string) -> boolean`
-
-Check if the specified path exists, as either a file or a directory.
-
-### `is_file(path: string) -> boolean`
-
-Check if the specified path is a file.
-
-### `is_dir(path: string) -> boolean`
-
-Check if the specified path is a directory.
\ No newline at end of file
diff --git a/packages/cli/examples/plugin/init.lua b/packages/cli/examples/plugin/init.lua
deleted file mode 100644
index 7d6b710ef..000000000
--- a/packages/cli/examples/plugin/init.lua
+++ /dev/null
@@ -1,18 +0,0 @@
-local Api = require("./interface")
-local log = Api.log;
-
-local manager = {
- name = "Dioxus-CLI Plugin Demo",
- repository = "http://github.com/DioxusLabs/cli",
- author = "YuKun Liu ",
-}
-
-manager.onLoad = function ()
- log.info("plugin loaded.")
-end
-
-manager.onStartBuild = function ()
- log.warn("system start to build")
-end
-
-return manager
\ No newline at end of file
diff --git a/packages/cli/examples/plugin/interface.lua b/packages/cli/examples/plugin/interface.lua
deleted file mode 100644
index bc6c91cb1..000000000
--- a/packages/cli/examples/plugin/interface.lua
+++ /dev/null
@@ -1,25 +0,0 @@
-local interface = {}
-
-if plugin_logger ~= nil then
- interface.log = plugin_logger
-else
- interface.log = {
- trace = function (info)
- print("trace: " .. info)
- end,
- debug = function (info)
- print("debug: " .. info)
- end,
- info = function (info)
- print("info: " .. info)
- end,
- warn = function (info)
- print("warn: " .. info)
- end,
- error = function (info)
- print("error: " .. info)
- end,
- }
-end
-
-return interface
\ No newline at end of file
diff --git a/packages/cli/src/assets/dioxus.toml b/packages/cli/src/assets/dioxus.toml
index 6386fb76e..892a6cdf8 100644
--- a/packages/cli/src/assets/dioxus.toml
+++ b/packages/cli/src/assets/dioxus.toml
@@ -23,7 +23,7 @@ title = "Dioxus | An elegant GUI library for Rust"
index_on_404 = true
-watch_path = ["src"]
+watch_path = ["src", "examples"]
# include `assets` in web platform
[web.resource]
diff --git a/packages/cli/src/builder.rs b/packages/cli/src/builder.rs
index f7016a069..c7a5aa68e 100644
--- a/packages/cli/src/builder.rs
+++ b/packages/cli/src/builder.rs
@@ -254,6 +254,7 @@ pub fn build_desktop(config: &CrateConfig, _is_serve: bool) -> Result Result String {
String::from(include_str!("./assets/index.html"))
};
- let resouces = config.web.resource.clone();
+ let resources = config.web.resource.clone();
- let mut style_list = resouces.style.unwrap_or_default();
- let mut script_list = resouces.script.unwrap_or_default();
+ let mut style_list = resources.style.unwrap_or_default();
+ let mut script_list = resources.script.unwrap_or_default();
if serve {
let mut dev_style = resouces.dev.style.clone();
- let mut dev_script = resouces.dev.script;
+ let mut dev_script = resouces.dev.script.clone();
style_list.append(&mut dev_style);
script_list.append(&mut dev_script);
}
@@ -671,35 +672,3 @@ fn build_assets(config: &CrateConfig) -> Result> {
Ok(result)
}
-
-// use binary_install::{Cache, Download};
-
-// /// Attempts to find `wasm-opt` in `PATH` locally, or failing that downloads a
-// /// precompiled binary.
-// ///
-// /// Returns `Some` if a binary was found or it was successfully downloaded.
-// /// Returns `None` if a binary wasn't found in `PATH` and this platform doesn't
-// /// have precompiled binaries. Returns an error if we failed to download the
-// /// binary.
-// pub fn find_wasm_opt(
-// cache: &Cache,
-// install_permitted: bool,
-// ) -> Result {
-// // First attempt to look up in PATH. If found assume it works.
-// if let Ok(path) = which::which("wasm-opt") {
-// PBAR.info(&format!("found wasm-opt at {:?}", path));
-
-// match path.as_path().parent() {
-// Some(path) => return Ok(install::Status::Found(Download::at(path))),
-// None => {}
-// }
-// }
-
-// let version = "version_78";
-// Ok(install::download_prebuilt(
-// &install::Tool::WasmOpt,
-// cache,
-// version,
-// install_permitted,
-// )?)
-// }
diff --git a/packages/cli/src/cli/autoformat.rs b/packages/cli/src/cli/autoformat.rs
index f436ab4c4..1d1cbcd24 100644
--- a/packages/cli/src/cli/autoformat.rs
+++ b/packages/cli/src/cli/autoformat.rs
@@ -46,18 +46,28 @@ impl Autoformat {
// Format single file
if let Some(file) = self.file {
- let file_content = fs::read_to_string(&file);
+ let file_content = if file == "-" {
+ let mut contents = String::new();
+ std::io::stdin().read_to_string(&mut contents)?;
+ Ok(contents)
+ } else {
+ fs::read_to_string(&file)
+ };
match file_content {
Ok(s) => {
let edits = dioxus_autofmt::fmt_file(&s);
let out = dioxus_autofmt::apply_formats(&s, edits);
- match fs::write(&file, out) {
- Ok(_) => {
- println!("formatted {}", file);
- }
- Err(e) => {
- eprintln!("failed to write formatted content to file: {}", e);
+ if file == "-" {
+ print!("{}", out);
+ } else {
+ match fs::write(&file, out) {
+ Ok(_) => {
+ println!("formatted {}", file);
+ }
+ Err(e) => {
+ eprintln!("failed to write formatted content to file: {}", e);
+ }
}
}
}
diff --git a/packages/cli/src/cli/bundle.rs b/packages/cli/src/cli/bundle.rs
index 0d4fb23da..80b52cf2f 100644
--- a/packages/cli/src/cli/bundle.rs
+++ b/packages/cli/src/cli/bundle.rs
@@ -132,10 +132,10 @@ impl Bundle {
.project_out_directory(crate_config.out_dir)
.package_settings(PackageSettings {
product_name: crate_config.dioxus_config.application.name.clone(),
- version: package.version,
- description: package.description.unwrap_or_default(),
- homepage: package.homepage,
- authors: Some(package.authors),
+ version: package.version().to_string(),
+ description: package.description().unwrap_or_default().to_string(),
+ homepage: Some(package.homepage().unwrap_or_default().to_string()),
+ authors: Some(Vec::from(package.authors())),
default_run: Some(crate_config.dioxus_config.application.name.clone()),
})
.binaries(binaries)
diff --git a/packages/cli/src/config.rs b/packages/cli/src/config.rs
index 278422b71..db3ce9bc7 100644
--- a/packages/cli/src/config.rs
+++ b/packages/cli/src/config.rs
@@ -216,7 +216,7 @@ pub struct WebWatcherConfig {
}
fn watch_path_default() -> Vec {
- vec![PathBuf::from("src")]
+ vec![PathBuf::from("src"), PathBuf::from("examples")]
}
#[derive(Debug, Clone, Serialize, Deserialize)]
diff --git a/packages/cli/src/lib.rs b/packages/cli/src/lib.rs
index c067ab148..b27cf55a9 100644
--- a/packages/cli/src/lib.rs
+++ b/packages/cli/src/lib.rs
@@ -1,3 +1,7 @@
+#![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")]
+
pub const DIOXUS_CLI_VERSION: &str = "0.4.1";
pub mod builder;
diff --git a/packages/cli/src/server/desktop/mod.rs b/packages/cli/src/server/desktop/mod.rs
index 91811857d..978b97d43 100644
--- a/packages/cli/src/server/desktop/mod.rs
+++ b/packages/cli/src/server/desktop/mod.rs
@@ -124,27 +124,34 @@ async fn start_desktop_hot_reload(hot_reload_state: HotReloadState) -> Result<()
let _ = local_socket_stream.set_nonblocking(true);
move || {
loop {
- if let Ok(mut connection) = local_socket_stream.accept() {
- // send any templates than have changed before the socket connected
- let templates: Vec<_> = {
- file_map
- .lock()
- .unwrap()
- .map
- .values()
- .filter_map(|(_, template_slot)| *template_slot)
- .collect()
- };
- for template in templates {
- if !send_msg(
- HotReloadMsg::UpdateTemplate(template),
- &mut connection,
- ) {
- continue;
+ match local_socket_stream.accept() {
+ Ok(mut connection) => {
+ // send any templates than have changed before the socket connected
+ let templates: Vec<_> = {
+ file_map
+ .lock()
+ .unwrap()
+ .map
+ .values()
+ .filter_map(|(_, template_slot)| *template_slot)
+ .collect()
+ };
+ for template in templates {
+ if !send_msg(
+ HotReloadMsg::UpdateTemplate(template),
+ &mut connection,
+ ) {
+ continue;
+ }
+ }
+ channels.lock().unwrap().push(connection);
+ println!("Connected to hot reloading 🚀");
+ }
+ Err(err) => {
+ if err.kind() != std::io::ErrorKind::WouldBlock {
+ println!("Error connecting to hot reloading: {} (Hot reloading is a feature of the dioxus-cli. If you are not using the CLI, this error can be ignored)", err);
}
}
- channels.lock().unwrap().push(connection);
- println!("Connected to hot reloading 🚀");
}
if *aborted.lock().unwrap() {
break;
diff --git a/packages/cli/src/server/mod.rs b/packages/cli/src/server/mod.rs
index 522f690d9..7b60c8178 100644
--- a/packages/cli/src/server/mod.rs
+++ b/packages/cli/src/server/mod.rs
@@ -112,12 +112,12 @@ async fn setup_file_watcher Result + Send + 'static>(
.unwrap();
for sub_path in allow_watch_path {
- watcher
- .watch(
- &config.crate_dir.join(sub_path),
- notify::RecursiveMode::Recursive,
- )
- .unwrap();
+ if let Err(err) = watcher.watch(
+ &config.crate_dir.join(sub_path),
+ notify::RecursiveMode::Recursive,
+ ) {
+ log::error!("Failed to watch path: {}", err);
+ }
}
Ok(watcher)
}
diff --git a/packages/cli/src/server/output.rs b/packages/cli/src/server/output.rs
index 68582f742..ebd9c2212 100644
--- a/packages/cli/src/server/output.rs
+++ b/packages/cli/src/server/output.rs
@@ -121,7 +121,7 @@ pub fn print_console_info(
log::warn!(
"{}",
format!(
- "There were {} warning messages during the build.",
+ "There were {} warning messages during the build. Run `cargo check` to see them.",
options.warnings.len() - 1
)
.yellow()
diff --git a/packages/core-macro/Cargo.toml b/packages/core-macro/Cargo.toml
index d928d5fec..1898d8bd1 100644
--- a/packages/core-macro/Cargo.toml
+++ b/packages/core-macro/Cargo.toml
@@ -19,6 +19,7 @@ syn = { version = "2.0", features = ["full", "extra-traits"] }
dioxus-rsx = { workspace = true }
dioxus-core = { workspace = true }
constcat = "0.3.0"
+prettyplease = "0.2.15"
# testing
[dev-dependencies]
diff --git a/packages/core-macro/README.md b/packages/core-macro/README.md
index 31b0cca90..497c7c587 100644
--- a/packages/core-macro/README.md
+++ b/packages/core-macro/README.md
@@ -23,9 +23,12 @@
`dioxus-core-macro` provides a handful of helpful macros used by the `dioxus` crate. These include:
-- The `rsx!` macro that underpins templates and node creation
-- The `inline_props` macro transforms function arguments into an auto-derived struct
-- The `format_args_f` macro which allows f-string formatting with support for expressions
+- The `rsx!` macro that underpins templates and node creation.
+- The `component` attribute macro denotes a function as a Dioxus component. Currently, this:
+ - Transforms function arguments into an auto-derived struct.
+ - Ensures that your component name uses PascalCase.
+ - Probably more stuff in the future. This macro allows us to have a way of distinguishing functions and components, which can be quite handy.
+- The `format_args_f` macro which allows f-string formatting with support for expressions.
## Contributing
diff --git a/packages/core-macro/src/component_body_deserializers/component.rs b/packages/core-macro/src/component_body_deserializers/component.rs
index e43b1819f..36cda850c 100644
--- a/packages/core-macro/src/component_body_deserializers/component.rs
+++ b/packages/core-macro/src/component_body_deserializers/component.rs
@@ -31,6 +31,7 @@ fn get_out_comp_fn(orig_comp_fn: &ItemFn, cx_pat: &Pat) -> ItemFn {
block: parse_quote! {
{
#[warn(non_snake_case)]
+ #[allow(clippy::inline_always)]
#[inline(always)]
#inner_comp_fn
#inner_comp_ident (#cx_pat)
diff --git a/packages/core-macro/src/component_body_deserializers/inline_props.rs b/packages/core-macro/src/component_body_deserializers/inline_props.rs
index 8e4581c19..d51132623 100644
--- a/packages/core-macro/src/component_body_deserializers/inline_props.rs
+++ b/packages/core-macro/src/component_body_deserializers/inline_props.rs
@@ -30,166 +30,312 @@ impl ToTokens for InlinePropsDeserializerOutput {
impl DeserializerArgs for InlinePropsDeserializerArgs {
fn to_output(&self, component_body: &ComponentBody) -> Result {
Ok(InlinePropsDeserializerOutput {
- comp_fn: Self::get_function(component_body),
- props_struct: Self::get_props_struct(component_body),
+ comp_fn: get_function(component_body),
+ props_struct: get_props_struct(component_body),
})
}
}
-impl InlinePropsDeserializerArgs {
- fn get_props_struct(component_body: &ComponentBody) -> ItemStruct {
- let ComponentBody { item_fn, .. } = component_body;
- let ItemFn { vis, sig, .. } = item_fn;
- let Signature {
- inputs,
- ident: fn_ident,
- generics,
- ..
- } = sig;
+fn get_props_struct(component_body: &ComponentBody) -> ItemStruct {
+ let ComponentBody { item_fn, .. } = component_body;
+ let ItemFn { vis, sig, .. } = item_fn;
+ let Signature {
+ inputs,
+ ident: fn_ident,
+ generics,
+ ..
+ } = sig;
- // Skip first arg since that's the context
- let struct_fields = inputs.iter().skip(1).map(move |f| {
- match f {
- FnArg::Receiver(_) => unreachable!(), // Unreachable because of ComponentBody parsing
- FnArg::Typed(pt) => {
- let arg_pat = &pt.pat; // Pattern (identifier)
- let arg_colon = &pt.colon_token;
- let arg_ty = &pt.ty; // Type
- let arg_attrs = &pt.attrs; // Attributes
+ // Skip first arg since that's the context
+ let struct_fields = inputs.iter().skip(1).map(move |f| {
+ match f {
+ FnArg::Receiver(_) => unreachable!(), // Unreachable because of ComponentBody parsing
+ FnArg::Typed(pt) => {
+ let arg_pat = &pt.pat; // Pattern (identifier)
+ let arg_colon = &pt.colon_token;
+ let arg_ty = &pt.ty; // Type
+ let arg_attrs = &pt.attrs; // Attributes
- quote! {
- #(#arg_attrs)
- *
- #vis #arg_pat #arg_colon #arg_ty
- }
+ quote! {
+ #(#arg_attrs)
+ *
+ #vis #arg_pat #arg_colon #arg_ty
}
}
- });
-
- let struct_ident = Ident::new(&format!("{fn_ident}Props"), fn_ident.span());
-
- let first_lifetime = if let Some(GenericParam::Lifetime(lt)) = generics.params.first() {
- Some(lt)
- } else {
- None
- };
-
- let struct_attrs = if first_lifetime.is_some() {
- quote! { #[derive(Props)] }
- } else {
- quote! { #[derive(Props, PartialEq)] }
- };
-
- let struct_generics = if first_lifetime.is_some() {
- let struct_generics: Punctuated = component_body
- .item_fn
- .sig
- .generics
- .params
- .iter()
- .map(|it| match it {
- GenericParam::Type(tp) => {
- let mut tp = tp.clone();
- tp.bounds.push(parse_quote!( 'a ));
-
- GenericParam::Type(tp)
- }
- _ => it.clone(),
- })
- .collect();
-
- quote! { <#struct_generics> }
- } else {
- quote! { #generics }
- };
-
- parse_quote! {
- #struct_attrs
- #[allow(non_camel_case_types)]
- #vis struct #struct_ident #struct_generics
- {
- #(#struct_fields),*
- }
}
- }
+ });
- fn get_function(component_body: &ComponentBody) -> ItemFn {
- let ComponentBody {
- item_fn,
- cx_pat_type,
- ..
- } = component_body;
- let ItemFn {
- attrs: fn_attrs,
- vis,
- sig,
- block: fn_block,
- } = item_fn;
- let Signature {
- inputs,
- ident: fn_ident,
- generics,
- output: fn_output,
- asyncness,
- ..
- } = sig;
- let Generics { where_clause, .. } = generics;
+ let struct_ident = Ident::new(&format!("{fn_ident}Props"), fn_ident.span());
- let cx_pat = &cx_pat_type.pat;
- let struct_ident = Ident::new(&format!("{fn_ident}Props"), fn_ident.span());
+ let first_lifetime = if let Some(GenericParam::Lifetime(lt)) = generics.params.first() {
+ Some(lt)
+ } else {
+ None
+ };
- // Skip first arg since that's the context
- let struct_field_names = inputs.iter().skip(1).filter_map(|f| match f {
- FnArg::Receiver(_) => unreachable!(), // ComponentBody prohibits receiver parameters.
- FnArg::Typed(t) => Some(&t.pat),
- });
+ let struct_attrs = if first_lifetime.is_some() {
+ quote! { #[derive(Props)] }
+ } else {
+ quote! { #[derive(Props, PartialEq)] }
+ };
- let first_lifetime = if let Some(GenericParam::Lifetime(lt)) = generics.params.first() {
- Some(lt)
- } else {
- None
- };
+ let struct_generics = if first_lifetime.is_some() {
+ let struct_generics: Punctuated = component_body
+ .item_fn
+ .sig
+ .generics
+ .params
+ .iter()
+ .map(|it| match it {
+ GenericParam::Type(tp) => {
+ let mut tp = tp.clone();
+ tp.bounds.push(parse_quote!( 'a ));
- let (scope_lifetime, fn_generics) = if let Some(lt) = first_lifetime {
- (quote! { #lt, }, generics.clone())
- } else {
- let lifetime: LifetimeParam = parse_quote! { 'a };
+ GenericParam::Type(tp)
+ }
+ _ => it.clone(),
+ })
+ .collect();
- let mut fn_generics = generics.clone();
- fn_generics
- .params
- .insert(0, GenericParam::Lifetime(lifetime.clone()));
+ quote! { <#struct_generics> }
+ } else {
+ quote! { #generics }
+ };
- (quote! { #lifetime, }, fn_generics)
- };
-
- let generics_no_bounds = {
- let mut generics = generics.clone();
- generics.params = generics
- .params
- .iter()
- .map(|it| match it {
- GenericParam::Type(tp) => {
- let mut tp = tp.clone();
- tp.bounds.clear();
-
- GenericParam::Type(tp)
- }
- _ => it.clone(),
- })
- .collect();
-
- generics
- };
-
- parse_quote! {
- #(#fn_attrs)*
- #asyncness #vis fn #fn_ident #fn_generics (#cx_pat: Scope<#scope_lifetime #struct_ident #generics_no_bounds>) #fn_output
- #where_clause
- {
- let #struct_ident { #(#struct_field_names),* } = cx_pat.props;
- #fn_block
- }
+ parse_quote! {
+ #struct_attrs
+ #[allow(non_camel_case_types)]
+ #vis struct #struct_ident #struct_generics
+ {
+ #(#struct_fields),*
}
}
}
+
+fn get_props_docs(fn_ident: &Ident, inputs: Vec<&FnArg>) -> Vec {
+ if inputs.len() <= 1 {
+ return Vec::new();
+ }
+
+ let arg_docs = inputs
+ .iter()
+ .filter_map(|f| match f {
+ FnArg::Receiver(_) => unreachable!(), // ComponentBody prohibits receiver parameters.
+ FnArg::Typed(pt) => {
+ let arg_doc = pt
+ .attrs
+ .iter()
+ .filter_map(|attr| {
+ // TODO: Error reporting
+ // Check if the path of the attribute is "doc"
+ if !is_attr_doc(attr) {
+ return None;
+ };
+
+ let Meta::NameValue(meta_name_value) = &attr.meta else {
+ return None;
+ };
+
+ let Expr::Lit(doc_lit) = &meta_name_value.value else {
+ return None;
+ };
+
+ let Lit::Str(doc_lit_str) = &doc_lit.lit else {
+ return None;
+ };
+
+ Some(doc_lit_str.value())
+ })
+ .fold(String::new(), |mut doc, next_doc_line| {
+ doc.push('\n');
+ doc.push_str(&next_doc_line);
+ doc
+ });
+
+ Some((
+ &pt.pat,
+ &pt.ty,
+ pt.attrs.iter().find_map(|attr| {
+ if attr.path() != &parse_quote!(deprecated) {
+ return None;
+ }
+
+ let res = crate::utils::DeprecatedAttribute::from_meta(&attr.meta);
+
+ match res {
+ Err(e) => panic!("{}", e.to_string()),
+ Ok(v) => Some(v),
+ }
+ }),
+ arg_doc,
+ ))
+ }
+ })
+ .collect::>();
+
+ let mut props_docs = Vec::with_capacity(5);
+ let props_def_link = fn_ident.to_string() + "Props";
+ let header =
+ format!("# Props\n*For details, see the [props struct definition]({props_def_link}).*");
+
+ props_docs.push(parse_quote! {
+ #[doc = #header]
+ });
+
+ for (arg_name, arg_type, deprecation, input_arg_doc) in arg_docs {
+ let arg_name = arg_name.into_token_stream().to_string();
+ let arg_type = crate::utils::format_type_string(arg_type);
+
+ let input_arg_doc = keep_up_to_n_consecutive_chars(input_arg_doc.trim(), 2, '\n')
+ .replace("\n\n", "
");
+ let prop_def_link = format!("{props_def_link}::{arg_name}");
+ let mut arg_doc = format!("- [`{arg_name}`]({prop_def_link}) : `{arg_type}`");
+
+ if let Some(deprecation) = deprecation {
+ arg_doc.push_str("
👎 Deprecated");
+
+ if let Some(since) = deprecation.since {
+ arg_doc.push_str(&format!(" since {since}"));
+ }
+
+ if let Some(note) = deprecation.note {
+ let note = keep_up_to_n_consecutive_chars(¬e, 1, '\n').replace('\n', " ");
+ let note = keep_up_to_n_consecutive_chars(¬e, 1, '\t').replace('\t', " ");
+
+ arg_doc.push_str(&format!(": {note}"));
+ }
+
+ arg_doc.push_str("
");
+
+ if !input_arg_doc.is_empty() {
+ arg_doc.push_str(" ");
+ }
+ }
+
+ if !input_arg_doc.is_empty() {
+ arg_doc.push_str(&format!("{input_arg_doc}
"));
+ }
+
+ props_docs.push(parse_quote! {
+ #[doc = #arg_doc]
+ });
+ }
+
+ props_docs
+}
+
+fn get_function(component_body: &ComponentBody) -> ItemFn {
+ let ComponentBody {
+ item_fn,
+ cx_pat_type,
+ ..
+ } = component_body;
+ let ItemFn {
+ attrs: fn_attrs,
+ vis,
+ sig,
+ block: fn_block,
+ } = item_fn;
+ let Signature {
+ inputs,
+ ident: fn_ident,
+ generics,
+ output: fn_output,
+ asyncness,
+ ..
+ } = sig;
+ let Generics { where_clause, .. } = generics;
+
+ let cx_pat = &cx_pat_type.pat;
+ let struct_ident = Ident::new(&format!("{fn_ident}Props"), fn_ident.span());
+
+ // Skip first arg since that's the context
+ let struct_field_names = inputs.iter().skip(1).filter_map(|f| match f {
+ FnArg::Receiver(_) => unreachable!(), // ComponentBody prohibits receiver parameters.
+ FnArg::Typed(pt) => Some(&pt.pat),
+ });
+
+ let first_lifetime = if let Some(GenericParam::Lifetime(lt)) = generics.params.first() {
+ Some(lt)
+ } else {
+ None
+ };
+
+ let (scope_lifetime, fn_generics) = if let Some(lt) = first_lifetime {
+ (quote! { #lt, }, generics.clone())
+ } else {
+ let lifetime: LifetimeParam = parse_quote! { 'a };
+
+ let mut fn_generics = generics.clone();
+ fn_generics
+ .params
+ .insert(0, GenericParam::Lifetime(lifetime.clone()));
+
+ (quote! { #lifetime, }, fn_generics)
+ };
+
+ let generics_no_bounds = {
+ let mut generics = generics.clone();
+ generics.params = generics
+ .params
+ .iter()
+ .map(|it| match it {
+ GenericParam::Type(tp) => {
+ let mut tp = tp.clone();
+ tp.bounds.clear();
+
+ GenericParam::Type(tp)
+ }
+ _ => it.clone(),
+ })
+ .collect();
+
+ generics
+ };
+
+ let props_docs = get_props_docs(fn_ident, inputs.iter().skip(1).collect());
+
+ parse_quote! {
+ #(#fn_attrs)*
+ #(#props_docs)*
+ #asyncness #vis fn #fn_ident #fn_generics (#cx_pat: Scope<#scope_lifetime #struct_ident #generics_no_bounds>) #fn_output
+ #where_clause
+ {
+ let #struct_ident { #(#struct_field_names),* } = cx_pat.props;
+ #fn_block
+ }
+ }
+}
+
+/// Checks if the attribute is a `#[doc]` attribute.
+fn is_attr_doc(attr: &Attribute) -> bool {
+ attr.path() == &parse_quote!(doc)
+}
+
+fn keep_up_to_n_consecutive_chars(
+ input: &str,
+ n_of_consecutive_chars_allowed: usize,
+ target_char: char,
+) -> String {
+ let mut output = String::new();
+ let mut prev_char: Option = None;
+ let mut consecutive_count = 0;
+
+ for c in input.chars() {
+ match prev_char {
+ Some(prev) if c == target_char && prev == target_char => {
+ if consecutive_count < n_of_consecutive_chars_allowed {
+ output.push(c);
+ consecutive_count += 1;
+ }
+ }
+ _ => {
+ output.push(c);
+ prev_char = Some(c);
+ consecutive_count = 1;
+ }
+ }
+ }
+
+ output
+}
diff --git a/packages/core-macro/src/lib.rs b/packages/core-macro/src/lib.rs
index d91c72e39..4686bc797 100644
--- a/packages/core-macro/src/lib.rs
+++ b/packages/core-macro/src/lib.rs
@@ -1,3 +1,7 @@
+#![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")]
+
use proc_macro::TokenStream;
use quote::ToTokens;
use rsx::RenderCallBody;
@@ -8,6 +12,7 @@ use syn::{parse_macro_input, Path, Token};
mod component_body;
mod component_body_deserializers;
mod props;
+mod utils;
// mod rsx;
use crate::component_body::ComponentBody;
diff --git a/packages/core-macro/src/props/mod.rs b/packages/core-macro/src/props/mod.rs
index c1931e497..6e6c43d66 100644
--- a/packages/core-macro/src/props/mod.rs
+++ b/packages/core-macro/src/props/mod.rs
@@ -551,18 +551,16 @@ mod struct_info {
let generics_with_empty = modify_types_generics_hack(&ty_generics, |args| {
args.insert(0, syn::GenericArgument::Type(empties_tuple.clone().into()));
});
- let phantom_generics = self.generics.params.iter().map(|param| match param {
+ let phantom_generics = self.generics.params.iter().filter_map(|param| match param {
syn::GenericParam::Lifetime(lifetime) => {
let lifetime = &lifetime.lifetime;
- quote!(::core::marker::PhantomData<lifetime ()>)
+ Some(quote!(::core::marker::PhantomData<lifetime ()>))
}
syn::GenericParam::Type(ty) => {
let ty = &ty.ident;
- quote!(::core::marker::PhantomData<#ty>)
- }
- syn::GenericParam::Const(_cnst) => {
- quote!()
+ Some(quote!(::core::marker::PhantomData<#ty>))
}
+ syn::GenericParam::Const(_cnst) => None,
});
let builder_method_doc = match self.builder_attr.builder_method_doc {
Some(ref doc) => quote!(#doc),
@@ -633,7 +631,7 @@ Finally, call `.build()` to create the instance of `{name}`.
Ok(quote! {
impl #impl_generics #name #ty_generics #where_clause {
#[doc = #builder_method_doc]
- #[allow(dead_code)]
+ #[allow(dead_code, clippy::type_complexity)]
#vis fn builder() -> #builder_name #generics_with_empty {
#builder_name {
fields: #empties_tuple,
@@ -701,6 +699,14 @@ Finally, call `.build()` to create the instance of `{name}`.
}
pub fn field_impl(&self, field: &FieldInfo) -> Result {
+ let FieldInfo {
+ name: field_name,
+ ty: field_type,
+ ..
+ } = field;
+ if *field_name == "key" {
+ return Err(Error::new_spanned(field_name, "Naming a prop `key` is not allowed because the name can conflict with the built in key attribute. See https://dioxuslabs.com/learn/0.4/reference/dynamic_rendering#rendering-lists for more information about keys"));
+ }
let StructInfo {
ref builder_name, ..
} = *self;
@@ -715,11 +721,6 @@ Finally, call `.build()` to create the instance of `{name}`.
});
let reconstructing = self.included_fields().map(|f| f.name);
- let FieldInfo {
- name: field_name,
- ty: field_type,
- ..
- } = field;
let mut ty_generics: Vec = self
.generics
.params
@@ -822,6 +823,7 @@ Finally, call `.build()` to create the instance of `{name}`.
#[allow(dead_code, non_camel_case_types, missing_docs)]
impl #impl_generics #builder_name < #( #ty_generics ),* > #where_clause {
#doc
+ #[allow(clippy::type_complexity)]
pub fn #field_name (self, #field_name: #arg_type) -> #builder_name < #( #target_generics ),* > {
let #field_name = (#arg_expr,);
let ( #(#descructuring,)* ) = self.fields;
@@ -840,6 +842,7 @@ Finally, call `.build()` to create the instance of `{name}`.
#[deprecated(
note = #repeated_fields_error_message
)]
+ #[allow(clippy::type_complexity)]
pub fn #field_name (self, _: #repeated_fields_error_type_name) -> #builder_name < #( #target_generics ),* > {
self
}
diff --git a/packages/core-macro/src/utils.rs b/packages/core-macro/src/utils.rs
new file mode 100644
index 000000000..7e066f773
--- /dev/null
+++ b/packages/core-macro/src/utils.rs
@@ -0,0 +1,129 @@
+use quote::ToTokens;
+use syn::parse::{Parse, ParseStream};
+use syn::spanned::Spanned;
+use syn::{parse_quote, Expr, Lit, Meta, Token, Type};
+
+const FORMATTED_TYPE_START: &str = "static TY_AFTER_HERE:";
+const FORMATTED_TYPE_END: &str = "= todo!();";
+
+/// Attempts to convert the given literal to a string.
+/// Converts ints and floats to their base 10 counterparts.
+///
+/// Returns `None` if the literal is [`Lit::Verbatim`] or if the literal is [`Lit::ByteStr`]
+/// and the byte string could not be converted to UTF-8.
+pub fn lit_to_string(lit: Lit) -> Option {
+ match lit {
+ Lit::Str(l) => Some(l.value()),
+ Lit::ByteStr(l) => String::from_utf8(l.value()).ok(),
+ Lit::Byte(l) => Some(String::from(l.value() as char)),
+ Lit::Char(l) => Some(l.value().to_string()),
+ Lit::Int(l) => Some(l.base10_digits().to_string()),
+ Lit::Float(l) => Some(l.base10_digits().to_string()),
+ Lit::Bool(l) => Some(l.value().to_string()),
+ Lit::Verbatim(_) => None,
+ _ => None,
+ }
+}
+
+pub fn format_type_string(ty: &Type) -> String {
+ let ty_unformatted = ty.into_token_stream().to_string();
+ let ty_unformatted = ty_unformatted.trim();
+
+ // This should always be valid syntax.
+ // Not Rust code, but syntax, which is the only thing that `syn` cares about.
+ let Ok(file_unformatted) = syn::parse_file(&format!(
+ "{FORMATTED_TYPE_START}{ty_unformatted}{FORMATTED_TYPE_END}"
+ )) else {
+ return ty_unformatted.to_string();
+ };
+
+ let file_formatted = prettyplease::unparse(&file_unformatted);
+
+ let file_trimmed = file_formatted.trim();
+ let start_removed = file_trimmed.trim_start_matches(FORMATTED_TYPE_START);
+ let end_removed = start_removed.trim_end_matches(FORMATTED_TYPE_END);
+ let ty_formatted = end_removed.trim();
+
+ ty_formatted.to_string()
+}
+
+/// Represents the `#[deprecated]` attribute.
+///
+/// You can use the [`DeprecatedAttribute::from_meta`] function to try to parse an attribute to this struct.
+#[derive(Default)]
+pub struct DeprecatedAttribute {
+ pub since: Option,
+ pub note: Option,
+}
+
+impl DeprecatedAttribute {
+ /// Returns `None` if the given attribute was not a valid form of the `#[deprecated]` attribute.
+ pub fn from_meta(meta: &Meta) -> syn::Result {
+ if meta.path() != &parse_quote!(deprecated) {
+ return Err(syn::Error::new(
+ meta.span(),
+ "attribute path is not `deprecated`",
+ ));
+ }
+
+ match &meta {
+ Meta::Path(_) => Ok(Self::default()),
+ Meta::NameValue(name_value) => {
+ let Expr::Lit(expr_lit) = &name_value.value else {
+ return Err(syn::Error::new(
+ name_value.span(),
+ "literal in `deprecated` value must be a string",
+ ));
+ };
+
+ Ok(Self {
+ since: None,
+ note: lit_to_string(expr_lit.lit.clone()).map(|s| s.trim().to_string()),
+ })
+ }
+ Meta::List(list) => {
+ let parsed = list.parse_args::()?;
+
+ Ok(Self {
+ since: parsed.since.map(|s| s.trim().to_string()),
+ note: parsed.note.map(|s| s.trim().to_string()),
+ })
+ }
+ }
+ }
+}
+
+mod kw {
+ use syn::custom_keyword;
+ custom_keyword!(since);
+ custom_keyword!(note);
+}
+
+struct DeprecatedAttributeArgsParser {
+ since: Option,
+ note: Option,
+}
+
+impl Parse for DeprecatedAttributeArgsParser {
+ fn parse(input: ParseStream) -> syn::Result {
+ let mut since: Option = None;
+ let mut note: Option = None;
+
+ if input.peek(kw::since) {
+ input.parse::()?;
+ input.parse::()?;
+
+ since = lit_to_string(input.parse()?);
+ }
+
+ if input.peek(Token![,]) && input.peek2(kw::note) {
+ input.parse::()?;
+ input.parse::()?;
+ input.parse::()?;
+
+ note = lit_to_string(input.parse()?);
+ }
+
+ Ok(Self { since, note })
+ }
+}
diff --git a/packages/core/src/arena.rs b/packages/core/src/arena.rs
index b7f768755..785d4b174 100644
--- a/packages/core/src/arena.rs
+++ b/packages/core/src/arena.rs
@@ -164,17 +164,11 @@ impl VirtualDom {
});
// Now that all the references are gone, we can safely drop our own references in our listeners.
- let mut listeners = scope.attributes_to_drop.borrow_mut();
+ let mut listeners = scope.attributes_to_drop_before_render.borrow_mut();
listeners.drain(..).for_each(|listener| {
let listener = unsafe { &*listener };
- match &listener.value {
- AttributeValue::Listener(l) => {
- _ = l.take();
- }
- AttributeValue::Any(a) => {
- _ = a.take();
- }
- _ => (),
+ if let AttributeValue::Listener(l) = &listener.value {
+ _ = l.take();
}
});
}
diff --git a/packages/core/src/bump_frame.rs b/packages/core/src/bump_frame.rs
index 0fe7b3867..bf630c605 100644
--- a/packages/core/src/bump_frame.rs
+++ b/packages/core/src/bump_frame.rs
@@ -1,10 +1,13 @@
use crate::nodes::RenderReturn;
+use crate::{Attribute, AttributeValue};
use bumpalo::Bump;
+use std::cell::RefCell;
use std::cell::{Cell, UnsafeCell};
pub(crate) struct BumpFrame {
pub bump: UnsafeCell,
pub node: Cell<*const RenderReturn<'static>>,
+ pub(crate) attributes_to_drop_before_reset: RefCell>>,
}
impl BumpFrame {
@@ -13,6 +16,7 @@ impl BumpFrame {
Self {
bump: UnsafeCell::new(bump),
node: Cell::new(std::ptr::null()),
+ attributes_to_drop_before_reset: Default::default(),
}
}
@@ -31,8 +35,23 @@ impl BumpFrame {
unsafe { &*self.bump.get() }
}
- #[allow(clippy::mut_from_ref)]
- pub(crate) unsafe fn bump_mut(&self) -> &mut Bump {
- unsafe { &mut *self.bump.get() }
+ pub(crate) fn add_attribute_to_drop(&self, attribute: *const Attribute<'static>) {
+ self.attributes_to_drop_before_reset
+ .borrow_mut()
+ .push(attribute);
+ }
+
+ pub(crate) unsafe fn reset(&self) {
+ let mut attributes = self.attributes_to_drop_before_reset.borrow_mut();
+ attributes.drain(..).for_each(|attribute| {
+ let attribute = unsafe { &*attribute };
+ if let AttributeValue::Any(l) = &attribute.value {
+ _ = l.take();
+ }
+ });
+ unsafe {
+ let bump = &mut *self.bump.get();
+ bump.reset();
+ }
}
}
diff --git a/packages/core/src/lib.rs b/packages/core/src/lib.rs
index 5b2f83305..392774767 100644
--- a/packages/core/src/lib.rs
+++ b/packages/core/src/lib.rs
@@ -1,4 +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")]
#![warn(missing_docs)]
mod any_props;
@@ -32,7 +34,7 @@ pub(crate) mod innerlude {
pub use crate::nodes::RenderReturn;
pub use crate::nodes::*;
pub use crate::properties::*;
- pub use crate::runtime::{in_runtime, override_runtime, Runtime};
+ pub use crate::runtime::{Runtime, RuntimeGuard};
pub use crate::scheduler::*;
pub use crate::scope_context::*;
pub use crate::scopes::*;
@@ -87,11 +89,11 @@ pub use crate::innerlude::{
pub mod prelude {
pub use crate::innerlude::{
consume_context, consume_context_from_scope, current_scope_id, fc_to_builder, has_context,
- in_runtime, override_runtime, provide_context, provide_context_to_scope,
- provide_root_context, push_future, remove_future, schedule_update_any, spawn,
- spawn_forever, suspend, throw, AnyValue, Component, Element, Event, EventHandler, Fragment,
- IntoAttributeValue, LazyNodes, Properties, Runtime, Scope, ScopeId, ScopeState, Scoped,
- TaskId, Template, TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
+ provide_context, provide_context_to_scope, provide_root_context, push_future,
+ remove_future, schedule_update_any, spawn, spawn_forever, suspend, throw, AnyValue,
+ Component, Element, Event, EventHandler, Fragment, IntoAttributeValue, IntoDynNode,
+ LazyNodes, Properties, Runtime, RuntimeGuard, Scope, ScopeId, ScopeState, Scoped, TaskId,
+ Template, TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
};
}
diff --git a/packages/core/src/runtime.rs b/packages/core/src/runtime.rs
index 4b9dcdab0..566e9ba7c 100644
--- a/packages/core/src/runtime.rs
+++ b/packages/core/src/runtime.rs
@@ -7,51 +7,6 @@ thread_local! {
static RUNTIMES: RefCell>> = RefCell::new(vec![]);
}
-/// Run some code within a runtime
-pub fn in_runtime(runtime: Rc, f: impl FnOnce() -> R) -> R {
- let _guard = RuntimeGuard::new(runtime);
- f()
-}
-
-/// Override the current runtime. This must be used to override the current runtime when importing components from a dynamic library that has it's own runtime.
-///
-/// ```rust
-/// use dioxus::prelude::*;
-///
-/// fn main() {
-/// let virtual_dom = VirtualDom::new(app);
-/// }
-///
-/// fn app(cx: Scope) -> Element {
-/// render!{ Component { runtime: Runtime::current().unwrap() } }
-/// }
-///
-/// // In a dynamic library
-/// #[derive(Props)]
-/// struct ComponentProps {
-/// runtime: std::rc::Rc,
-/// }
-///
-/// impl PartialEq for ComponentProps {
-/// fn eq(&self, _other: &Self) -> bool {
-/// true
-/// }
-/// }
-///
-/// fn Component(cx: Scope) -> Element {
-/// cx.use_hook(|| override_runtime(cx.props.runtime.clone()));
-///
-/// render! { div {} }
-/// }
-/// ```
-pub fn override_runtime(runtime: Rc) {
- RUNTIMES.with(|stack| {
- let mut stack = stack.borrow_mut();
- stack.pop();
- stack.push(runtime);
- });
-}
-
/// Pushes a new scope onto the stack
pub(crate) fn push_runtime(runtime: Rc) {
RUNTIMES.with(|stack| stack.borrow_mut().push(runtime));
@@ -143,10 +98,42 @@ impl Runtime {
}
}
-pub(crate) struct RuntimeGuard(Rc);
+/// A gaurd for a new runtime. This must be used to override the current runtime when importing components from a dynamic library that has it's own runtime.
+///
+/// ```rust
+/// use dioxus::prelude::*;
+///
+/// fn main() {
+/// let virtual_dom = VirtualDom::new(app);
+/// }
+///
+/// fn app(cx: Scope) -> Element {
+/// render!{ Component { runtime: Runtime::current().unwrap() } }
+/// }
+///
+/// // In a dynamic library
+/// #[derive(Props)]
+/// struct ComponentProps {
+/// runtime: std::rc::Rc,
+/// }
+///
+/// impl PartialEq for ComponentProps {
+/// fn eq(&self, _other: &Self) -> bool {
+/// true
+/// }
+/// }
+///
+/// fn Component(cx: Scope) -> Element {
+/// cx.use_hook(|| RuntimeGuard::new(cx.props.runtime.clone()));
+///
+/// render! { div {} }
+/// }
+/// ```
+pub struct RuntimeGuard(Rc);
impl RuntimeGuard {
- pub(crate) fn new(runtime: Rc) -> Self {
+ /// Create a new runtime guard that sets the current Dioxus runtime. The runtime will be reset when the guard is dropped
+ pub fn new(runtime: Rc) -> Self {
push_runtime(runtime.clone());
Self(runtime)
}
diff --git a/packages/core/src/scope_arena.rs b/packages/core/src/scope_arena.rs
index 1ed5b816c..397f5328e 100644
--- a/packages/core/src/scope_arena.rs
+++ b/packages/core/src/scope_arena.rs
@@ -35,7 +35,7 @@ impl VirtualDom {
hook_idx: Default::default(),
borrowed_props: Default::default(),
- attributes_to_drop: Default::default(),
+ attributes_to_drop_before_render: Default::default(),
}));
let context =
@@ -54,7 +54,7 @@ impl VirtualDom {
let new_nodes = unsafe {
let scope = &self.scopes[scope_id.0];
- scope.previous_frame().bump_mut().reset();
+ scope.previous_frame().reset();
scope.context().suspended.set(false);
diff --git a/packages/core/src/scopes.rs b/packages/core/src/scopes.rs
index 996529a0d..3fd2aac30 100644
--- a/packages/core/src/scopes.rs
+++ b/packages/core/src/scopes.rs
@@ -94,7 +94,7 @@ pub struct ScopeState {
pub(crate) hook_idx: Cell,
pub(crate) borrowed_props: RefCell>>,
- pub(crate) attributes_to_drop: RefCell>>,
+ pub(crate) attributes_to_drop_before_render: RefCell>>,
pub(crate) props: Option>>,
}
@@ -348,13 +348,19 @@ impl<'src> ScopeState {
pub fn render(&'src self, rsx: LazyNodes<'src, '_>) -> Element<'src> {
let element = rsx.call(self);
- let mut listeners = self.attributes_to_drop.borrow_mut();
+ let mut listeners = self.attributes_to_drop_before_render.borrow_mut();
for attr in element.dynamic_attrs {
match attr.value {
- AttributeValue::Any(_) | AttributeValue::Listener(_) => {
+ // We need to drop listeners before the next render because they may borrow data from the borrowed props which will be dropped
+ AttributeValue::Listener(_) => {
let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
listeners.push(unbounded);
}
+ // We need to drop any values manually to make sure that their drop implementation is called before the next render
+ AttributeValue::Any(_) => {
+ let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
+ self.previous_frame().add_attribute_to_drop(unbounded);
+ }
_ => (),
}
diff --git a/packages/desktop/Cargo.toml b/packages/desktop/Cargo.toml
index a884928ba..dcb994120 100644
--- a/packages/desktop/Cargo.toml
+++ b/packages/desktop/Cargo.toml
@@ -56,6 +56,7 @@ tokio_runtime = ["tokio"]
fullscreen = ["wry/fullscreen"]
transparent = ["wry/transparent"]
devtools = ["wry/devtools"]
+tray = ["wry/tray"]
dox = ["wry/dox"]
hot-reload = ["dioxus-hot-reload"]
diff --git a/packages/desktop/src/lib.rs b/packages/desktop/src/lib.rs
index badbe3276..bfefaf547 100644
--- a/packages/desktop/src/lib.rs
+++ b/packages/desktop/src/lib.rs
@@ -161,6 +161,7 @@ pub fn launch_with_props(root: Component, props: P, cfg: Config)
// iOS panics if we create a window before the event loop is started
let props = Rc::new(Cell::new(Some(props)));
let cfg = Rc::new(Cell::new(Some(cfg)));
+ let mut is_visible_before_start = true;
event_loop.run(move |window_event, event_loop, control_flow| {
*control_flow = ControlFlow::Wait;
@@ -210,6 +211,8 @@ pub fn launch_with_props(root: Component, props: P, cfg: Config)
// Create a dom
let dom = VirtualDom::new_with_props(root, props);
+ is_visible_before_start = cfg.window.window.visible;
+
let handler = create_new_window(
cfg,
event_loop,
@@ -323,6 +326,10 @@ pub fn launch_with_props(root: Component, props: P, cfg: Config)
EventData::Ipc(msg) if msg.method() == "initialize" => {
let view = webviews.get_mut(&event.1).unwrap();
send_edits(view.dom.rebuild(), &view.desktop_context.webview);
+ view.desktop_context
+ .webview
+ .window()
+ .set_visible(is_visible_before_start);
}
EventData::Ipc(msg) if msg.method() == "browser_open" => {
diff --git a/packages/desktop/src/protocol.rs b/packages/desktop/src/protocol.rs
index 53652f82f..2f660b7a2 100644
--- a/packages/desktop/src/protocol.rs
+++ b/packages/desktop/src/protocol.rs
@@ -153,7 +153,7 @@ fn get_asset_root() -> Option {
/// Get the mime type from a path-like string
fn get_mime_from_path(trimmed: &Path) -> Result<&'static str> {
- if trimmed.ends_with(".svg") {
+ if trimmed.extension().is_some_and(|ext| ext == "svg") {
return Ok("image/svg+xml");
}
diff --git a/packages/desktop/src/webview.rs b/packages/desktop/src/webview.rs
index 469aa8068..6e6d26b17 100644
--- a/packages/desktop/src/webview.rs
+++ b/packages/desktop/src/webview.rs
@@ -13,7 +13,7 @@ pub fn build(
proxy: EventLoopProxy,
) -> (WebView, WebContext) {
let builder = cfg.window.clone();
- let window = builder.build(event_loop).unwrap();
+ let window = builder.with_visible(false).build(event_loop).unwrap();
let file_handler = cfg.file_drop_handler.take();
let custom_head = cfg.custom_head.clone();
let index_file = cfg.custom_index.clone();
diff --git a/packages/dioxus-tui/Cargo.toml b/packages/dioxus-tui/Cargo.toml
index 0d0bb59f4..47ff3f536 100644
--- a/packages/dioxus-tui/Cargo.toml
+++ b/packages/dioxus-tui/Cargo.toml
@@ -10,7 +10,6 @@ keywords = ["dom", "ui", "gui", "react", "terminal"]
license = "MIT OR Apache-2.0"
[dependencies]
-dioxus = { workspace = true }
dioxus-core = { workspace = true, features = ["serialize"] }
dioxus-html = { workspace = true }
dioxus-native-core = { workspace = true, features = ["dioxus"] }
diff --git a/packages/dioxus-tui/src/lib.rs b/packages/dioxus-tui/src/lib.rs
index fd5b63501..ca0f0a07d 100644
--- a/packages/dioxus-tui/src/lib.rs
+++ b/packages/dioxus-tui/src/lib.rs
@@ -1,3 +1,7 @@
+#![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")]
+
mod element;
use std::{
diff --git a/packages/dioxus/src/lib.rs b/packages/dioxus/src/lib.rs
index bc2cd76e6..6256e96d7 100644
--- a/packages/dioxus/src/lib.rs
+++ b/packages/dioxus/src/lib.rs
@@ -1,3 +1,7 @@
+#![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")]
+
pub use dioxus_core as core;
#[cfg(feature = "hooks")]
diff --git a/packages/fermi/src/callback.rs b/packages/fermi/src/callback.rs
index a7ca9155f..bb9f61bf2 100644
--- a/packages/fermi/src/callback.rs
+++ b/packages/fermi/src/callback.rs
@@ -28,6 +28,7 @@ impl CallbackApi {
}
}
+#[must_use]
pub fn use_atom_context(cx: &ScopeState) -> &CallbackApi {
todo!()
}
diff --git a/packages/fermi/src/hooks/atom_ref.rs b/packages/fermi/src/hooks/atom_ref.rs
index 74dd9268b..8dbeb2c4d 100644
--- a/packages/fermi/src/hooks/atom_ref.rs
+++ b/packages/fermi/src/hooks/atom_ref.rs
@@ -13,6 +13,7 @@ use std::{
///
///
///
+#[must_use]
pub fn use_atom_ref<'a, T: 'static>(
cx: &'a ScopeState,
atom: &'static AtomRef,
diff --git a/packages/fermi/src/hooks/atom_root.rs b/packages/fermi/src/hooks/atom_root.rs
index 24fd70093..468f5f980 100644
--- a/packages/fermi/src/hooks/atom_root.rs
+++ b/packages/fermi/src/hooks/atom_root.rs
@@ -7,6 +7,6 @@ use dioxus_core::ScopeState;
pub fn use_atom_root(cx: &ScopeState) -> &Rc {
cx.use_hook(|| match cx.consume_context::>() {
Some(root) => root,
- None => panic!("No atom root found in context. Did you forget place an AtomRoot component at the top of your app?"),
+ None => panic!("No atom root found in context. Did you forget to call use_init_atom_root at the top of your app?"),
})
}
diff --git a/packages/fermi/src/hooks/read.rs b/packages/fermi/src/hooks/read.rs
index 57a544e93..c2538c74d 100644
--- a/packages/fermi/src/hooks/read.rs
+++ b/packages/fermi/src/hooks/read.rs
@@ -2,10 +2,12 @@ use crate::{use_atom_root, AtomId, AtomRoot, Readable};
use dioxus_core::{ScopeId, ScopeState};
use std::rc::Rc;
+#[must_use]
pub fn use_read(cx: &ScopeState, f: impl Readable) -> &V {
use_read_rc(cx, f).as_ref()
}
+#[must_use]
pub fn use_read_rc(cx: &ScopeState, f: impl Readable) -> &Rc {
let root = use_atom_root(cx);
diff --git a/packages/fermi/src/hooks/set.rs b/packages/fermi/src/hooks/set.rs
index 5e5141227..89fe48b0f 100644
--- a/packages/fermi/src/hooks/set.rs
+++ b/packages/fermi/src/hooks/set.rs
@@ -2,6 +2,7 @@ use crate::{use_atom_root, Writable};
use dioxus_core::ScopeState;
use std::rc::Rc;
+#[must_use]
pub fn use_set(cx: &ScopeState, f: impl Writable) -> &Rc {
let root = use_atom_root(cx);
cx.use_hook(|| {
diff --git a/packages/fermi/src/hooks/state.rs b/packages/fermi/src/hooks/state.rs
index 071b18059..7d473588a 100644
--- a/packages/fermi/src/hooks/state.rs
+++ b/packages/fermi/src/hooks/state.rs
@@ -30,6 +30,7 @@ use std::{
/// ))
/// }
/// ```
+#[must_use]
pub fn use_atom_state(cx: &ScopeState, f: impl Writable) -> &AtomState {
let root = crate::use_atom_root(cx);
@@ -85,7 +86,9 @@ impl AtomState {
/// ```
#[must_use]
pub fn current(&self) -> Rc {
- self.value.as_ref().unwrap().clone()
+ let atoms = self.root.atoms.borrow();
+ let slot = atoms.get(&self.id).unwrap();
+ slot.value.clone().downcast().unwrap()
}
/// Get the `setter` function directly without the `AtomState` wrapper.
diff --git a/packages/fermi/src/lib.rs b/packages/fermi/src/lib.rs
index 4943e38a3..52bf4cd09 100644
--- a/packages/fermi/src/lib.rs
+++ b/packages/fermi/src/lib.rs
@@ -1,4 +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")]
pub mod prelude {
pub use crate::*;
diff --git a/packages/fullstack/Cargo.toml b/packages/fullstack/Cargo.toml
index 8ab213e78..8de27a9b1 100644
--- a/packages/fullstack/Cargo.toml
+++ b/packages/fullstack/Cargo.toml
@@ -11,7 +11,7 @@ keywords = ["ui", "gui", "react", "ssr", "fullstack"]
[dependencies]
# server functions
-server_fn = { version = "0.4.6", default-features = false }
+server_fn = { version = "0.5.2", default-features = false }
dioxus_server_macro = { workspace = true }
# warp
diff --git a/packages/fullstack/src/hooks/server_future.rs b/packages/fullstack/src/hooks/server_future.rs
index e4d89480e..f8eaef963 100644
--- a/packages/fullstack/src/hooks/server_future.rs
+++ b/packages/fullstack/src/hooks/server_future.rs
@@ -22,6 +22,7 @@ use std::sync::Arc;
/// will be allowed to continue
///
/// - dependencies: a tuple of references to values that are PartialEq + Clone
+#[must_use = "Consider using `cx.spawn` to run a future without reading its value"]
pub fn use_server_future(
cx: &ScopeState,
dependencies: D,
diff --git a/packages/fullstack/src/launch.rs b/packages/fullstack/src/launch.rs
index c982a1c90..bd145f363 100644
--- a/packages/fullstack/src/launch.rs
+++ b/packages/fullstack/src/launch.rs
@@ -121,8 +121,15 @@ impl for DioxusServerFnRegistry {
}
}
- fn register(
- url: &'static str,
- server_function: ServerFunction,
- encoding: server_fn::Encoding,
- ) -> Result<(), Self::Error> {
- Self::register_explicit("", url, server_function, encoding)
- }
-
/// Returns the server function registered at the given URL, or `None` if no function is registered at that URL.
fn get(url: &str) -> Option> {
REGISTERED_SERVER_FUNCTIONS
diff --git a/packages/generational-box/README.md b/packages/generational-box/README.md
index 5ab7926ba..7d3088eda 100644
--- a/packages/generational-box/README.md
+++ b/packages/generational-box/README.md
@@ -31,4 +31,4 @@ let store = Store::default();
## How it works
-Internally
\ No newline at end of file
+Internally, `generational-box` creates an arena of generational RefCell's that are recyled when the owner is dropped. You can think of the cells as something like `&'static RefCell>` with a generational check to make recyling a cell easier to debug. Then GenerationalBox's are `Copy` because the `&'static` pointer is `Copy`
diff --git a/packages/generational-box/src/lib.rs b/packages/generational-box/src/lib.rs
index 60bd41419..4be383b4f 100644
--- a/packages/generational-box/src/lib.rs
+++ b/packages/generational-box/src/lib.rs
@@ -184,7 +184,7 @@ impl GenerationalBox {
}
/// Try to read the value. Returns None if the value is no longer valid.
- pub fn try_read(&self) -> Option[> {
+ pub fn try_read(&self) -> Option][> {
self.validate()
.then(|| {
Ref::filter_map(self.raw.data.borrow(), |any| {
@@ -196,12 +196,12 @@ impl] GenerationalBox {
}
/// Read the value. Panics if the value is no longer valid.
- pub fn read(&self) -> Ref<'_, T> {
+ pub fn read(&self) -> Ref<'static, T> {
self.try_read().unwrap()
}
/// Try to write the value. Returns None if the value is no longer valid.
- pub fn try_write(&self) -> Option> {
+ pub fn try_write(&self) -> Option> {
self.validate()
.then(|| {
RefMut::filter_map(self.raw.data.borrow_mut(), |any| {
@@ -213,7 +213,7 @@ impl GenerationalBox {
}
/// Write the value. Panics if the value is no longer valid.
- pub fn write(&self) -> RefMut<'_, T> {
+ pub fn write(&self) -> RefMut<'static, T> {
self.try_write().unwrap()
}
diff --git a/packages/hooks/src/computed.rs b/packages/hooks/src/computed.rs
index 3369d6832..dbea75d73 100644
--- a/packages/hooks/src/computed.rs
+++ b/packages/hooks/src/computed.rs
@@ -37,6 +37,7 @@ use std::{
/// }
/// }
/// ```
+#[must_use]
pub fn use_tracked_state(cx: &ScopeState, init: impl FnOnce() -> T) -> &Tracked {
cx.use_hook(|| {
let init = init();
@@ -160,6 +161,7 @@ impl Drop for Tracker {
}
}
+#[must_use = "Consider using the `use_effect` hook to rerun an effect whenever the tracked state changes if you don't need the result of the computation"]
pub fn use_selector(
cx: &ScopeState,
tracked: &Tracked,
diff --git a/packages/hooks/src/lib.rs b/packages/hooks/src/lib.rs
index 6d7ab6f53..a5b92a036 100644
--- a/packages/hooks/src/lib.rs
+++ b/packages/hooks/src/lib.rs
@@ -1,7 +1,10 @@
+#![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 environements.
+/// A helper macro for using hooks and properties in async environments.
///
/// # Usage
///
@@ -54,35 +57,37 @@ macro_rules! to_owned {
pub mod computed;
-mod use_on_unmount;
-pub use use_on_unmount::*;
+mod use_on_destroy;
+pub use use_on_destroy::*;
-mod usecontext;
-pub use usecontext::*;
+mod use_context;
+pub use use_context::*;
-mod usestate;
-pub use usestate::{use_state, UseState};
+mod use_state;
+pub use use_state::{use_state, UseState};
-mod useref;
-pub use useref::*;
+mod use_ref;
+pub use use_ref::*;
mod use_shared_state;
pub use use_shared_state::*;
-mod usecoroutine;
-pub use usecoroutine::*;
+mod use_coroutine;
+pub use use_coroutine::*;
-mod usefuture;
-pub use usefuture::*;
+mod use_future;
+pub use use_future::*;
-mod useeffect;
-pub use useeffect::*;
+mod use_effect;
+pub use use_effect::*;
-mod usecallback;
-pub use usecallback::*;
+mod use_callback;
+pub use use_callback::*;
-mod usememo;
-pub use usememo::*;
+mod use_memo;
+pub use use_memo::*;
-mod userootcontext;
-pub use userootcontext::*;
+mod use_on_create;
+pub use use_on_create::*;
+mod use_root_context;
+pub use use_root_context::*;
diff --git a/packages/hooks/src/usecallback.rs b/packages/hooks/src/use_callback.rs
similarity index 99%
rename from packages/hooks/src/usecallback.rs
rename to packages/hooks/src/use_callback.rs
index 3f223b581..52e592f6b 100644
--- a/packages/hooks/src/usecallback.rs
+++ b/packages/hooks/src/use_callback.rs
@@ -24,6 +24,7 @@ macro_rules! use_callback {
)
};
}
+
pub fn use_callback(cx: &ScopeState, make: impl FnOnce() -> R) -> impl FnMut(T) + '_
where
R: FnMut(T) -> F + 'static,
diff --git a/packages/hooks/src/usecollection.rs b/packages/hooks/src/use_collection.rs
similarity index 100%
rename from packages/hooks/src/usecollection.rs
rename to packages/hooks/src/use_collection.rs
diff --git a/packages/hooks/src/usecontext.rs b/packages/hooks/src/use_context.rs
similarity index 98%
rename from packages/hooks/src/usecontext.rs
rename to packages/hooks/src/use_context.rs
index fdf363252..0d94492f6 100644
--- a/packages/hooks/src/usecontext.rs
+++ b/packages/hooks/src/use_context.rs
@@ -3,6 +3,7 @@ use dioxus_core::ScopeState;
/// Consume some context in the tree, providing a sharable handle to the value
///
/// Does not regenerate the value if the value is changed at the parent.
+#[must_use]
pub fn use_context(cx: &ScopeState) -> Option<&T> {
cx.use_hook(|| cx.consume_context::()).as_ref()
}
diff --git a/packages/hooks/src/usecoroutine.rs b/packages/hooks/src/use_coroutine.rs
similarity index 99%
rename from packages/hooks/src/usecoroutine.rs
rename to packages/hooks/src/use_coroutine.rs
index e5563d793..f2577b90c 100644
--- a/packages/hooks/src/usecoroutine.rs
+++ b/packages/hooks/src/use_coroutine.rs
@@ -79,6 +79,7 @@ where
/// Get a handle to a coroutine higher in the tree
///
/// See the docs for [`use_coroutine`] for more details.
+#[must_use]
pub fn use_coroutine_handle(cx: &ScopeState) -> Option<&Coroutine> {
cx.use_hook(|| cx.consume_context::>())
.as_ref()
diff --git a/packages/hooks/src/useeffect.rs b/packages/hooks/src/use_effect.rs
similarity index 87%
rename from packages/hooks/src/useeffect.rs
rename to packages/hooks/src/use_effect.rs
index 76a3f5245..e72afe27f 100644
--- a/packages/hooks/src/useeffect.rs
+++ b/packages/hooks/src/use_effect.rs
@@ -3,13 +3,18 @@ use std::{any::Any, cell::Cell, future::Future};
use crate::UseFutureDep;
-/// A hook that provides a future that executes after the hooks have been applied
+/// A hook that provides a future that executes after the hooks have been applied.
///
/// Whenever the hooks dependencies change, the future will be re-evaluated.
/// If a future is pending when the dependencies change, the previous future
-/// will be allowed to continue
+/// will be allowed to continue.
///
-/// - dependencies: a tuple of references to values that are `PartialEq` + `Clone`
+/// **Note:** If your dependency list is always empty, use [`use_on_create`](crate::use_on_create).
+///
+/// ## Arguments
+///
+/// - `dependencies`: a tuple of references to values that are `PartialEq` + `Clone`.
+/// - `future`: a closure that takes the `dependencies` as arguments and returns a `'static` future.
///
/// ## Examples
///
diff --git a/packages/hooks/src/usefuture.rs b/packages/hooks/src/use_future.rs
similarity index 100%
rename from packages/hooks/src/usefuture.rs
rename to packages/hooks/src/use_future.rs
diff --git a/packages/hooks/src/usememo.rs b/packages/hooks/src/use_memo.rs
similarity index 93%
rename from packages/hooks/src/usememo.rs
rename to packages/hooks/src/use_memo.rs
index 3181d57b8..be61b8d53 100644
--- a/packages/hooks/src/usememo.rs
+++ b/packages/hooks/src/use_memo.rs
@@ -28,6 +28,7 @@ use crate::UseFutureDep;
/// render!(Calculator { number: 0 })
/// }
/// ```
+#[must_use = "Consider using `use_effect` to run rerun a callback when dependencies change"]
pub fn use_memo(cx: &ScopeState, dependencies: D, callback: impl FnOnce(D::Out) -> T) -> &T
where
T: 'static,
diff --git a/packages/hooks/src/usemodel.rs b/packages/hooks/src/use_model.rs
similarity index 100%
rename from packages/hooks/src/usemodel.rs
rename to packages/hooks/src/use_model.rs
diff --git a/packages/hooks/src/use_on_create.rs b/packages/hooks/src/use_on_create.rs
new file mode 100644
index 000000000..28f7bcd6f
--- /dev/null
+++ b/packages/hooks/src/use_on_create.rs
@@ -0,0 +1,27 @@
+use dioxus_core::ScopeState;
+use std::cell::Cell;
+use std::future::Future;
+
+/// A hook that runs a future when the component is mounted.
+///
+/// This is just [`use_effect`](crate::use_effect), but with no dependencies.
+/// If you have no dependencies, it's recommended to use this, not just because it's more readable,
+/// but also because it's a tiny bit more efficient.
+pub fn use_on_create(cx: &ScopeState, future: impl FnOnce() -> F)
+where
+ T: 'static,
+ F: Future + 'static,
+{
+ let needs_regen = cx.use_hook(|| Cell::new(true));
+
+ if needs_regen.get() {
+ // We don't need regen anymore
+ needs_regen.set(false);
+
+ let fut = future();
+
+ cx.push_future(async move {
+ fut.await;
+ });
+ }
+}
diff --git a/packages/hooks/src/use_on_unmount.rs b/packages/hooks/src/use_on_destroy.rs
similarity index 76%
rename from packages/hooks/src/use_on_unmount.rs
rename to packages/hooks/src/use_on_destroy.rs
index 1309ca122..8b09b6a20 100644
--- a/packages/hooks/src/use_on_unmount.rs
+++ b/packages/hooks/src/use_on_destroy.rs
@@ -1,9 +1,20 @@
-/// Creates a callback that will be run before the component is removed. This can be used to clean up side effects from the component (created with use_effect)
+#[deprecated(
+ note = "Use `use_on_destroy` instead, which has the same functionality. \
+This is deprecated because of the introduction of `use_on_create` which is better mirrored by `use_on_destroy`. \
+The reason why `use_on_create` is not `use_on_mount` is because of potential confusion with `dioxus::events::onmounted`."
+)]
+pub fn use_on_unmount(cx: &dioxus_core::ScopeState, destroy: D) {
+ use_on_destroy(cx, destroy);
+}
+
+/// Creates a callback that will be run before the component is removed.
+/// This can be used to clean up side effects from the component
+/// (created with [`use_effect`](crate::use_effect)).
///
/// Example:
/// ```rust
/// use dioxus::prelude::*;
-
+///
/// fn app(cx: Scope) -> Element {
/// let state = use_state(cx, || true);
/// render! {
@@ -25,7 +36,7 @@
/// }
/// }
/// }
-
+///
/// fn child_component(cx: Scope) -> Element {
/// let original_scroll_position = use_state(cx, || 0.0);
/// use_effect(cx, (), move |_| {
@@ -38,8 +49,8 @@
/// original_scroll_position.set(window.scroll_y().unwrap());
/// }
/// });
-
-/// use_on_unmount(cx, {
+///
+/// use_on_destroy(cx, {
/// to_owned![original_scroll_position];
/// /// restore scroll to the top of the page
/// move || {
@@ -47,7 +58,7 @@
/// window.scroll_with_x_and_y(*original_scroll_position.current(), 0.0);
/// }
/// });
-
+///
/// render!{
/// div {
/// id: "my_element",
@@ -56,7 +67,7 @@
/// }
/// }
/// ```
-pub fn use_on_unmount(cx: &dioxus_core::ScopeState, destroy: D) {
+pub fn use_on_destroy(cx: &dioxus_core::ScopeState, destroy: D) {
cx.use_hook(|| LifeCycle {
ondestroy: Some(destroy),
});
diff --git a/packages/hooks/src/useref.rs b/packages/hooks/src/use_ref.rs
similarity index 99%
rename from packages/hooks/src/useref.rs
rename to packages/hooks/src/use_ref.rs
index cf1b0306f..d0b95074e 100644
--- a/packages/hooks/src/useref.rs
+++ b/packages/hooks/src/use_ref.rs
@@ -110,6 +110,7 @@ use std::{
/// }
/// })
/// ```
+#[must_use]
pub fn use_ref(cx: &ScopeState, initialize_refcell: impl FnOnce() -> T) -> &UseRef {
let hook = cx.use_hook(|| UseRef {
update: cx.schedule_update(),
diff --git a/packages/hooks/src/userootcontext.rs b/packages/hooks/src/use_root_context.rs
similarity index 100%
rename from packages/hooks/src/userootcontext.rs
rename to packages/hooks/src/use_root_context.rs
diff --git a/packages/hooks/src/use_shared_state.rs b/packages/hooks/src/use_shared_state.rs
index 18ce1e5f1..37226c759 100644
--- a/packages/hooks/src/use_shared_state.rs
+++ b/packages/hooks/src/use_shared_state.rs
@@ -158,6 +158,7 @@ impl ProvidedStateInner {
/// Any time a component calls `write`, every consumer of the state will be notified - excluding the provider.
///
/// Right now, there is not a distinction between read-only and write-only, so every consumer will be notified.
+#[must_use]
pub fn use_shared_state(cx: &ScopeState) -> Option<&UseSharedState> {
let state_owner: &mut Option> = &mut *cx.use_hook(move || {
let scope_id = cx.scope_id();
diff --git a/packages/cli/examples/README.md b/packages/hooks/src/use_signal.rs
similarity index 100%
rename from packages/cli/examples/README.md
rename to packages/hooks/src/use_signal.rs
diff --git a/packages/hooks/src/usestate.rs b/packages/hooks/src/use_state.rs
similarity index 92%
rename from packages/hooks/src/usestate.rs
rename to packages/hooks/src/use_state.rs
index 9e3fb5eed..254493510 100644
--- a/packages/hooks/src/usestate.rs
+++ b/packages/hooks/src/use_state.rs
@@ -30,6 +30,7 @@ use std::{
/// ))
/// }
/// ```
+#[must_use]
pub fn use_state(
cx: &ScopeState,
initial_state_fn: impl FnOnce() -> T,
@@ -336,6 +337,50 @@ impl PartialEq> for UseState {
}
}
+impl PartialOrd for UseState {
+ fn ge(&self, other: &T) -> bool {
+ *self.current_val >= *other
+ }
+
+ fn gt(&self, other: &T) -> bool {
+ *self.current_val > *other
+ }
+
+ fn le(&self, other: &T) -> bool {
+ *self.current_val <= *other
+ }
+
+ fn lt(&self, other: &T) -> bool {
+ *self.current_val < *other
+ }
+
+ fn partial_cmp(&self, other: &T) -> Option {
+ (*self.current_val).partial_cmp(other)
+ }
+}
+
+impl PartialOrd> for UseState {
+ fn ge(&self, other: &UseState) -> bool {
+ self.current_val >= other.current_val
+ }
+
+ fn gt(&self, other: &UseState) -> bool {
+ self.current_val > other.current_val
+ }
+
+ fn le(&self, other: &UseState) -> bool {
+ self.current_val <= other.current_val
+ }
+
+ fn lt(&self, other: &UseState) -> bool {
+ self.current_val < other.current_val
+ }
+
+ fn partial_cmp(&self, other: &UseState) -> Option {
+ self.current_val.partial_cmp(&other.current_val)
+ }
+}
+
impl Debug for UseState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.current_val)
diff --git a/packages/hooks/src/usesignal.rs b/packages/hooks/src/usesignal.rs
deleted file mode 100644
index e69de29bb..000000000
diff --git a/packages/hot-reload/Cargo.toml b/packages/hot-reload/Cargo.toml
index b724ad685..70057114a 100644
--- a/packages/hot-reload/Cargo.toml
+++ b/packages/hot-reload/Cargo.toml
@@ -12,7 +12,7 @@ keywords = ["dom", "ui", "gui", "react", "hot-reloading"]
[dependencies]
dioxus-rsx = { workspace = true }
dioxus-core = { workspace = true, features = ["serialize"] }
-dioxus-html = { workspace = true }
+dioxus-html = { workspace = true, optional = true }
interprocess-docfix = { version = "1.2.2" }
notify = { version = "5.0.0", optional = true }
@@ -24,5 +24,6 @@ once_cell = { version = "1.17.0", optional = true }
ignore = { version = "0.4.19", optional = true }
[features]
-default = []
-file_watcher = ["ignore", "chrono", "notify", "execute", "once_cell", "ignore", "dioxus-html/hot-reload-context"]
+default = ["dioxus-html"]
+custom_file_watcher = ["ignore", "chrono", "notify", "execute", "once_cell", "ignore"]
+file_watcher = ["custom_file_watcher", "dioxus-html/hot-reload-context"]
diff --git a/packages/hot-reload/src/file_watcher.rs b/packages/hot-reload/src/file_watcher.rs
index 48d97dfa7..2509dd789 100644
--- a/packages/hot-reload/src/file_watcher.rs
+++ b/packages/hot-reload/src/file_watcher.rs
@@ -13,11 +13,12 @@ use dioxus_rsx::{
};
use interprocess_docfix::local_socket::{LocalSocketListener, LocalSocketStream};
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
-
-pub use dioxus_html::HtmlCtx;
use serde::{Deserialize, Serialize};
-pub struct Config {
+#[cfg(feature = "file_watcher")]
+use dioxus_html::HtmlCtx;
+
+pub struct Config {
root_path: &'static str,
listening_paths: &'static [&'static str],
excluded_paths: &'static [&'static str],
@@ -39,6 +40,7 @@ impl Default for Config {
}
}
+#[cfg(feature = "file_watcher")]
impl Config {
pub const fn new() -> Self {
Self {
diff --git a/packages/hot-reload/src/lib.rs b/packages/hot-reload/src/lib.rs
index f7906b141..68692b72b 100644
--- a/packages/hot-reload/src/lib.rs
+++ b/packages/hot-reload/src/lib.rs
@@ -6,9 +6,9 @@ pub use dioxus_html::HtmlCtx;
use interprocess_docfix::local_socket::LocalSocketStream;
use serde::{Deserialize, Serialize};
-#[cfg(feature = "file_watcher")]
+#[cfg(feature = "custom_file_watcher")]
mod file_watcher;
-#[cfg(feature = "file_watcher")]
+#[cfg(feature = "custom_file_watcher")]
pub use file_watcher::*;
/// A message the hot reloading server sends to the client
diff --git a/packages/html/src/elements.rs b/packages/html/src/elements.rs
index 7800369a9..6a0e546fa 100644
--- a/packages/html/src/elements.rs
+++ b/packages/html/src/elements.rs
@@ -1107,6 +1107,7 @@ builder_constructors! {
formnovalidate: Bool DEFAULT,
formtarget: Target DEFAULT,
height: isize DEFAULT,
+ initial_checked: Bool DEFAULT,
list: Id DEFAULT,
max: String DEFAULT,
maxlength: usize DEFAULT,
@@ -1203,6 +1204,7 @@ builder_constructors! {
value: String DEFAULT,
selected: Bool volatile,
+ initial_selected: Bool DEFAULT,
};
/// Build a
diff --git a/packages/html/src/eval.rs b/packages/html/src/eval.rs
index c90f5125b..292de70fc 100644
--- a/packages/html/src/eval.rs
+++ b/packages/html/src/eval.rs
@@ -33,6 +33,7 @@ type EvalCreator = Rc Result>;
/// parts is practically asking for a hacker to find an XSS vulnerability in
/// it. **This applies especially to web targets, where the JavaScript context
/// has access to most, if not all of your application data.**
+#[must_use]
pub fn use_eval(cx: &ScopeState) -> &EvalCreator {
&*cx.use_hook(|| {
let eval_provider = cx
diff --git a/packages/html/src/lib.rs b/packages/html/src/lib.rs
index 2fc1baeac..6dd7c42bd 100644
--- a/packages/html/src/lib.rs
+++ b/packages/html/src/lib.rs
@@ -1,3 +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")]
#![allow(non_snake_case)]
//! # Dioxus Namespace for HTML
diff --git a/packages/interpreter/src/common.js b/packages/interpreter/src/common.js
index 1583da10e..3745e8c6b 100644
--- a/packages/interpreter/src/common.js
+++ b/packages/interpreter/src/common.js
@@ -51,9 +51,15 @@ export function setAttributeInner(node, field, value, ns) {
case "checked":
node.checked = truthy(value);
break;
+ case "initial_checked":
+ node.defaultChecked = truthy(value);
+ break;
case "selected":
node.selected = truthy(value);
break;
+ case "initial_selected":
+ node.defaultSelected = truthy(value);
+ break;
case "dangerous_inner_html":
node.innerHTML = value;
break;
diff --git a/packages/interpreter/src/lib.rs b/packages/interpreter/src/lib.rs
index 47093c29c..c540b0d7d 100644
--- a/packages/interpreter/src/lib.rs
+++ b/packages/interpreter/src/lib.rs
@@ -1,3 +1,7 @@
+#![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")]
+
pub static INTERPRETER_JS: &str = include_str!("./interpreter.js");
pub static COMMON_JS: &str = include_str!("./common.js");
diff --git a/packages/interpreter/src/sledgehammer_bindings.rs b/packages/interpreter/src/sledgehammer_bindings.rs
index 7d5f44f7d..e2633d024 100644
--- a/packages/interpreter/src/sledgehammer_bindings.rs
+++ b/packages/interpreter/src/sledgehammer_bindings.rs
@@ -80,9 +80,15 @@ mod js {
case "checked":
node.checked = truthy(value);
break;
+ case "initial_checked":
+ node.defaultChecked = truthy(value);
+ break;
case "selected":
node.selected = truthy(value);
break;
+ case "initial_selected":
+ node.defaultSelected = truthy(value);
+ break;
case "dangerous_inner_html":
node.innerHTML = value;
break;
diff --git a/packages/liveview/examples/axum.rs b/packages/liveview/examples/axum.rs
index 2e7f10ee7..6584d5e9b 100644
--- a/packages/liveview/examples/axum.rs
+++ b/packages/liveview/examples/axum.rs
@@ -19,32 +19,43 @@ async fn main() {
let addr: std::net::SocketAddr = ([127, 0, 0, 1], 3030).into();
let view = dioxus_liveview::LiveViewPool::new();
+ let index_page_with_glue = |glue: &str| {
+ Html(format!(
+ r#"
+
+
+ Dioxus LiveView with axum
+
+ {glue}
+
+ "#,
+ ))
+ };
- let app = Router::new()
- .route(
- "/",
- get(move || async move {
- Html(format!(
- r#"
-
-
- Dioxus LiveView with axum
-
- {glue}
-
- "#,
- glue = dioxus_liveview::interpreter_glue(&format!("ws://{addr}/ws"))
- ))
- }),
- )
- .route(
- "/ws",
- get(move |ws: WebSocketUpgrade| async move {
- ws.on_upgrade(move |socket| async move {
- _ = view.launch(dioxus_liveview::axum_socket(socket), app).await;
- })
- }),
- );
+ let app =
+ Router::new()
+ .route(
+ "/",
+ get(move || async move {
+ index_page_with_glue(&dioxus_liveview::interpreter_glue(&format!(
+ "ws://{addr}/ws"
+ )))
+ }),
+ )
+ .route(
+ "/as-path",
+ get(move || async move {
+ index_page_with_glue(&dioxus_liveview::interpreter_glue("/ws"))
+ }),
+ )
+ .route(
+ "/ws",
+ get(move |ws: WebSocketUpgrade| async move {
+ ws.on_upgrade(move |socket| async move {
+ _ = view.launch(dioxus_liveview::axum_socket(socket), app).await;
+ })
+ }),
+ );
println!("Listening on http://{addr}");
diff --git a/packages/liveview/src/lib.rs b/packages/liveview/src/lib.rs
index 92cce63e6..6a2768fd5 100644
--- a/packages/liveview/src/lib.rs
+++ b/packages/liveview/src/lib.rs
@@ -1,3 +1,7 @@
+#![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")]
+
pub mod adapters {
#[cfg(feature = "warp")]
pub mod warp_adapter;
@@ -93,14 +97,49 @@ static MAIN_JS: &str = include_str!("./main.js");
/// This script that gets injected into your app connects this page to the websocket endpoint
///
/// Once the endpoint is connected, it will send the initial state of the app, and then start
-/// processing user events and returning edits to the liveview instance
-pub fn interpreter_glue(url: &str) -> String {
+/// processing user events and returning edits to the liveview instance.
+///
+/// You can pass a relative path prefixed with "/", or enter a full URL including the protocol
+/// (`ws:` or `wss:`) as an argument.
+///
+/// If you enter a relative path, the web client automatically prefixes the host address in
+/// `window.location` when creating a web socket to LiveView.
+///
+/// ```
+/// // Creates websocket connection to same host as current page
+/// interpreter_glue("/api/liveview");
+///
+/// // Creates websocket connection to specified url
+/// interpreter_glue("ws://localhost:8080/api/liveview");
+/// ```
+pub fn interpreter_glue(url_or_path: &str) -> String {
+ // If the url starts with a `/`, generate glue which reuses current host
+ let get_ws_url = if url_or_path.starts_with('/') {
+ r#"
+ let loc = window.location;
+ let new_url = "";
+ if (loc.protocol === "https:") {{
+ new_url = "wss:";
+ }} else {{
+ new_url = "ws:";
+ }}
+ new_url += "//" + loc.host + path;
+ return new_url;
+ "#
+ } else {
+ "return path;"
+ };
+
let js = &*INTERPRETER_JS;
let common = &*COMMON_JS;
format!(
r#"