Add generate script

This commit is contained in:
Daniëlle Huisman 2024-11-24 15:12:58 +01:00
parent 49a2c4915b
commit 1fc93a202c
46 changed files with 1758 additions and 12 deletions

37
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,37 @@
name: CI
on:
pull_request: {}
push:
branches:
- main
env:
RUSTFLAGS: '-Dwarnings'
jobs:
test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Rust toolchain
run: rustup toolchain install nightly --no-self-update --profile default --target wasm32-unknown-unknown
- name: Set up Rust cache
uses: swatinem/rust-cache@v2
with:
cache-on-failure: true
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Check formatting
run: cargo fmt --all --check
- name: Lint
run: cargo clippy --all-features
- name: Test
run: cargo test --all-features

115
.github/workflows/website.yml vendored Normal file
View file

@ -0,0 +1,115 @@
name: Website
on:
pull_request: {}
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
jobs:
book-test:
name: Test Book
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Rust toolchain
run: |
rustup toolchain install stable --no-self-update --profile minimal
rustup target add wasm32-unknown-unknown
- name: Set up Rust cache
uses: swatinem/rust-cache@v2
with:
cache-on-failure: true
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install Cargo Binary Install
uses: cargo-bins/cargo-binstall@main
- name: Install mdBook
run: cargo binstall --force -y mdbook mdbook-tabs mdbook-trunk
- name: Run tests
run: mdbook test
working-directory: book
book-build:
name: Build Book
needs: book-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Rust toolchain
run: |
rustup toolchain install stable --no-self-update --profile minimal
rustup target add wasm32-unknown-unknown
- name: Set up Rust cache
uses: swatinem/rust-cache@v2
with:
cache-on-failure: true
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install Cargo Binary Install
uses: cargo-bins/cargo-binstall@main
- name: Install mdBook and Trunk
run: cargo binstall --force -y mdbook mdbook-tabs mdbook-trunk trunk
- name: Install Node.js dependencies
run: npm install
- name: Build Book
run: mdbook build
working-directory: book
- name: Combine Book Outputs
run: mdbook-trunk combine
working-directory: book
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: book
path: book/dist
retention-days: 1
if-no-files-found: error
deploy:
name: Deploy
needs: book-build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
contents: read
pages: write
id-token: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: dist
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

659
Cargo.lock generated
View file

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "addr2line"
@ -44,6 +44,55 @@ version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9"
[[package]]
name = "anstream"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
dependencies = [
"anstyle",
"windows-sys 0.59.0",
]
[[package]]
name = "any_spawner"
version = "0.1.1"
@ -164,6 +213,12 @@ dependencies = [
"windows-targets",
]
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
@ -251,6 +306,17 @@ dependencies = [
"thiserror 1.0.69",
]
[[package]]
name = "cc"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
dependencies = [
"jobserver",
"libc",
"shlex",
]
[[package]]
name = "cfg-expr"
version = "0.15.8"
@ -266,6 +332,33 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "ciborium"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
dependencies = [
"ciborium-io",
"ciborium-ll",
"serde",
]
[[package]]
name = "ciborium-io"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
[[package]]
name = "ciborium-ll"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
dependencies = [
"ciborium-io",
"half",
]
[[package]]
name = "codee"
version = "0.2.0"
@ -283,6 +376,12 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186dce98367766de751c42c4f03970fc60fc012296e706ccbb9d5df9b6c1e271"
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "concurrent-queue"
version = "2.5.0"
@ -315,6 +414,16 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "console_log"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f"
dependencies = [
"log",
"web-sys",
]
[[package]]
name = "const_format"
version = "0.2.33"
@ -362,6 +471,12 @@ version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "darling"
version = "0.20.10"
@ -396,6 +511,19 @@ dependencies = [
"syn 2.0.89",
]
[[package]]
name = "dashmap"
version = "5.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
dependencies = [
"cfg-if",
"hashbrown 0.14.5",
"lock_api",
"once_cell",
"parking_lot_core",
]
[[package]]
name = "dashmap"
version = "6.1.0"
@ -430,10 +558,25 @@ dependencies = [
"dioxus-config-macro",
"dioxus-core",
"dioxus-core-macro",
"dioxus-fullstack",
"dioxus-hooks",
"dioxus-hot-reload",
"dioxus-html",
"dioxus-router",
"dioxus-signals",
"dioxus-web",
]
[[package]]
name = "dioxus-cli-config"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7dffc452ed91af6ef772b0d9a5899573f6785314e97c533733ec55413c01df3"
dependencies = [
"once_cell",
"serde",
"serde_json",
"tracing",
]
[[package]]
@ -485,6 +628,29 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ea539174bb236e0e7dc9c12b19b88eae3cb574dedbd0252a2d43ea7e6de13e2"
[[package]]
name = "dioxus-fullstack"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b80f0ac18166302341164e681322e0385131c08a11c3cc1c51ee8df799ab0d3d"
dependencies = [
"async-trait",
"base64 0.21.7",
"bytes",
"ciborium",
"dioxus-hot-reload",
"dioxus-lib",
"dioxus-web",
"dioxus_server_macro",
"futures-util",
"once_cell",
"serde",
"serde_json",
"server_fn 0.6.15",
"tracing",
"web-sys",
]
[[package]]
name = "dioxus-hooks"
version = "0.5.6"
@ -535,6 +701,7 @@ dependencies = [
"serde_json",
"serde_repr",
"tracing",
"wasm-bindgen",
"web-sys",
]
@ -550,6 +717,66 @@ dependencies = [
"syn 2.0.89",
]
[[package]]
name = "dioxus-interpreter-js"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "351fad098c657d14f3ac2900362d2b86e83c22c4c620a404839e1ab628f3395b"
dependencies = [
"js-sys",
"md5",
"sledgehammer_bindgen",
"sledgehammer_utils",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "dioxus-lib"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bd39b2c41dd1915dcb91d914ea72d8b646f1f8995aaeff82816b862ec586ecd"
dependencies = [
"dioxus-core",
"dioxus-core-macro",
"dioxus-hooks",
"dioxus-html",
"dioxus-rsx",
"dioxus-signals",
]
[[package]]
name = "dioxus-router"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c235c5dbeb528c0c2b0424763da812e7500df69b82eddac54db6f4975e065c5f"
dependencies = [
"dioxus-cli-config",
"dioxus-lib",
"dioxus-router-macro",
"gloo 0.8.1",
"gloo-utils 0.1.7",
"js-sys",
"tracing",
"url",
"urlencoding",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "dioxus-router-macro"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7cd1c5137ba361f2150cdea6b3bc9ddda7b1af84b22c9ee6b5499bf43e1381"
dependencies = [
"proc-macro2",
"quote",
"slab",
"syn 2.0.89",
]
[[package]]
name = "dioxus-rsx"
version = "0.5.6"
@ -581,6 +808,44 @@ dependencies = [
"tracing",
]
[[package]]
name = "dioxus-web"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0855ac81fcc9252a0863930a7a7cbb2504fc1b6efe893489c8d0e23aaeb2cb9"
dependencies = [
"async-trait",
"console_error_panic_hook",
"dioxus-core",
"dioxus-html",
"dioxus-interpreter-js",
"futures-channel",
"futures-util",
"generational-box",
"js-sys",
"rustc-hash 1.1.0",
"serde",
"serde-wasm-bindgen 0.5.0",
"serde_json",
"tracing",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "dioxus_server_macro"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5ef2cad17001c1155f019cb69adbacd620644566d78a77d0778807bb106a337"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"server_fn_macro 0.6.15",
"syn 2.0.89",
]
[[package]]
name = "displaydoc"
version = "0.2.5"
@ -634,12 +899,45 @@ dependencies = [
"syn 2.0.89",
]
[[package]]
name = "env_filter"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"humantime",
"log",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "euclid"
version = "0.22.11"
@ -689,6 +987,12 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foldhash"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2"
[[package]]
name = "form_urlencoded"
version = "1.2.1"
@ -826,6 +1130,21 @@ version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "git2"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724"
dependencies = [
"bitflags",
"libc",
"libgit2-sys",
"log",
"openssl-probe",
"openssl-sys",
"url",
]
[[package]]
name = "gloo"
version = "0.8.1"
@ -1200,6 +1519,16 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "493913a18c0d7bebb75127a26a432162c59edbe06f6cf712001e3e769345e8b5"
[[package]]
name = "half"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
dependencies = [
"cfg-if",
"crunchy",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
@ -1215,6 +1544,11 @@ name = "hashbrown"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash",
]
[[package]]
name = "hermit-abi"
@ -1253,6 +1587,12 @@ dependencies = [
"itoa",
]
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hydration_context"
version = "0.2.0-rc2"
@ -1484,6 +1824,12 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae52f28f45ac2bc96edb7714de995cffc174a395fb0abf5bff453587c980d7b9"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itertools"
version = "0.13.0"
@ -1499,6 +1845,15 @@ version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2"
[[package]]
name = "jobserver"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
dependencies = [
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.72"
@ -1561,8 +1916,8 @@ dependencies = [
"rustc-hash 2.0.0",
"send_wrapper",
"serde",
"serde_qs",
"server_fn",
"serde_qs 0.13.0",
"server_fn 0.7.0-rc2",
"slotmap",
"tachys",
"thiserror 2.0.3",
@ -1636,7 +1991,7 @@ dependencies = [
"proc-macro2",
"quote",
"rstml",
"server_fn_macro",
"server_fn_macro 0.7.0-rc2",
"syn 2.0.89",
"uuid",
]
@ -1648,7 +2003,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1387314dcb7f9547394a61b0cb41cdbd09e6c5dd5e154e304123f3d9b5b747b"
dependencies = [
"any_spawner",
"base64",
"base64 0.22.1",
"codee",
"futures",
"hydration_context",
@ -1657,7 +2012,7 @@ dependencies = [
"send_wrapper",
"serde",
"serde_json",
"server_fn",
"server_fn 0.7.0-rc2",
"tachys",
]
@ -1667,12 +2022,58 @@ version = "0.2.164"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
[[package]]
name = "libgit2-sys"
version = "0.17.0+1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224"
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.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "linear-map"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfae20f6b19ad527b550c223fddc3077a547fc70cda94b9b566575423fd303ee"
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "litemap"
version = "0.7.4"
@ -1701,6 +2102,15 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86"
[[package]]
name = "lru"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
dependencies = [
"hashbrown 0.15.1",
]
[[package]]
name = "lucide-dioxus"
version = "0.0.1"
@ -1708,6 +2118,17 @@ dependencies = [
"dioxus",
]
[[package]]
name = "lucide-dioxus-book"
version = "0.0.1"
dependencies = [
"console_error_panic_hook",
"console_log",
"dioxus",
"log",
"lucide-dioxus",
]
[[package]]
name = "lucide-leptos"
version = "0.0.1"
@ -1715,6 +2136,17 @@ dependencies = [
"leptos",
]
[[package]]
name = "lucide-leptos-book"
version = "0.0.1"
dependencies = [
"console_error_panic_hook",
"console_log",
"leptos",
"log",
"lucide-leptos",
]
[[package]]
name = "lucide-yew"
version = "0.0.1"
@ -1722,6 +2154,17 @@ dependencies = [
"yew",
]
[[package]]
name = "lucide-yew-book"
version = "0.0.1"
dependencies = [
"console_error_panic_hook",
"console_log",
"log",
"lucide-yew",
"yew",
]
[[package]]
name = "manyhow"
version = "0.11.4"
@ -1745,6 +2188,12 @@ dependencies = [
"quote",
]
[[package]]
name = "md5"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
[[package]]
name = "memchr"
version = "2.7.4"
@ -1836,6 +2285,24 @@ version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[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.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "or_poisoned"
version = "0.1.0"
@ -1968,6 +2435,12 @@ dependencies = [
"futures-io",
]
[[package]]
name = "pkg-config"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "prettyplease"
version = "0.2.25"
@ -2244,6 +2717,19 @@ dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "0.38.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
]
[[package]]
name = "rustversion"
version = "1.0.18"
@ -2274,6 +2760,17 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "scripts"
version = "0.0.1"
dependencies = [
"convert_case",
"env_logger",
"git2",
"log",
"prettyplease",
"proc-macro2",
"quote",
"syn 2.0.89",
"tempfile",
]
[[package]]
name = "semver"
@ -2357,6 +2854,17 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_qs"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c"
dependencies = [
"percent-encoding",
"serde",
"thiserror 1.0.69",
]
[[package]]
name = "serde_qs"
version = "0.13.0"
@ -2400,6 +2908,34 @@ dependencies = [
"serde",
]
[[package]]
name = "server_fn"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fae7a3038a32e5a34ba32c6c45eb4852f8affaf8b794ebfcd4b1099e2d62ebe"
dependencies = [
"bytes",
"const_format",
"dashmap 5.5.3",
"futures",
"gloo-net 0.6.0",
"http 1.1.0",
"js-sys",
"once_cell",
"send_wrapper",
"serde",
"serde_json",
"serde_qs 0.12.0",
"server_fn_macro_default 0.6.15",
"thiserror 1.0.69",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"xxhash-rust",
]
[[package]]
name = "server_fn"
version = "0.7.0-rc2"
@ -2408,7 +2944,7 @@ checksum = "bed94ec81d1b9ef2b28325bcf715461d861e90f41d249b70b561c6eefcb96afe"
dependencies = [
"bytes",
"const_format",
"dashmap",
"dashmap 6.1.0",
"futures",
"gloo-net 0.6.0",
"http 1.1.0",
@ -2418,8 +2954,8 @@ dependencies = [
"send_wrapper",
"serde",
"serde_json",
"serde_qs",
"server_fn_macro_default",
"serde_qs 0.13.0",
"server_fn_macro_default 0.7.0-rc2",
"thiserror 2.0.3",
"throw_error",
"url",
@ -2430,6 +2966,20 @@ dependencies = [
"xxhash-rust",
]
[[package]]
name = "server_fn_macro"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "faaaf648c6967aef78177c0610478abb5a3455811f401f3c62d10ae9bd3901a1"
dependencies = [
"const_format",
"convert_case",
"proc-macro2",
"quote",
"syn 2.0.89",
"xxhash-rust",
]
[[package]]
name = "server_fn_macro"
version = "0.7.0-rc2"
@ -2444,13 +2994,23 @@ dependencies = [
"xxhash-rust",
]
[[package]]
name = "server_fn_macro_default"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f2aa8119b558a17992e0ac1fd07f080099564f24532858811ce04f742542440"
dependencies = [
"server_fn_macro 0.6.15",
"syn 2.0.89",
]
[[package]]
name = "server_fn_macro_default"
version = "0.7.0-rc2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "295a3c3d01be1cf17d0c8b25a48b963a747f6ccdba0f62f657e8df37df4afaac"
dependencies = [
"server_fn_macro",
"server_fn_macro 0.7.0-rc2",
"syn 2.0.89",
]
@ -2463,6 +3023,12 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "slab"
version = "0.4.9"
@ -2472,6 +3038,37 @@ dependencies = [
"autocfg",
]
[[package]]
name = "sledgehammer_bindgen"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcfaf791ff02f48f3518ce825d32cf419c13a43c1d8b1232f74ac89f339c46d2"
dependencies = [
"sledgehammer_bindgen_macro",
"wasm-bindgen",
]
[[package]]
name = "sledgehammer_bindgen_macro"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edc90d3e8623d29a664cd8dba5078b600dd203444f00b9739f744e4c6e7aeaf2"
dependencies = [
"quote",
"syn 2.0.89",
]
[[package]]
name = "sledgehammer_utils"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f20798defa0e9d4eff9ca451c7f84774c7378a9c3b5a40112cfa2b3eadb97ae2"
dependencies = [
"lru",
"once_cell",
"rustc-hash 1.1.0",
]
[[package]]
name = "slotmap"
version = "1.0.7"
@ -2579,6 +3176,19 @@ dependencies = [
"web-sys",
]
[[package]]
name = "tempfile"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
dependencies = [
"cfg-if",
"fastrand",
"once_cell",
"rustix",
"windows-sys 0.59.0",
]
[[package]]
name = "thiserror"
version = "1.0.69"
@ -2826,6 +3436,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "urlencoding"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]]
name = "utf16_iter"
version = "1.0.5"
@ -2844,6 +3460,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.11.0"
@ -2859,6 +3481,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[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.5"
@ -2993,7 +3621,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -3002,6 +3630,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.59.0"

View file

@ -1,5 +1,5 @@
[workspace]
members = ["packages/*", "scripts"]
members = ["book-examples/*", "packages/*", "scripts"]
resolver = "2"
[workspace.package]
@ -10,6 +10,9 @@ repository = "https://github.com/RustForWeb/lucide"
version = "0.0.1"
[workspace.dependencies]
console_log = "1.0.0"
console_error_panic_hook = "0.1.7"
dioxus = "0.5.6"
leptos = "0.7.0-rc2"
log = "0.4.22"
yew = "0.21.0"

View file

@ -0,0 +1,21 @@
[package]
name = "lucide-dioxus-book"
description = "Book examples for Lucide Dioxus."
publish = false
authors.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
version.workspace = true
[dependencies]
console_error_panic_hook.workspace = true
console_log.workspace = true
dioxus = { workspace = true, features = ["web"] }
log.workspace = true
lucide-dioxus = { path = "../../packages/dioxus", optional = true }
[features]
default = []
icons = ["dep:lucide-dioxus", "lucide-dioxus/full"]

View file

@ -0,0 +1,7 @@
[[hooks]]
stage = "pre_build"
command = "sh"
command_arguments = [
"-c",
"npx tailwindcss -i style/tailwind.css -o style/tailwind.output.css",
]

View file

@ -0,0 +1,9 @@
<!doctype html>
<html>
<head>
<link data-trunk rel="css" href="/style/tailwind.output.css" />
<script data-trunk type="application/javascript" src="/main.js"></script>
</head>
<body></body>
</html>

View file

@ -0,0 +1,13 @@
document.addEventListener('DOMContentLoaded', () => {
const resizeObserver = new ResizeObserver(() => {
if (window.top) {
window.top.postMessage({
mdbookTrunk: {
width: document.body.scrollWidth,
height: document.body.scrollHeight
}
});
}
});
resizeObserver.observe(document.body);
});

View file

@ -0,0 +1,23 @@
use dioxus::prelude::*;
#[component]
pub fn App() -> Element {
#[allow(unused_mut)]
let mut children: Vec<Option<VNode>> = vec![];
#[cfg(feature = "icons")]
{
use crate::icons::Icons;
children.push(rsx! {
Icons {}
});
}
rsx! {
div {
class: "w-full h-full flex justify-center items-center",
{children.iter()}
}
}
}

View file

@ -0,0 +1,6 @@
use dioxus::prelude::*;
#[component]
pub fn Icons() -> Element {
rsx! {}
}

View file

@ -0,0 +1,13 @@
mod app;
#[cfg(feature = "icons")]
mod icons;
use crate::app::App;
pub fn main() {
_ = console_log::init_with_level(log::Level::Debug);
console_error_panic_hook::set_once();
dioxus::launch(App);
}

View file

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View file

@ -0,0 +1,6 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['*.html', './src/**/*.rs'],
theme: {},
plugins: []
};

View file

@ -0,0 +1,21 @@
[package]
name = "lucide-leptos-book"
description = "Book examples for Lucide Leptos."
publish = false
authors.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
version.workspace = true
[dependencies]
console_error_panic_hook.workspace = true
console_log.workspace = true
leptos = { workspace = true, features = ["csr"] }
log.workspace = true
lucide-leptos = { path = "../../packages/leptos", optional = true }
[features]
default = []
icons = ["dep:lucide-leptos", "lucide-leptos/full"]

View file

@ -0,0 +1,7 @@
[[hooks]]
stage = "pre_build"
command = "sh"
command_arguments = [
"-c",
"npx tailwindcss -i style/tailwind.css -o style/tailwind.output.css",
]

View file

@ -0,0 +1,9 @@
<!doctype html>
<html>
<head>
<link data-trunk rel="css" href="/style/tailwind.output.css" />
<script data-trunk type="application/javascript" src="/main.js"></script>
</head>
<body></body>
</html>

View file

@ -0,0 +1,13 @@
document.addEventListener('DOMContentLoaded', () => {
const resizeObserver = new ResizeObserver(() => {
if (window.top) {
window.top.postMessage({
mdbookTrunk: {
width: document.body.scrollWidth,
height: document.body.scrollHeight
}
});
}
});
resizeObserver.observe(document.body);
});

View file

@ -0,0 +1,24 @@
use leptos::prelude::*;
#[component]
pub fn App() -> impl IntoView {
#[allow(unused_mut)]
let mut views: Vec<AnyView> = vec![];
#[cfg(feature = "icons")]
{
use crate::icons::Icons;
views.push(
view! {
<Icons />
}
.into_any(),
);
}
view! {
<div class="w-full h-full flex justify-center items-start">
{views.into_view()}
</div>
}
}

View file

@ -0,0 +1,6 @@
use leptos::prelude::*;
#[component]
pub fn Icons() -> impl IntoView {
view! {}
}

View file

@ -0,0 +1,15 @@
mod app;
#[cfg(feature = "icons")]
mod icons;
use leptos::prelude::mount_to_body;
use crate::app::App;
pub fn main() {
_ = console_log::init_with_level(log::Level::Debug);
console_error_panic_hook::set_once();
mount_to_body(App);
}

View file

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View file

@ -0,0 +1,6 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['*.html', './src/**/*.rs'],
theme: {},
plugins: []
};

View file

@ -0,0 +1,21 @@
[package]
name = "lucide-yew-book"
description = "Book examples for Lucide Yew."
publish = false
authors.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
version.workspace = true
[dependencies]
console_error_panic_hook.workspace = true
console_log.workspace = true
log.workspace = true
lucide-yew = { path = "../../packages/yew", optional = true }
yew = { workspace = true, features = ["csr"] }
[features]
default = []
icons = ["dep:lucide-yew", "lucide-yew/full"]

View file

@ -0,0 +1,7 @@
[[hooks]]
stage = "pre_build"
command = "sh"
command_arguments = [
"-c",
"npx tailwindcss -i style/tailwind.css -o style/tailwind.output.css",
]

View file

@ -0,0 +1,9 @@
<!doctype html>
<html>
<head>
<link data-trunk rel="css" href="/style/tailwind.output.css" />
<script data-trunk type="application/javascript" src="/main.js"></script>
</head>
<body></body>
</html>

13
book-examples/yew/main.js Normal file
View file

@ -0,0 +1,13 @@
document.addEventListener('DOMContentLoaded', () => {
const resizeObserver = new ResizeObserver(() => {
if (window.top) {
window.top.postMessage({
mdbookTrunk: {
width: document.body.scrollWidth,
height: document.body.scrollHeight
}
});
}
});
resizeObserver.observe(document.body);
});

View file

@ -0,0 +1,15 @@
use yew::prelude::*;
#[function_component]
pub fn App() -> Html {
#[allow(unused_mut)]
let mut children: Vec<Html> = vec![];
#[cfg(feature = "icons")]
{
use crate::icons::Icons;
children.push(html! { <Icons /> });
}
html! { <div class="w-full h-full flex justify-center items-start">{ children }</div> }
}

View file

@ -0,0 +1,6 @@
use yew::prelude::*;
#[function_component]
pub fn Icons() -> Html {
html! {}
}

View file

@ -0,0 +1,13 @@
mod app;
#[cfg(feature = "icons")]
mod icons;
use crate::app::App;
pub fn main() {
_ = console_log::init_with_level(log::Level::Debug);
console_error_panic_hook::set_once();
yew::Renderer::<App>::new().render();
}

View file

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View file

@ -0,0 +1,6 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['*.html', './src/**/*.rs'],
theme: {},
plugins: []
};

View file

@ -1,3 +1,11 @@
# Lucide Dioxus
TODO
## Example
```toml,trunk
package = "lucide-dioxus-book"
features = ["icons"]
files = ["src/icons.rs"]
```

View file

@ -1,3 +1,11 @@
# Lucide Leptos
TODO
## Example
```toml,trunk
package = "lucide-leptos-book"
features = ["icons"]
files = ["src/icons.rs"]
```

View file

@ -1,3 +1,11 @@
# Lucide Yew
TODO
## Example
```toml,trunk
package = "lucide-yew-book"
features = ["icons"]
files = ["src/icons.rs"]
```

View file

@ -11,3 +11,7 @@ version.workspace = true
[dependencies]
dioxus.workspace = true
[features]
default = []
full = []

View file

@ -11,3 +11,7 @@ version.workspace = true
[dependencies]
leptos.workspace = true
[features]
default = []
full = []

View file

@ -11,3 +11,7 @@ version.workspace = true
[dependencies]
yew.workspace = true
[features]
default = []
full = []

2
rust-toolchain.toml Normal file
View file

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"

View file

@ -10,3 +10,12 @@ repository.workspace = true
version.workspace = true
[dependencies]
convert_case = "0.6.0"
env_logger = "0.11.5"
git2 = "0.19.0"
log.workspace = true
prettyplease = "0.2.25"
proc-macro2 = "1.0.92"
quote = "1.0.37"
tempfile = "3.14.0"
syn = "2.0.89"

234
scripts/src/bin/generate.rs Normal file
View file

@ -0,0 +1,234 @@
use std::{error::Error, fs, path::Path};
use convert_case::{Case, Casing};
use git2::Repository;
use log::info;
use scripts::{
framework::Framework,
frameworks::{leptos::Leptos, yew::Yew},
};
use tempfile::tempdir;
const GIT_URL: &str = "https://github.com/lucide-icons/lucide.git";
const GIT_REF: &str = "0.460.1";
fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();
let frameworks: [Box<dyn Framework>; 2] = [Box::new(Leptos), Box::new(Yew)];
let repository_path = tempdir()?;
let repository_icons_path = repository_path.path().join("icons");
info!(
"Cloning \"{}\" ref \"{}\" into \"{}\".",
GIT_URL,
GIT_REF,
repository_path.path().display()
);
git_checkout(&repository_path)?;
info!("Generating icons.");
let mut modules = vec![];
let mut component_names = vec![];
for entry in fs::read_dir(repository_icons_path)? {
let path = entry?.path();
if !path.is_file() || path.extension().is_none_or(|extension| extension != "svg") {
continue;
}
let file_path = path.clone();
let file_stem = file_path
.file_stem()
.expect("File stem should exist.")
.to_string_lossy();
let file_contents = fs::read_to_string(path)?;
let module = file_stem.to_case(Case::Snake);
modules.push(module.clone());
let component_name = file_stem.to_case(Case::Pascal);
component_names.push(component_name.clone());
info!("{} - {}", module, component_name);
for framework in &frameworks {
generate_icon(
&**framework,
module.clone(),
component_name.clone(),
file_contents.clone(),
)?;
}
}
for framework in &frameworks {
generate_lib(&**framework, &modules)?;
generate_features(&**framework, &modules)?;
generate_example(&**framework, &component_names)?;
framework.format(
format!("lucide-{}", framework.name()),
Path::new("packages").join(framework.name()).join("src"),
)?;
framework.format(
format!("lucide-{}-book", framework.name()),
Path::new("book-examples")
.join(framework.name())
.join("src"),
)?;
}
Ok(())
}
fn git_checkout<P: AsRef<Path>>(path: P) -> Result<(), Box<dyn Error>> {
let repository = Repository::clone(GIT_URL, path)?;
let (object, reference) = repository.revparse_ext(GIT_REF)?;
repository.checkout_tree(&object, None)?;
match reference {
Some(reference) => {
repository.set_head(reference.name().expect("Reference name should exist."))?
}
None => repository.set_head_detached(object.id())?,
}
Ok(())
}
fn generate_icon(
framework: &dyn Framework,
module: String,
component_name: String,
input: String,
) -> Result<(), Box<dyn Error>> {
let output_path = Path::new("packages")
.join(framework.name())
.join("src")
.join(format!("{}.rs", module));
let output_tokens = framework.generate(component_name, input)?;
let output = prettyplease::unparse(&syn::parse2(output_tokens)?);
fs::write(output_path, output)?;
Ok(())
}
fn generate_example(
framework: &dyn Framework,
component_names: &[String],
) -> Result<(), Box<dyn Error>> {
let output_path = Path::new("book-examples")
.join(framework.name())
.join("src")
.join("icons.rs");
let output_tokens = framework.generate_example(component_names)?;
let output = prettyplease::unparse(&syn::parse2(output_tokens)?);
fs::write(output_path, output)?;
Ok(())
}
fn generate_lib(framework: &dyn Framework, modules: &[String]) -> Result<(), Box<dyn Error>> {
let output_path = Path::new("packages")
.join(framework.name())
.join("src")
.join("lib.rs");
let output_modules = modules
.iter()
.map(|module| {
format!(
"#[cfg(feature = \"{}\")]\nmod {};",
module.trim_end_matches("_icon").to_case(Case::Kebab),
sanitize_identifier(module.as_str())
)
})
.collect::<Vec<String>>()
.join("\n");
let output_uses = modules
.iter()
.map(|module| {
format!(
"#[cfg(feature = \"{}\")]\npub use {}::*;",
module.trim_end_matches("_icon").to_case(Case::Kebab),
sanitize_identifier(module.as_str())
)
})
.collect::<Vec<String>>()
.join("\n");
let output = format!(
"{}{}\n\n{}\n",
match framework.lib_header() {
Some(header) => format!("{}\n\n", header),
None => "".into(),
},
output_modules,
output_uses
);
fs::write(output_path, output)?;
Ok(())
}
fn generate_features(framework: &dyn Framework, modules: &[String]) -> Result<(), Box<dyn Error>> {
let output_path = Path::new("packages")
.join(framework.name())
.join("features.toml");
let output_features = modules
.iter()
.map(|module| {
format!(
"{} = []",
module.trim_end_matches("_icon").to_case(Case::Kebab)
)
})
.collect::<Vec<String>>()
.join("\n");
let output_full = modules
.iter()
.map(|module| {
format!(
"\"{}\"",
module.trim_end_matches("_icon").to_case(Case::Kebab)
)
})
.collect::<Vec<String>>()
.join(", ");
let output = format!(
"[features]\ndefault = []\n{}\nfull = [{}]\n",
output_features, output_full
);
fs::write(output_path, output)?;
// TODO: Replace features in Cargo.toml instead of writing to features.toml.
Ok(())
}
fn sanitize_identifier(identifier: &str) -> &str {
match identifier {
"box" => "r#box",
"move" => "r#move",
"type" => "r#type",
identifier => identifier,
}
}

15
scripts/src/framework.rs Normal file
View file

@ -0,0 +1,15 @@
use std::{error::Error, path::PathBuf};
use proc_macro2::TokenStream;
pub trait Framework {
fn name(&self) -> &'static str;
fn lib_header(&self) -> Option<String>;
fn generate(&self, component_name: String, svg: String) -> Result<TokenStream, Box<dyn Error>>;
fn generate_example(&self, component_names: &[String]) -> Result<TokenStream, Box<dyn Error>>;
fn format(&self, package: String, path: PathBuf) -> Result<(), Box<dyn Error>>;
}

View file

@ -0,0 +1,3 @@
pub mod dioxus;
pub mod leptos;
pub mod yew;

View file

@ -0,0 +1,45 @@
use std::{error::Error, path::PathBuf};
use proc_macro2::TokenStream;
use crate::framework::Framework;
#[allow(dead_code)]
pub struct Dioxus;
impl Framework for Dioxus {
fn name(&self) -> &'static str {
"dioxus"
}
fn lib_header(&self) -> Option<String> {
Some(
"\
//! Dioxus port of [Lucide](https://lucide.dev/).\n\
//!\n\
//! Lucide is a beautiful & consistent icon toolkit made by the community.\n\
//!\n\
//! See [the Rust Lucide book](https://lucide.rustforweb.org/dioxus.html) for more documenation.\n\
"
.to_owned()
)
}
fn generate(
&self,
_component_name: String,
_svg: String,
) -> Result<TokenStream, Box<dyn Error>> {
// TODO
todo!()
}
fn generate_example(&self, _component_names: &[String]) -> Result<TokenStream, Box<dyn Error>> {
// TODO
todo!()
}
fn format(&self, _package: String, _path: PathBuf) -> Result<(), Box<dyn Error>> {
Ok(())
}
}

View file

@ -0,0 +1,149 @@
use std::{error::Error, path::PathBuf, process::Command};
use convert_case::{Case, Casing};
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use crate::framework::Framework;
pub struct Leptos;
impl Framework for Leptos {
fn name(&self) -> &'static str {
"leptos"
}
fn lib_header(&self) -> Option<String> {
Some(
"\
//! Leptos port of [Lucide](https://lucide.dev/).\n\
//!\n\
//! Lucide is a beautiful & consistent icon toolkit made by the community.\n\
//!\n\
//! See [the Rust Lucide book](https://lucide.rustforweb.org/leptos.html) for more documenation.\n\
"
.to_owned()
)
}
fn generate(&self, component_name: String, svg: String) -> Result<TokenStream, Box<dyn Error>> {
let component_name: TokenStream = component_name.parse()?;
let svg: TokenStream = svg
.replacen("<svg", "<svg node_ref=node_ref class:lucide=true ", 1)
.replacen("width=\"24\"", "width=size", 1)
.replacen("height=\"24\"", "height=size", 1)
.replacen("fill=\"none\"", "fill=fill", 1)
.replacen("stroke=\"currentColor\"", "stroke=color", 1)
.replacen("stroke-width=\"2\"", "stroke-width=stroke_width", 1)
.parse()?;
Ok(quote! {
use leptos::{prelude::*, svg::Svg};
#[component]
pub fn #component_name(
#[prop(default = 24.into(), into)] size: Signal<usize>,
#[prop(default = "currentColor".into(), into)] color: Signal<String>,
#[prop(default = "none".into(), into)] fill: Signal<String>,
#[prop(default = 2.into(), into)] stroke_width: Signal<usize>,
#[prop(default = false.into(), into)] absolute_stroke_width: Signal<bool>,
#[prop(optional)] node_ref: NodeRef<Svg>,
) -> impl IntoView {
let stroke_width = Signal::derive(move || {
if absolute_stroke_width.get() {
stroke_width.get() * 24 / size.get()
} else {
stroke_width.get()
}
});
view! {
#svg
}
}
})
}
fn generate_example(&self, component_names: &[String]) -> Result<TokenStream, Box<dyn Error>> {
let mut letter_component_name: Vec<TokenStream> = vec![];
let mut letter_component: Vec<TokenStream> = vec![];
for letter in 'A'..='Z' {
let mut component_name: Vec<TokenStream> = vec![];
let mut human_name: Vec<TokenStream> = vec![];
for name in component_names {
if !name.starts_with(letter) {
continue;
}
component_name.push(name.parse()?);
human_name.push(
name.trim_end_matches("Icon")
.to_case(Case::Title)
.to_token_stream(),
);
}
let name: TokenStream = format!("Icons{letter}").parse()?;
letter_component_name.push(quote! {
<#name />
});
letter_component.push(quote! {
#[component]
pub fn #name() -> impl IntoView {
view! {
<For
each=move || [
#((view! { <#component_name /> }.into_any(), #human_name),)*
]
key=|icon| icon.1
children=move |(icon, name)| {
view! {
<div class="flex flex-wrap items-center gap-4 text-sm">
{icon}
<span>{name}</span>
</div>
}
}
/>
}
}
});
}
Ok(quote! {
use leptos::prelude::*;
use lucide_leptos::*;
#[component]
pub fn Icons() -> impl IntoView {
view! {
<div class="w-full max-w-80 py-4">
#(#letter_component_name)*
</div>
}
}
#(#letter_component)*
})
}
fn format(&self, package: String, path: PathBuf) -> Result<(), Box<dyn Error>> {
Command::new("cargo")
.arg("fmt")
.arg("-p")
.arg(&package)
.status()?
.exit_ok()?;
Command::new("leptosfmt")
.arg("--quiet")
.arg(path)
.status()?
.exit_ok()?;
Ok(())
}
}

View file

@ -0,0 +1,160 @@
use std::{error::Error, path::PathBuf, process::Command};
use convert_case::{Case, Casing};
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use crate::framework::Framework;
pub struct Yew;
impl Framework for Yew {
fn name(&self) -> &'static str {
"yew"
}
fn lib_header(&self) -> Option<String> {
Some(
"\
//! Yew port of [Lucide](https://lucide.dev/).\n\
//!\n\
//! Lucide is a beautiful & consistent icon toolkit made by the community.\n\
//!\n\
//! See [the Rust Lucide book](https://lucide.rustforweb.org/yew.html) for more documenation.\n\
\n\
#![allow(ambiguous_glob_reexports)]
".to_owned()
)
}
fn generate(&self, component_name: String, svg: String) -> Result<TokenStream, Box<dyn Error>> {
let component_name: TokenStream = component_name.parse()?;
let props_name: TokenStream = format!("{}Props", component_name).parse()?;
let svg: TokenStream = svg
.replacen(
"<svg",
"<svg ref={props.node_ref.clone()} class={classes!(\"lucide\", props.class.clone())} ",
1,
)
.replacen("width=\"24\"", "width={props.size.to_string()}", 1)
.replacen("height=\"24\"", "height={props.size.to_string()}", 1)
.replacen("fill=\"none\"", "fill={&props.fill}", 1)
.replacen("stroke=\"currentColor\"", "stroke={&props.color}", 1)
.replacen(
"stroke-width=\"2\"",
"stroke-width={stroke_width.to_string()}",
1,
)
.parse()?;
Ok(quote! {
use yew::prelude::*;
#[derive(PartialEq, Properties)]
pub struct #props_name {
#[prop_or(24)]
pub size: usize,
#[prop_or(AttrValue::from("currentColor"))]
pub color: AttrValue,
#[prop_or(AttrValue::from("none"))]
pub fill: AttrValue,
#[prop_or(2)]
pub stroke_width: usize,
#[prop_or(false)]
pub absolute_stroke_width: bool,
#[prop_or_default]
pub class: Classes,
#[prop_or_default]
pub node_ref: NodeRef,
}
#[function_component]
pub fn #component_name(props: &#props_name) -> Html {
let stroke_width = if props.absolute_stroke_width {
props.stroke_width * 24 / props.size
} else {
props.stroke_width
};
html! {
#svg
}
}
})
}
fn generate_example(&self, component_names: &[String]) -> Result<TokenStream, Box<dyn Error>> {
let mut letter_component_name: Vec<TokenStream> = vec![];
let mut letter_component: Vec<TokenStream> = vec![];
for letter in 'A'..='Z' {
let mut component_name: Vec<TokenStream> = vec![];
let mut human_name: Vec<TokenStream> = vec![];
for name in component_names {
if !name.starts_with(letter) {
continue;
}
component_name.push(name.parse()?);
human_name.push(
name.trim_end_matches("Icon")
.to_case(Case::Title)
.to_token_stream(),
);
}
let name: TokenStream = format!("Icons{letter}").parse()?;
letter_component_name.push(quote! {
<#name />
});
letter_component.push(quote! {
#[function_component]
pub fn #name() -> Html {
let icons = [
#((html! { <#component_name /> }, #human_name),)*
];
icons
.into_iter()
.map(|(icon, name)| html! {
<div class="flex flex-wrap items-center gap-4 text-sm">
{icon}
<span>{name}</span>
</div>
})
.collect::<Html>()
}
});
}
Ok(quote! {
use lucide_yew::{*, Component};
use yew::prelude::*;
#[function_component]
pub fn Icons() -> Html {
html! {
<div class="w-full max-w-80 py-4">
#(#letter_component_name)*
</div>
}
}
#(#letter_component)*
})
}
fn format(&self, package: String, _path: PathBuf) -> Result<(), Box<dyn Error>> {
Command::new("cargo")
.arg("fmt")
.arg("-p")
.arg(package)
.env("RUSTFMT", "yew-fmt")
.status()?
.exit_ok()?;
Ok(())
}
}

View file

@ -1 +1,4 @@
#![feature(exit_status_error)]
pub mod framework;
pub mod frameworks;