├── .cargo └── config.toml ├── .github ├── dependabot.yaml └── workflows │ ├── ci.yaml │ └── security-audit.yaml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE.txt ├── README.md ├── deny.toml ├── examples └── htmx-rsx │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── src │ ├── handlers.rs │ ├── main.rs │ └── views │ │ ├── about.rs │ │ ├── document.rs │ │ ├── home.rs │ │ ├── list.rs │ │ ├── mod.rs │ │ └── nav.rs │ └── tailwind.css ├── hypertext-macros ├── Cargo.toml └── src │ ├── component.rs │ ├── html │ ├── basics.rs │ ├── component.rs │ ├── control.rs │ ├── generate.rs │ ├── mod.rs │ └── syntaxes │ │ ├── maud.rs │ │ ├── mod.rs │ │ └── rsx.rs │ └── lib.rs ├── hypertext ├── Cargo.toml ├── src │ ├── alloc.rs │ ├── frameworks.rs │ ├── html_elements.rs │ ├── lib.rs │ ├── prelude.rs │ ├── proc_macros.rs │ ├── validation.rs │ └── web.rs └── tests │ └── main.rs ├── rustfmt.toml └── taplo.toml /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | rustdocflags = ["--cfg", "docsrs"] 3 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: "cargo" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | 9 | - package-ecosystem: "github-actions" 10 | directory: "/" 11 | schedule: 12 | interval: "daily" 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | 3 | on: 4 | - push 5 | - pull_request 6 | 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | test: 12 | name: Test 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout repository 18 | uses: actions/checkout@v4 19 | 20 | - name: Install Rust 21 | uses: dtolnay/rust-toolchain@stable 22 | 23 | - name: Cache dependencies 24 | uses: Swatinem/rust-cache@v2 25 | 26 | - name: Execute tests 27 | run: cargo test --all-features --lib --bins --tests 28 | 29 | - name: Execute documentation tests 30 | run: cargo +nightly test --all-features --doc 31 | 32 | check: 33 | name: Check 34 | 35 | runs-on: ubuntu-latest 36 | 37 | steps: 38 | - name: Checkout repository 39 | uses: actions/checkout@v4 40 | 41 | - name: Install Rust 42 | uses: dtolnay/rust-toolchain@nightly 43 | with: 44 | components: clippy 45 | 46 | - name: Cache dependencies 47 | uses: Swatinem/rust-cache@v2 48 | 49 | - name: Check code 50 | run: cargo clippy --all-features --all-targets -- -D warnings 51 | 52 | format: 53 | name: Format 54 | 55 | runs-on: ubuntu-latest 56 | 57 | steps: 58 | - name: Checkout repository 59 | uses: actions/checkout@v4 60 | 61 | - name: Install Rust 62 | uses: dtolnay/rust-toolchain@nightly 63 | with: 64 | components: rustfmt 65 | 66 | - name: Cache dependencies 67 | uses: Swatinem/rust-cache@v2 68 | 69 | - name: Check formatting 70 | run: cargo fmt --all -- --check 71 | 72 | toml-format: 73 | name: TOML Format 74 | 75 | runs-on: ubuntu-latest 76 | 77 | steps: 78 | - name: Checkout repository 79 | uses: actions/checkout@v4 80 | 81 | - name: Install Taplo CLI 82 | uses: dtolnay/install@taplo-cli 83 | 84 | - name: Check TOML formatting 85 | run: taplo fmt --check 86 | -------------------------------------------------------------------------------- /.github/workflows/security-audit.yaml: -------------------------------------------------------------------------------- 1 | name: Security Audit 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | 7 | push: 8 | paths: 9 | - "**/Cargo.toml" 10 | - "**/Cargo.lock" 11 | - "**/deny.toml" 12 | 13 | pull_request: 14 | 15 | jobs: 16 | cargo-deny: 17 | name: Security Audit 18 | 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - name: Checkout repository 23 | uses: actions/checkout@v4 24 | with: 25 | lfs: true 26 | 27 | - name: Run `cargo-deny` 28 | uses: EmbarkStudios/cargo-deny-action@v2 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig 2 | # Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,rust 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,macos,rust 4 | 5 | ### macOS ### 6 | # General 7 | .DS_Store 8 | .AppleDouble 9 | .LSOverride 10 | 11 | # Icon must end with two \r 12 | Icon 13 | 14 | # Thumbnails 15 | ._* 16 | 17 | # Files that might appear in the root of a volume 18 | .DocumentRevisions-V100 19 | .fseventsd 20 | .Spotlight-V100 21 | .TemporaryItems 22 | .Trashes 23 | .VolumeIcon.icns 24 | .com.apple.timemachine.donotpresent 25 | 26 | # Directories potentially created on remote AFP share 27 | .AppleDB 28 | .AppleDesktop 29 | Network Trash Folder 30 | Temporary Items 31 | .apdisk 32 | 33 | ### macOS Patch ### 34 | # iCloud generated files 35 | *.icloud 36 | 37 | ### Rust ### 38 | # Generated by Cargo 39 | # will have compiled files and executables 40 | debug/ 41 | target/ 42 | 43 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 44 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 45 | # Cargo.lock 46 | 47 | # These are backup files generated by rustfmt 48 | **/*.rs.bk 49 | 50 | # MSVC Windows builds of rustc generate these, which store debugging information 51 | *.pdb 52 | 53 | ### VisualStudioCode ### 54 | .vscode/* 55 | !.vscode/settings.json 56 | !.vscode/tasks.json 57 | !.vscode/launch.json 58 | !.vscode/extensions.json 59 | !.vscode/*.code-snippets 60 | 61 | # Local History for Visual Studio Code 62 | .history/ 63 | 64 | # Built Visual Studio Code Extensions 65 | *.vsix 66 | 67 | ### VisualStudioCode Patch ### 68 | # Ignore all local history of files 69 | .history 70 | .ionide 71 | 72 | # End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,rust 73 | 74 | # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) 75 | tmp/ 76 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | default-members = ["hypertext", "hypertext-macros"] 3 | members = ["examples/*", "hypertext", "hypertext-macros"] 4 | resolver = "2" 5 | 6 | [workspace.package] 7 | authors = ["Vidhan Bhatt "] 8 | categories = ["template-engine"] 9 | description = "A blazing fast type-checked HTML macro crate." 10 | edition = "2024" 11 | homepage = "https://github.com/vidhanio/hypertext" 12 | keywords = ["html", "macro"] 13 | license = "MIT" 14 | readme = "README.md" 15 | repository = "https://github.com/vidhanio/hypertext" 16 | version = "0.9.0" 17 | 18 | 19 | [workspace.dependencies] 20 | hypertext = { version = "0.9.0", path = "./hypertext" } 21 | hypertext-macros = { version = "0.9.0", path = "./hypertext-macros" } 22 | 23 | html-escape = { version = "0.2", default-features = false } 24 | 25 | [workspace.lints] 26 | [workspace.lints.rust] 27 | 28 | missing_copy_implementations = "warn" 29 | missing_debug_implementations = "warn" 30 | missing_docs = "warn" 31 | unsafe_code = "forbid" 32 | 33 | [workspace.lints.clippy] 34 | cargo = { level = "warn", priority = -1 } 35 | nursery = { level = "warn", priority = -1 } 36 | pedantic = { level = "warn", priority = -1 } 37 | too_long_first_doc_paragraph = "allow" 38 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 [fullname] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `hypertext` 2 | 3 | A blazing fast type-checked HTML macro crate. 4 | 5 | ## Features 6 | 7 | - Type checking for element names/attributes 8 | - Completely extensible for use with non-standard elements/attributes, such as 9 | those used by [htmx](https://htmx.org/) and [Alpine.js](https://alpinejs.dev/) 10 | - `#![no_std]` support 11 | - Automatic escaping 12 | - [Extremely fast](https://github.com/askama-rs/template-benchmark#benchmark-results), 13 | using lazy rendering by default to avoid unnecessary allocations 14 | - Support for two well-known HTML macro syntaxes, `maud` and `rsx` 15 | - `#![forbid(unsafe_code)]` across the entire codebase 16 | - Integration with all major web frameworks, enabled by their respective feature flags 17 | - [`actix-web`](https://actix.rs/) 18 | - [`axum`](https://github.com/tokio-rs/axum) 19 | - [`poem`](https://github.com/poem-web/poem) 20 | - [`rocket`](https://rocket.rs/) 21 | - [`salvo`](https://github.com/salvo-rs/salvo) 22 | - [`tide`](https://github.com/http-rs/tide) 23 | - [`warp`](https://github.com/seanmonstar/warp) 24 | 25 | ## Projects Using `hypertext` 26 | 27 | - [vidhan.io](https://github.com/vidhanio/site) (my website!) 28 | 29 | Make a pull request to list your project here! 30 | 31 | ## Example 32 | 33 | ```rust 34 | use hypertext::prelude::*; 35 | 36 | let shopping_list = ["milk", "eggs", "bread"]; 37 | 38 | let shopping_list_maud = maud! { 39 | div { 40 | h1 { "Shopping List" } 41 | ul { 42 | @for (i, item) in (1..).zip(shopping_list) { 43 | li.item { 44 | input #{ "item-" (i) } type="checkbox"; 45 | label for={ "item-" (i) } { (item) } 46 | } 47 | } 48 | } 49 | } 50 | } 51 | .render(); 52 | 53 | // or, alternatively: 54 | 55 | let shopping_list_rsx = rsx! { 56 |
57 |

Shopping List

58 | 66 |
67 | } 68 | .render(); 69 | ``` 70 | -------------------------------------------------------------------------------- /deny.toml: -------------------------------------------------------------------------------- 1 | [licenses] 2 | allow = ["Apache-2.0", "BSD-3-Clause", "MIT", "Unicode-3.0", "Zlib"] 3 | 4 | [advisories] 5 | ignore = [ 6 | "RUSTSEC-2020-0056", 7 | "RUSTSEC-2021-0059", 8 | "RUSTSEC-2021-0060", 9 | "RUSTSEC-2021-0064", 10 | "RUSTSEC-2024-0384", 11 | ] 12 | -------------------------------------------------------------------------------- /examples/htmx-rsx/.gitignore: -------------------------------------------------------------------------------- 1 | static/ 2 | -------------------------------------------------------------------------------- /examples/htmx-rsx/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.4.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 25 | 26 | [[package]] 27 | name = "axum" 28 | version = "0.8.4" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" 31 | dependencies = [ 32 | "axum-core", 33 | "bytes", 34 | "form_urlencoded", 35 | "futures-util", 36 | "http", 37 | "http-body", 38 | "http-body-util", 39 | "hyper", 40 | "hyper-util", 41 | "itoa", 42 | "matchit", 43 | "memchr", 44 | "mime", 45 | "percent-encoding", 46 | "pin-project-lite", 47 | "rustversion", 48 | "serde", 49 | "serde_json", 50 | "serde_path_to_error", 51 | "serde_urlencoded", 52 | "sync_wrapper", 53 | "tokio", 54 | "tower", 55 | "tower-layer", 56 | "tower-service", 57 | "tracing", 58 | ] 59 | 60 | [[package]] 61 | name = "axum-core" 62 | version = "0.5.2" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" 65 | dependencies = [ 66 | "bytes", 67 | "futures-core", 68 | "http", 69 | "http-body", 70 | "http-body-util", 71 | "mime", 72 | "pin-project-lite", 73 | "rustversion", 74 | "sync_wrapper", 75 | "tower-layer", 76 | "tower-service", 77 | "tracing", 78 | ] 79 | 80 | [[package]] 81 | name = "axum-htmx" 82 | version = "0.7.0" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "d16a4be621f96b959fc829e4cbf02fd79ffb8427525002af31a9e2979599fbb7" 85 | dependencies = [ 86 | "axum-core", 87 | "http", 88 | ] 89 | 90 | [[package]] 91 | name = "backtrace" 92 | version = "0.3.74" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 95 | dependencies = [ 96 | "addr2line", 97 | "cfg-if", 98 | "libc", 99 | "miniz_oxide", 100 | "object", 101 | "rustc-demangle", 102 | "windows-targets", 103 | ] 104 | 105 | [[package]] 106 | name = "bitflags" 107 | version = "2.9.0" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" 110 | 111 | [[package]] 112 | name = "bytes" 113 | version = "1.10.1" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 116 | 117 | [[package]] 118 | name = "cfg-if" 119 | version = "1.0.0" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 122 | 123 | [[package]] 124 | name = "derive-where" 125 | version = "1.4.0" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "e73f2692d4bd3cac41dca28934a39894200c9fabf49586d77d0e5954af1d7902" 128 | dependencies = [ 129 | "proc-macro2", 130 | "quote", 131 | "syn", 132 | ] 133 | 134 | [[package]] 135 | name = "fnv" 136 | version = "1.0.7" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 139 | 140 | [[package]] 141 | name = "form_urlencoded" 142 | version = "1.2.1" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 145 | dependencies = [ 146 | "percent-encoding", 147 | ] 148 | 149 | [[package]] 150 | name = "futures-channel" 151 | version = "0.3.31" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 154 | dependencies = [ 155 | "futures-core", 156 | ] 157 | 158 | [[package]] 159 | name = "futures-core" 160 | version = "0.3.31" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 163 | 164 | [[package]] 165 | name = "futures-sink" 166 | version = "0.3.31" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 169 | 170 | [[package]] 171 | name = "futures-task" 172 | version = "0.3.31" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 175 | 176 | [[package]] 177 | name = "futures-util" 178 | version = "0.3.31" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 181 | dependencies = [ 182 | "futures-core", 183 | "futures-task", 184 | "pin-project-lite", 185 | "pin-utils", 186 | ] 187 | 188 | [[package]] 189 | name = "gimli" 190 | version = "0.31.1" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 193 | 194 | [[package]] 195 | name = "html-escape" 196 | version = "0.2.13" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" 199 | dependencies = [ 200 | "utf8-width", 201 | ] 202 | 203 | [[package]] 204 | name = "htmx-rsx" 205 | version = "0.0.0" 206 | dependencies = [ 207 | "axum", 208 | "axum-htmx", 209 | "hypertext", 210 | "tokio", 211 | "tower-http", 212 | ] 213 | 214 | [[package]] 215 | name = "http" 216 | version = "1.3.1" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" 219 | dependencies = [ 220 | "bytes", 221 | "fnv", 222 | "itoa", 223 | ] 224 | 225 | [[package]] 226 | name = "http-body" 227 | version = "1.0.1" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 230 | dependencies = [ 231 | "bytes", 232 | "http", 233 | ] 234 | 235 | [[package]] 236 | name = "http-body-util" 237 | version = "0.1.3" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" 240 | dependencies = [ 241 | "bytes", 242 | "futures-core", 243 | "http", 244 | "http-body", 245 | "pin-project-lite", 246 | ] 247 | 248 | [[package]] 249 | name = "http-range-header" 250 | version = "0.4.2" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" 253 | 254 | [[package]] 255 | name = "httparse" 256 | version = "1.10.1" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 259 | 260 | [[package]] 261 | name = "httpdate" 262 | version = "1.0.3" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 265 | 266 | [[package]] 267 | name = "hyper" 268 | version = "1.6.0" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" 271 | dependencies = [ 272 | "bytes", 273 | "futures-channel", 274 | "futures-util", 275 | "http", 276 | "http-body", 277 | "httparse", 278 | "httpdate", 279 | "itoa", 280 | "pin-project-lite", 281 | "smallvec", 282 | "tokio", 283 | ] 284 | 285 | [[package]] 286 | name = "hyper-util" 287 | version = "0.1.11" 288 | source = "registry+https://github.com/rust-lang/crates.io-index" 289 | checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" 290 | dependencies = [ 291 | "bytes", 292 | "futures-util", 293 | "http", 294 | "http-body", 295 | "hyper", 296 | "pin-project-lite", 297 | "tokio", 298 | "tower-service", 299 | ] 300 | 301 | [[package]] 302 | name = "hypertext" 303 | version = "0.8.0" 304 | dependencies = [ 305 | "axum-core", 306 | "html-escape", 307 | "http", 308 | "hypertext-macros", 309 | "itoa", 310 | "ryu", 311 | ] 312 | 313 | [[package]] 314 | name = "hypertext-macros" 315 | version = "0.8.0" 316 | dependencies = [ 317 | "html-escape", 318 | "proc-macro2", 319 | "proc-macro2-diagnostics", 320 | "quote", 321 | "rstml", 322 | "syn", 323 | ] 324 | 325 | [[package]] 326 | name = "itoa" 327 | version = "1.0.15" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 330 | 331 | [[package]] 332 | name = "libc" 333 | version = "0.2.172" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" 336 | 337 | [[package]] 338 | name = "lock_api" 339 | version = "0.4.12" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 342 | dependencies = [ 343 | "autocfg", 344 | "scopeguard", 345 | ] 346 | 347 | [[package]] 348 | name = "log" 349 | version = "0.4.27" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 352 | 353 | [[package]] 354 | name = "matchit" 355 | version = "0.8.4" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" 358 | 359 | [[package]] 360 | name = "memchr" 361 | version = "2.7.4" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 364 | 365 | [[package]] 366 | name = "mime" 367 | version = "0.3.17" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 370 | 371 | [[package]] 372 | name = "mime_guess" 373 | version = "2.0.5" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" 376 | dependencies = [ 377 | "mime", 378 | "unicase", 379 | ] 380 | 381 | [[package]] 382 | name = "miniz_oxide" 383 | version = "0.8.8" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" 386 | dependencies = [ 387 | "adler2", 388 | ] 389 | 390 | [[package]] 391 | name = "mio" 392 | version = "1.0.3" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 395 | dependencies = [ 396 | "libc", 397 | "wasi", 398 | "windows-sys", 399 | ] 400 | 401 | [[package]] 402 | name = "object" 403 | version = "0.36.7" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 406 | dependencies = [ 407 | "memchr", 408 | ] 409 | 410 | [[package]] 411 | name = "once_cell" 412 | version = "1.21.3" 413 | source = "registry+https://github.com/rust-lang/crates.io-index" 414 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 415 | 416 | [[package]] 417 | name = "parking_lot" 418 | version = "0.12.3" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 421 | dependencies = [ 422 | "lock_api", 423 | "parking_lot_core", 424 | ] 425 | 426 | [[package]] 427 | name = "parking_lot_core" 428 | version = "0.9.10" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 431 | dependencies = [ 432 | "cfg-if", 433 | "libc", 434 | "redox_syscall", 435 | "smallvec", 436 | "windows-targets", 437 | ] 438 | 439 | [[package]] 440 | name = "percent-encoding" 441 | version = "2.3.1" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 444 | 445 | [[package]] 446 | name = "pin-project-lite" 447 | version = "0.2.16" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 450 | 451 | [[package]] 452 | name = "pin-utils" 453 | version = "0.1.0" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 456 | 457 | [[package]] 458 | name = "proc-macro-error-attr2" 459 | version = "2.0.0" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" 462 | dependencies = [ 463 | "proc-macro2", 464 | "quote", 465 | ] 466 | 467 | [[package]] 468 | name = "proc-macro-error2" 469 | version = "2.0.1" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" 472 | dependencies = [ 473 | "proc-macro-error-attr2", 474 | "proc-macro2", 475 | "quote", 476 | ] 477 | 478 | [[package]] 479 | name = "proc-macro2" 480 | version = "1.0.95" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 483 | dependencies = [ 484 | "unicode-ident", 485 | ] 486 | 487 | [[package]] 488 | name = "proc-macro2-diagnostics" 489 | version = "0.10.1" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" 492 | dependencies = [ 493 | "proc-macro2", 494 | "quote", 495 | "syn", 496 | "version_check", 497 | ] 498 | 499 | [[package]] 500 | name = "quote" 501 | version = "1.0.40" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 504 | dependencies = [ 505 | "proc-macro2", 506 | ] 507 | 508 | [[package]] 509 | name = "redox_syscall" 510 | version = "0.5.11" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" 513 | dependencies = [ 514 | "bitflags", 515 | ] 516 | 517 | [[package]] 518 | name = "rstml" 519 | version = "0.12.1" 520 | source = "registry+https://github.com/rust-lang/crates.io-index" 521 | checksum = "61cf4616de7499fc5164570d40ca4e1b24d231c6833a88bff0fe00725080fd56" 522 | dependencies = [ 523 | "derive-where", 524 | "proc-macro2", 525 | "proc-macro2-diagnostics", 526 | "quote", 527 | "syn", 528 | "syn_derive", 529 | "thiserror", 530 | ] 531 | 532 | [[package]] 533 | name = "rustc-demangle" 534 | version = "0.1.24" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 537 | 538 | [[package]] 539 | name = "rustversion" 540 | version = "1.0.20" 541 | source = "registry+https://github.com/rust-lang/crates.io-index" 542 | checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" 543 | 544 | [[package]] 545 | name = "ryu" 546 | version = "1.0.20" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 549 | 550 | [[package]] 551 | name = "scopeguard" 552 | version = "1.2.0" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 555 | 556 | [[package]] 557 | name = "serde" 558 | version = "1.0.219" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 561 | dependencies = [ 562 | "serde_derive", 563 | ] 564 | 565 | [[package]] 566 | name = "serde_derive" 567 | version = "1.0.219" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 570 | dependencies = [ 571 | "proc-macro2", 572 | "quote", 573 | "syn", 574 | ] 575 | 576 | [[package]] 577 | name = "serde_json" 578 | version = "1.0.140" 579 | source = "registry+https://github.com/rust-lang/crates.io-index" 580 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" 581 | dependencies = [ 582 | "itoa", 583 | "memchr", 584 | "ryu", 585 | "serde", 586 | ] 587 | 588 | [[package]] 589 | name = "serde_path_to_error" 590 | version = "0.1.17" 591 | source = "registry+https://github.com/rust-lang/crates.io-index" 592 | checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" 593 | dependencies = [ 594 | "itoa", 595 | "serde", 596 | ] 597 | 598 | [[package]] 599 | name = "serde_urlencoded" 600 | version = "0.7.1" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 603 | dependencies = [ 604 | "form_urlencoded", 605 | "itoa", 606 | "ryu", 607 | "serde", 608 | ] 609 | 610 | [[package]] 611 | name = "signal-hook-registry" 612 | version = "1.4.5" 613 | source = "registry+https://github.com/rust-lang/crates.io-index" 614 | checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" 615 | dependencies = [ 616 | "libc", 617 | ] 618 | 619 | [[package]] 620 | name = "smallvec" 621 | version = "1.15.0" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" 624 | 625 | [[package]] 626 | name = "socket2" 627 | version = "0.5.9" 628 | source = "registry+https://github.com/rust-lang/crates.io-index" 629 | checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" 630 | dependencies = [ 631 | "libc", 632 | "windows-sys", 633 | ] 634 | 635 | [[package]] 636 | name = "syn" 637 | version = "2.0.101" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" 640 | dependencies = [ 641 | "proc-macro2", 642 | "quote", 643 | "unicode-ident", 644 | ] 645 | 646 | [[package]] 647 | name = "syn_derive" 648 | version = "0.2.0" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "cdb066a04799e45f5d582e8fc6ec8e6d6896040d00898eb4e6a835196815b219" 651 | dependencies = [ 652 | "proc-macro-error2", 653 | "proc-macro2", 654 | "quote", 655 | "syn", 656 | ] 657 | 658 | [[package]] 659 | name = "sync_wrapper" 660 | version = "1.0.2" 661 | source = "registry+https://github.com/rust-lang/crates.io-index" 662 | checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 663 | 664 | [[package]] 665 | name = "thiserror" 666 | version = "2.0.12" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 669 | dependencies = [ 670 | "thiserror-impl", 671 | ] 672 | 673 | [[package]] 674 | name = "thiserror-impl" 675 | version = "2.0.12" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" 678 | dependencies = [ 679 | "proc-macro2", 680 | "quote", 681 | "syn", 682 | ] 683 | 684 | [[package]] 685 | name = "tokio" 686 | version = "1.44.2" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" 689 | dependencies = [ 690 | "backtrace", 691 | "bytes", 692 | "libc", 693 | "mio", 694 | "parking_lot", 695 | "pin-project-lite", 696 | "signal-hook-registry", 697 | "socket2", 698 | "tokio-macros", 699 | "windows-sys", 700 | ] 701 | 702 | [[package]] 703 | name = "tokio-macros" 704 | version = "2.5.0" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 707 | dependencies = [ 708 | "proc-macro2", 709 | "quote", 710 | "syn", 711 | ] 712 | 713 | [[package]] 714 | name = "tokio-util" 715 | version = "0.7.15" 716 | source = "registry+https://github.com/rust-lang/crates.io-index" 717 | checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" 718 | dependencies = [ 719 | "bytes", 720 | "futures-core", 721 | "futures-sink", 722 | "pin-project-lite", 723 | "tokio", 724 | ] 725 | 726 | [[package]] 727 | name = "tower" 728 | version = "0.5.2" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 731 | dependencies = [ 732 | "futures-core", 733 | "futures-util", 734 | "pin-project-lite", 735 | "sync_wrapper", 736 | "tokio", 737 | "tower-layer", 738 | "tower-service", 739 | "tracing", 740 | ] 741 | 742 | [[package]] 743 | name = "tower-http" 744 | version = "0.6.2" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" 747 | dependencies = [ 748 | "bitflags", 749 | "bytes", 750 | "futures-util", 751 | "http", 752 | "http-body", 753 | "http-body-util", 754 | "http-range-header", 755 | "httpdate", 756 | "mime", 757 | "mime_guess", 758 | "percent-encoding", 759 | "pin-project-lite", 760 | "tokio", 761 | "tokio-util", 762 | "tower-layer", 763 | "tower-service", 764 | "tracing", 765 | ] 766 | 767 | [[package]] 768 | name = "tower-layer" 769 | version = "0.3.3" 770 | source = "registry+https://github.com/rust-lang/crates.io-index" 771 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 772 | 773 | [[package]] 774 | name = "tower-service" 775 | version = "0.3.3" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 778 | 779 | [[package]] 780 | name = "tracing" 781 | version = "0.1.41" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 784 | dependencies = [ 785 | "log", 786 | "pin-project-lite", 787 | "tracing-core", 788 | ] 789 | 790 | [[package]] 791 | name = "tracing-core" 792 | version = "0.1.33" 793 | source = "registry+https://github.com/rust-lang/crates.io-index" 794 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 795 | dependencies = [ 796 | "once_cell", 797 | ] 798 | 799 | [[package]] 800 | name = "unicase" 801 | version = "2.8.1" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" 804 | 805 | [[package]] 806 | name = "unicode-ident" 807 | version = "1.0.18" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 810 | 811 | [[package]] 812 | name = "utf8-width" 813 | version = "0.1.7" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" 816 | 817 | [[package]] 818 | name = "version_check" 819 | version = "0.9.5" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 822 | 823 | [[package]] 824 | name = "wasi" 825 | version = "0.11.0+wasi-snapshot-preview1" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 828 | 829 | [[package]] 830 | name = "windows-sys" 831 | version = "0.52.0" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 834 | dependencies = [ 835 | "windows-targets", 836 | ] 837 | 838 | [[package]] 839 | name = "windows-targets" 840 | version = "0.52.6" 841 | source = "registry+https://github.com/rust-lang/crates.io-index" 842 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 843 | dependencies = [ 844 | "windows_aarch64_gnullvm", 845 | "windows_aarch64_msvc", 846 | "windows_i686_gnu", 847 | "windows_i686_gnullvm", 848 | "windows_i686_msvc", 849 | "windows_x86_64_gnu", 850 | "windows_x86_64_gnullvm", 851 | "windows_x86_64_msvc", 852 | ] 853 | 854 | [[package]] 855 | name = "windows_aarch64_gnullvm" 856 | version = "0.52.6" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 859 | 860 | [[package]] 861 | name = "windows_aarch64_msvc" 862 | version = "0.52.6" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 865 | 866 | [[package]] 867 | name = "windows_i686_gnu" 868 | version = "0.52.6" 869 | source = "registry+https://github.com/rust-lang/crates.io-index" 870 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 871 | 872 | [[package]] 873 | name = "windows_i686_gnullvm" 874 | version = "0.52.6" 875 | source = "registry+https://github.com/rust-lang/crates.io-index" 876 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 877 | 878 | [[package]] 879 | name = "windows_i686_msvc" 880 | version = "0.52.6" 881 | source = "registry+https://github.com/rust-lang/crates.io-index" 882 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 883 | 884 | [[package]] 885 | name = "windows_x86_64_gnu" 886 | version = "0.52.6" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 889 | 890 | [[package]] 891 | name = "windows_x86_64_gnullvm" 892 | version = "0.52.6" 893 | source = "registry+https://github.com/rust-lang/crates.io-index" 894 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 895 | 896 | [[package]] 897 | name = "windows_x86_64_msvc" 898 | version = "0.52.6" 899 | source = "registry+https://github.com/rust-lang/crates.io-index" 900 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 901 | -------------------------------------------------------------------------------- /examples/htmx-rsx/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "htmx-rsx" 3 | 4 | edition.workspace = true 5 | license.workspace = true 6 | publish = false 7 | version = "0.0.0" 8 | 9 | [dependencies] 10 | anyhow = "1" 11 | axum = "0.8" 12 | axum-htmx = "0.7" 13 | hypertext = { path = "../../hypertext", features = ["axum", "htmx"] } 14 | tokio = { version = "1", features = ["macros", "rt-multi-thread"] } 15 | tower-http = { version = "0.6", features = ["fs"] } 16 | -------------------------------------------------------------------------------- /examples/htmx-rsx/README.md: -------------------------------------------------------------------------------- 1 | # Hypertext HTMX RSX Example 2 | 3 | ## Setup 4 | 5 | First, install `npm` packages (Tailwind CSS CLI) 6 | 7 | ```sh 8 | npm i 9 | ``` 10 | 11 | Next, install [air](https://github.com/air-verse/air) for automatic reload (make sure you have [Go installed](https://go.dev/doc/install)): 12 | 13 | ```sh 14 | go install github.com/air-verse/air@latest 15 | ``` 16 | 17 | Start the server: 18 | 19 | ```sh 20 | air 21 | ``` 22 | 23 | Open `localhost:3001` in your browser! 24 | 25 | ## Design 26 | 27 | The `views` folder contains any HTML templates. 28 | The `handlers` folder contains any `axum` handlers used for routing. 29 | 30 | ### Components 31 | 32 | With `hypertext` you can use Rust functions as re-usable HTML components! Simply set the return type to `impl Renderable` and you can 33 | reference that function to call your component. 34 | 35 | ```rust 36 | use hypertext::prelude::*; 37 | 38 | use crate::views::nav; 39 | 40 | pub fn about(nav_oob: bool) -> impl Renderable { 41 | rsx! { 42 | @if nav_oob { 43 | { nav("/", true) } 44 | } 45 |
46 |

"About HTMX-RSX"

47 |

"HTMX-RSX is a simple example of using HTMX with RSX."

48 |

"This project demonstrates how to use HTMX for dynamic content loading in a Rust web application."

49 |
50 | } 51 | } 52 | ``` 53 | 54 | You can even pass a component into another component as a parameter! 55 | 56 | In this example we are setting a parameter `page` so that any component can be passed into this one. 57 | 58 | ```rust 59 | pub fn index(selected: &str, page: impl Renderable) -> impl Renderable { 60 | // ... 61 | } 62 | ``` 63 | -------------------------------------------------------------------------------- /examples/htmx-rsx/build.rs: -------------------------------------------------------------------------------- 1 | use std::{error::Error, process::Command}; 2 | 3 | const TAILWIND_CSS: &str = "tailwind.css"; 4 | 5 | fn main() -> Result<(), Box> { 6 | println!("cargo:rerun-if-changed={TAILWIND_CSS}"); 7 | println!("cargo:rerun-if-changed=src/views/"); 8 | 9 | let output = Command::new("tailwindcss") 10 | .args(["-i", TAILWIND_CSS, "-o", "static/styles.css", "--minify"]) 11 | .output()?; 12 | 13 | if !output.status.success() { 14 | return Err(format!( 15 | "failed to execute `tailwindcss`:\n{}", 16 | String::from_utf8_lossy(&output.stderr) 17 | ) 18 | .into()); 19 | } 20 | 21 | Ok(()) 22 | } 23 | -------------------------------------------------------------------------------- /examples/htmx-rsx/src/handlers.rs: -------------------------------------------------------------------------------- 1 | use axum::response::IntoResponse; 2 | use axum_htmx::HxRequest; 3 | use hypertext::prelude::*; 4 | 5 | use crate::views::{Document, Nav, about, home, list}; 6 | 7 | fn maybe_document( 8 | HxRequest(is_hx_request): HxRequest, 9 | selected: &str, 10 | children: R, 11 | ) -> impl IntoResponse { 12 | rsx! { 13 | @if is_hx_request { 14 |