diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..150e9d2 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: weekly + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: weekly diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..2bbd76b --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,40 @@ +name: check + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +jobs: + verify: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: clippy, rustfmt + - uses: Swatinem/rust-cache@v2 + - uses: taiki-e/install-action@v2 + with: + tool: cargo-hack@0.6,just@1,cargo-msrv@0.16,cargo-deny@0.16,cargo-semver-checks@0.35 + - run: just verify + lint: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: clippy, rustfmt + - uses: Swatinem/rust-cache@v2 + - uses: taiki-e/install-action@v2 + with: + tool: cargo-hack,just,cargo-deny + - run: cargo update + - run: just test lint doc + env: + RUSTFLAGS: "-D warnings" + RUSTDOCFLAGS: "-D warnings" + - run: cargo deny check diff --git a/.github/workflows/create-todo-issues.yml b/.github/workflows/create-todo-issues.yml new file mode 100644 index 0000000..408f8fb --- /dev/null +++ b/.github/workflows/create-todo-issues.yml @@ -0,0 +1,26 @@ +name: "Create Issues from TODO comments" + +on: + push: + branches: [ main ] + workflow_dispatch: + inputs: + COMMIT_REF: + description: The SHA of the commit to get the diff for + required: true + BASE_COMMIT: + description: By default, the commit entered above is compared to the one directly before it; to go back further, enter an earlier SHA here + required: false + +jobs: + todo-to-issues: + runs-on: ubuntu-latest + permissions: + issues: write + contents: read + steps: + - uses: actions/checkout@v4 + - uses: alstr/todo-to-issue-action@master + env: + MANUAL_COMMIT_REF: ${{ inputs.COMMIT_REF }} + MANUAL_BASE_REF: ${{ inputs.BASE_COMMIT }} diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml new file mode 100644 index 0000000..3b9d05f --- /dev/null +++ b/.github/workflows/github-release.yml @@ -0,0 +1,19 @@ +name: Create github release + +permissions: + contents: write + +on: + push: + tags: + - v[0-9]+.* + +jobs: + create-release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: taiki-e/create-gh-release-action@v1 + with: + changelog: CHANGELOG.md + token: ${{ github.token }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ce771a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Rust +/target +/.cargo/*.toml diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..021cd6f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ +# 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.1.0/). + + +## [Unreleased] + + +[Unreleased]: https://github.com/jcornaz/fun-htmx/compare/...HEAD diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..d538b49 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,174 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "fun-html" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa7e485d48e1f5fffbd08e734f721c86a8110dddc8a2f2955a74efbfa28fda3" +dependencies = [ + "html-escape", +] + +[[package]] +name = "fun-htmx" +version = "1.1.0" +dependencies = [ + "fun-html", + "rstest", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "html-escape" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" +dependencies = [ + "utf8-width", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + +[[package]] +name = "rstest" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2c585be59b6b5dd66a9d2084aa1d8bd52fbdb806eafdeffb52791147862035" +dependencies = [ + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825ea780781b15345a146be27eaefb05085e337e869bff01b4306a4fd4a9ad5a" +dependencies = [ + "cfg-if", + "glob", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn", + "unicode-ident", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "syn" +version = "2.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..2213487 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "fun-htmx" +version = "1.1.0" +license = "MIT" +authors = ["Jonathan Cornaz"] +edition = "2021" +rust-version = "1.60" +repository = "https://github.com/jcornaz/fun-htmx" +description = "HTMX attributes for `fun-html`" +categories = ["template-engine"] +keywords = ["html", "web", "functional", "htmx", "fun-html"] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[features] +default = ["std"] +std = ["fun-html/std"] + +[dependencies] +# Public +fun-html = { version = "1", default-features = false, optional = true } + +[dev-dependencies] +rstest = { version = "0.23", default-features = false } diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..87fb696 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Jonathan Cornaz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..d70adbb --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# fun-htmx + +![License](https://img.shields.io/github/license/jcornaz/fun-htmx) +![MSRV](https://img.shields.io/crates/msrv/fun-htmx) + +HTMX attributes for [fun-html] + +[fun-html]: https://github.com/jcornaz/fun-html + + +## Feature flags + +* `std`: enabled by default. must be disabled to compile to `no_std` + + +## MSRV + +The minimum supported rust version is currently `1.60`. + +It will be updated when required, and that will not be considered a breaking change (it can happen in a minor version). + + +## MIT License + +Copyright (c) 2024 Jonathan Cornaz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..a35104d --- /dev/null +++ b/deny.toml @@ -0,0 +1,19 @@ +[advisories] +yanked = "deny" +ignore = [] + +[licenses] +unused-allowed-license = "allow" +private.ignore = true +allow = [ + "Unlicense", + "MIT", + "Apache-2.0", +] + +[sources] +unknown-registry = "deny" +unknown-git = "deny" + +[bans] +multiple-versions = "allow" diff --git a/justfile b/justfile new file mode 100644 index 0000000..941c943 --- /dev/null +++ b/justfile @@ -0,0 +1,37 @@ +set dotenv-load + +# Perform all verifications (compile, test, lint, etc.) +verify: test lint doc check-msrv + # TODO cargo semver-checks + cargo deny check licenses + +# Watch the source files and run `just verify` when source changes +watch: + cargo watch --delay 0.1 --clear --why -- just verify + +# Run the tests +test: + cargo hack test --tests --feature-powerset --locked + cargo test --examples --all-features --locked + cargo test --doc --all-features --locked + +# Run the static code analysis +lint: + cargo fmt -- --check + cargo hack clippy --each-feature --all-targets --locked + +# Build the documentation +doc *args: + cargo doc --all-features --no-deps {{args}} + +# Open the documentation page +doc-open: (doc "--open") + +# Make sure the MSRV is satisfiable +check-msrv: + cargo msrv verify + +release *args: verify + test $GITHUB_TOKEN + test $CARGO_REGISTRY_TOKEN + cargo release {{args}} diff --git a/release.toml b/release.toml new file mode 100644 index 0000000..ccee63d --- /dev/null +++ b/release.toml @@ -0,0 +1,23 @@ +allow-branch = ["main"] +pre-release-commit-message = "release {{version}}" + +[[pre-release-replacements]] +file = "CHANGELOG.md" +search = "## \\[Unreleased\\]" +replace = "## [Unreleased]\n\n\n## [{{version}}] - {{date}}" +prerelease = true +exactly = 1 + +[[pre-release-replacements]] +file = "CHANGELOG.md" +search = "\\.\\.\\.HEAD" +replace = "...v{{version}}" +prerelease = true +exactly = 1 + +[[pre-release-replacements]] +file = "CHANGELOG.md" +search = "\\[Unreleased\\]:" +replace = "[Unreleased]: https://github.com/jcornaz/fun-htmx/compare/v{{version}}...HEAD\n[{{version}}]:" +prerelease = true +exactly = 1 diff --git a/src/interop/rocket_v05.rs b/src/interop/rocket_v05.rs new file mode 100644 index 0000000..e3ebe19 --- /dev/null +++ b/src/interop/rocket_v05.rs @@ -0,0 +1,13 @@ +use rocket_v05::response::{content::RawHtml, Responder}; + +impl<'r> Responder<'r, 'static> for crate::Element { + fn respond_to(self, req: &'r rocket_v05::Request<'_>) -> rocket_v05::response::Result<'static> { + RawHtml(self.to_string()).respond_to(req) + } +} + +impl<'r> Responder<'r, 'static> for crate::Document { + fn respond_to(self, req: &'r rocket_v05::Request<'_>) -> rocket_v05::response::Result<'static> { + RawHtml(self.to_string()).respond_to(req) + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..6cff71c --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,3 @@ +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +// TODO #![warn(missing_docs)]