diff --git a/.github/workflows/ci-without-db.yml b/.github/workflows/ci-without-db.yml new file mode 100644 index 000000000..15c5f0481 --- /dev/null +++ b/.github/workflows/ci-without-db.yml @@ -0,0 +1,75 @@ +name: CI-WITHOUT_DB + +on: + push: + branches: + - master + pull_request: + +env: + RUST_TOOLCHAIN: stable + TOOLCHAIN_PROFILE: minimal + +jobs: + rustfmt: + name: Check Style + runs-on: ubuntu-latest + + permissions: + contents: read + + steps: + - name: Checkout the code + uses: actions/checkout@v4 + - uses: actions-rs/toolchain@v1 + with: + profile: ${{ env.TOOLCHAIN_PROFILE }} + toolchain: nightly + override: true + components: rustfmt + - run: cargo fmt --all -- --check + working-directory: ./examples/without-db + + clippy: + name: Run Clippy + needs: [rustfmt] + runs-on: ubuntu-latest + + permissions: + contents: read + + steps: + - name: Checkout the code + uses: actions/checkout@v4 + - uses: actions-rs/toolchain@v1 + with: + profile: ${{ env.TOOLCHAIN_PROFILE }} + toolchain: ${{ env.RUST_TOOLCHAIN }} + override: true + - name: Setup Rust cache + uses: Swatinem/rust-cache@v2 + - name: Run cargo clippy + run: cargo clippy -- -W clippy::nursery -W clippy::pedantic -W rust-2018-idioms -W rust-2021-compatibility + working-directory: ./examples/without-db + + test: + name: Run Tests + needs: [rustfmt, clippy] + runs-on: ubuntu-latest + + permissions: + contents: read + + steps: + - name: Checkout the code + uses: actions/checkout@v4 + - uses: actions-rs/toolchain@v1 + with: + profile: ${{ env.TOOLCHAIN_PROFILE }} + toolchain: ${{ env.RUST_TOOLCHAIN }} + override: true + - name: Setup Rust cache + uses: Swatinem/rust-cache@v2 + - name: Run cargo test + run: cargo test + working-directory: ./examples/without-db diff --git a/Cargo.lock b/Cargo.lock index 16f03fff2..dd1453dd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2675,7 +2675,6 @@ dependencies = [ "serde_json", "serde_variant", "serde_yaml", - "sqlx", "tera", "thiserror", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 1e75e9ec3..52f4dabd8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,11 +10,12 @@ authors = ["Dotan Nahum ", "Elad Kaplan "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -default = ["auth", "cli"] +default = ["auth", "cli", "with-db"] auth = ["dep:jsonwebtoken", "dep:bcrypt"] cli = ["dep:clap"] testing = ["dep:axum-test"] +with-db = ["dep:sea-orm", "dep:sea-orm-migration"] [dependencies] @@ -29,10 +30,10 @@ sea-orm = { version = "0.12.4", features = [ "sqlx-mysql", "runtime-tokio-rustls", "macros", -] } +], optional = true } + tokio = { version = "1.33.0", features = ["full"] } # the rest -sqlx = "0.7.2" serde = "1.0.193" serde_json = "1.0.108" @@ -64,14 +65,6 @@ tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } # cli/migrations duct = "0.13.6" -# _meta.rs: schema discovery for truncate -# sea-schema = { version = "*", features = ["runtime-tokio-rustls", "sqlx-all"] } -# sqlx = { version = "0.7.2", default-features = false, features = [ -# "mysql", -# "postgres", -# ] } -# url = "*" - config = "0.13.3" tower-http = { version = "0.4.4", features = ["trace", "catch-panic"] } tower-request-id = "0.2.1" @@ -90,6 +83,7 @@ cargo_metadata = "0.18.1" [dependencies.sea-orm-migration] +optional = true version = "0.12.4" features = [ # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI. diff --git a/examples/demo/Cargo.lock b/examples/demo/Cargo.lock index 3bc77a516..cbb8daf39 100644 --- a/examples/demo/Cargo.lock +++ b/examples/demo/Cargo.lock @@ -526,7 +526,6 @@ dependencies = [ "eyre", "include_dir", "insta", - "lazy_static", "migration", "rstest", "rustyrails", @@ -3125,7 +3124,6 @@ dependencies = [ "serde_json", "serde_variant", "serde_yaml", - "sqlx", "tera", "thiserror", "tokio", diff --git a/examples/demo/Cargo.toml b/examples/demo/Cargo.toml index 13a8ae6c8..6f5e32780 100644 --- a/examples/demo/Cargo.toml +++ b/examples/demo/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] rustyrails = { version = "*", path = "../../" } +migration = { path = "migration" } serde = "*" serde_json = "*" @@ -17,30 +18,17 @@ async-trait = "0.1.74" tracing = "0.1.40" chrono = "*" validator = { version = "*" } - -# TODO(review): check if can use this crate from the framework sea-orm = { version = "0.12.4", features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros", ] } -migration = { path = "migration" } - axum = "*" include_dir = "*" uuid = { version = "*", features = ["v4"] } - -# cli tracing-subscriber = { version = "0.3.17", features = ["env-filter", "json"] } -# TODO: this is required by test-utils remove once, -# test-utils migrated into "rustyrails::testing" -lazy_static = "*" - -# TODO: this is required by test-utils. when we should move thie test-utils into the framework and creating a feature called testing -insta = { version = "*", features = ["redactions", "yaml", "filters"] } - [patch.crates-io] # see https://github.com/heim-rs/darwin-libproc/pull/9 # rusty-sidekiq needs robotty/simple-process-stats which depends on darwin-libproc, which depends on @@ -61,3 +49,4 @@ serial_test = "*" rstest = "*" rustyrails = { version = "*", path = "../../", features = ["testing"] } trycmd = "0.14.19" +insta = { version = "*", features = ["redactions", "yaml", "filters"] } diff --git a/examples/without-db/Cargo.lock b/examples/without-db/Cargo.lock new file mode 100644 index 000000000..0e97e6678 --- /dev/null +++ b/examples/without-db/Cargo.lock @@ -0,0 +1,3416 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "auto-future" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-test" +version = "13.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deffdcc6ae7bc024b82f4bd3f46b048781a504588e86716a6d5ccc10b2615e99" +dependencies = [ + "anyhow", + "async-trait", + "auto-future", + "axum", + "bytes", + "cookie", + "http", + "hyper", + "pretty_assertions", + "reserve-port", + "serde", + "serde_json", + "serde_urlencoded", + "smallvec", + "tokio", + "tower", + "url", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "bb8" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98b4b0f25f18bcdc3ac72bdb486ed0acf7e185221fd4dc985bc15db5800b0ba2" +dependencies = [ + "async-trait", + "futures-channel", + "futures-util", + "parking_lot", + "tokio", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "blo" +version = "0.1.0" +dependencies = [ + "async-trait", + "axum", + "chrono", + "eyre", + "include_dir", + "insta", + "rstest", + "rustyrails", + "serde", + "serde_json", + "serial_test", + "tokio", + "tracing", + "tracing-subscriber", + "trycmd", + "uuid", + "validator", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bstr" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byte-unit" +version = "4.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c" +dependencies = [ + "serde", + "utf8-width", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.48.5", +] + +[[package]] +name = "chrono-tz" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e23185c0e21df6ed832a12e2bda87c7d1def6842881fb634a8511ced741b0d76" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", +] + +[[package]] +name = "chumsky" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9" +dependencies = [ + "hashbrown 0.14.2", + "stacker", +] + +[[package]] +name = "clap" +version = "4.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "config" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" +dependencies = [ + "async-trait", + "json5", + "lazy_static", + "nom", + "pathdiff", + "ron", + "rust-ini", + "serde", + "serde_json", + "toml", + "yaml-rust", +] + +[[package]] +name = "console" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "windows-sys 0.45.0", +] + +[[package]] +name = "content_inspector" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38" +dependencies = [ + "memchr", +] + +[[package]] +name = "cookie" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8" +dependencies = [ + "time", + "version_check", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "cron_clock" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a8699d8ed16e3db689f8ae04d8dc3c6666a4ba7e724e5a157884b7cc385d16b" +dependencies = [ + "chrono", + "nom", + "once_cell", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "cruet" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "113a9e83d8f614be76de8df1f25bf9d0ea6e85ea573710a3d3f3abe1438ae49c" +dependencies = [ + "once_cell", + "regex", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darwin-libproc" +version = "0.2.0" +source = "git+https://github.com/codota/darwin-libproc#37aa92edb46ed077f3f5213fe4ea009e795230c8" +dependencies = [ + "darwin-libproc-sys", + "libc", + "memchr", +] + +[[package]] +name = "darwin-libproc-sys" +version = "0.2.0" +source = "git+https://github.com/codota/darwin-libproc#37aa92edb46ed077f3f5213fe4ea009e795230c8" + +[[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.2", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "deunicode" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a1abaf4d861455be59f64fd2b55606cb151fce304ede7165f410243ce96bde6" + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dlv-list" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" + +[[package]] +name = "duct" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ae3fc31835f74c2a7ceda3aeede378b0ae2e74c8f1c36559fcc9ae2a4e7d3e" +dependencies = [ + "libc", + "once_cell", + "os_pipe", + "shared_child", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "email-encoding" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfb21b9878cf7a348dcb8559109aabc0ec40d69924bd706fa5149846c4fef75" +dependencies = [ + "base64 0.21.5", + "memchr", +] + +[[package]] +name = "email_address" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[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.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "eyre" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80f656be11ddf91bd709454d15d5bd896fbaf4cc3314e69349e4d1569f5b46cd" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "filetime" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "windows-sys 0.48.0", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs-err" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] + +[[package]] +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "globset" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.7", +] + +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +dependencies = [ + "ahash 0.8.6", + "allocator-api2", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humansize" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +dependencies = [ + "libm", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "humantime-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" +dependencies = [ + "humantime", + "serde", +] + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + +[[package]] +name = "ignore" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +dependencies = [ + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "include_dir" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.2", +] + +[[package]] +name = "insta" +version = "1.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d64600be34b2fcfc267740a243fa7744441bb4947a619ac4e5bb6507f35fbfc" +dependencies = [ + "console", + "lazy_static", + "linked-hash-map", + "pest", + "pest_derive", + "regex", + "serde", + "similar", + "yaml-rust", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lettre" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a466bc111374ccf4d90877dba636924a2185e67e5be4b35d32043199365097b2" +dependencies = [ + "async-trait", + "base64 0.21.5", + "chumsky", + "email-encoding", + "email_address", + "fastrand", + "futures-io", + "futures-util", + "hostname", + "httpdate", + "idna", + "mime", + "nom", + "once_cell", + "quoted_printable", + "rustls", + "rustls-pemfile", + "socket2 0.5.5", + "tokio", + "tokio-rustls", + "url", + "webpki-roots", +] + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall 0.4.1", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.3", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "ordered-multimap" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" +dependencies = [ + "dlv-list", + "hashbrown 0.12.3", +] + +[[package]] +name = "os_pipe" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae859aa07428ca9a929b936690f8b12dc5f11dd8c6992a18ca93919f28bc177" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pest" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "pest_meta" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "procfs" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab8809e0c18450a2db0f236d2a44ec0b4c1412d0eb936233579f0990faa5d5cd" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "chrono", + "flate2", + "hex", + "lazy_static", + "libc", +] + +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "quoted_printable" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79ec282e887b434b68c18fe5c121d38e72a5cf35119b59e54ec5b992ea9c8eb0" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redis" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa8455fa3621f6b41c514946de66ea0531f57ca017b2e6c7cc368035ea5b46df" +dependencies = [ + "async-trait", + "bytes", + "combine", + "futures-util", + "itoa", + "percent-encoding", + "pin-project-lite", + "ryu", + "sha1_smol", + "tokio", + "tokio-util", + "url", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "relative-path" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c707298afce11da2efef2f600116fa93ffa7a032b5d7b628aa17711ec81383ca" + +[[package]] +name = "reserve-port" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3969e7fe15c6c1532ba1a761628298e870bbd18c252fd41a58445f6091c372a0" +dependencies = [ + "lazy_static", + "thiserror", +] + +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.48.0", +] + +[[package]] +name = "ron" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" +dependencies = [ + "base64 0.13.1", + "bitflags 1.3.2", + "serde", +] + +[[package]] +name = "rrgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5573326bb192af458f3bf97164b5e5b67c4901c0d5dea589fb1d744f73ebc1d6" +dependencies = [ + "cruet", + "fs-err", + "glob", + "heck", + "regex", + "serde", + "serde_json", + "serde_regex", + "serde_yaml", + "tera", + "thiserror", +] + +[[package]] +name = "rstest" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97eeab2f3c0a199bc4be135c36c924b6590b88c377d416494288c14f2db30199" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d428f8247852f894ee1be110b375111b586d4fa431f6c46e64ba5a0dcccbe605" +dependencies = [ + "cfg-if", + "glob", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn 2.0.39", + "unicode-ident", +] + +[[package]] +name = "rust-ini" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.21.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "rusty-sidekiq" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41da6bac897708d794b0d9f8838db7ccb68a84521db58e1e1ed541b5956ec0e3" +dependencies = [ + "async-trait", + "bb8", + "chrono", + "cron_clock", + "gethostname", + "heck", + "hex", + "num_cpus", + "rand", + "redis", + "serde", + "serde_json", + "sha2", + "simple-process-stats", + "slog-term", + "thiserror", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "rustyrails" +version = "0.1.0" +dependencies = [ + "async-trait", + "axum", + "axum-test", + "bb8", + "byte-unit", + "cargo_metadata", + "chrono", + "clap", + "config", + "duct", + "eyre", + "include_dir", + "lazy_static", + "lettre", + "regex", + "rrgen", + "rusty-sidekiq", + "serde", + "serde_json", + "serde_variant", + "serde_yaml", + "tera", + "thiserror", + "tokio", + "tower-http", + "tower-request-id", + "tracing", + "tracing-subscriber", + "validator", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +dependencies = [ + "itoa", + "serde", +] + +[[package]] +name = "serde_regex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf" +dependencies = [ + "regex", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_variant" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47a8ec0b2fd0506290348d9699c0e3eb2e3e8c0498b5a9a6158b3bd4d6970076" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cc7a1570e38322cfe4154732e5110f887ea57e22b76f4bfd32b5bdd3368666c" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "serial_test" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d" +dependencies = [ + "dashmap", + "futures", + "lazy_static", + "log", + "parking_lot", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared_child" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "shlex" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "similar" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aeaf503862c419d66959f5d7ca015337d864e9c49485d771b732e2a20453597" + +[[package]] +name = "simple-process-stats" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbac11c9c71488f54be642954a9d41eefeecbe009fe2c98a6d0ad8c785565199" +dependencies = [ + "darwin-libproc", + "libc", + "procfs", + "thiserror", + "tokio", + "winapi", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slog" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" + +[[package]] +name = "slog-term" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87d29185c55b7b258b4f120eab00f48557d4d9bc814f41713f449d35b0f8977c" +dependencies = [ + "atty", + "slog", + "term", + "thread_local", + "time", +] + +[[package]] +name = "slug" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" +dependencies = [ + "deunicode", + "wasm-bindgen", +] + +[[package]] +name = "smallvec" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "snapbox" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b377c0b6e4715c116473d8e40d51e3fa5b0a2297ca9b2a931ba800667b259ed" +dependencies = [ + "anstream", + "anstyle", + "content_inspector", + "dunce", + "filetime", + "libc", + "normalize-line-endings", + "os_pipe", + "similar", + "snapbox-macros", + "tempfile", + "wait-timeout", + "walkdir", + "windows-sys 0.48.0", +] + +[[package]] +name = "snapbox-macros" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed1559baff8a696add3322b9be3e940d433e7bb4e38d79017205fd37ff28b28e" +dependencies = [ + "anstream", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "stacker" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "winapi", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "tera" +version = "1.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970dff17c11e884a4a09bc76e3a17ef71e01bb13447a11e85226e254fe6d10b8" +dependencies = [ + "chrono", + "chrono-tz", + "globwalk", + "humansize", + "lazy_static", + "percent-encoding", + "pest", + "pest_derive", + "rand", + "regex", + "serde", + "serde_json", + "slug", + "unic-segment", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "libc", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.5", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +dependencies = [ + "bitflags 2.4.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-request-id" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a4fbab3421649e92056980671a04d83aa76e3bd4e7b755a9d9ae24eb2015b25" +dependencies = [ + "http", + "tower-layer", + "tower-service", + "ulid", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "trycmd" +version = "0.14.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed009372a42fb103e6f8767b9222925485e03cca032b700d203e2c5b67bee4fb" +dependencies = [ + "glob", + "humantime", + "humantime-serde", + "rayon", + "serde", + "shlex", + "snapbox", + "toml_edit", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "ulid" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e37c4b6cbcc59a8dcd09a6429fbc7890286bcbb79215cea7b38a3c4c0921d93" +dependencies = [ + "rand", +] + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" +dependencies = [ + "unic-ucd-segment", +] + +[[package]] +name = "unic-ucd-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unsafe-libyaml" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +dependencies = [ + "getrandom", +] + +[[package]] +name = "validator" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b92f40481c04ff1f4f61f304d61793c7b56ff76ac1469f1beb199b1445b253bd" +dependencies = [ + "idna", + "lazy_static", + "regex", + "serde", + "serde_derive", + "serde_json", + "url", + "validator_derive", +] + +[[package]] +name = "validator_derive" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc44ca3088bb3ba384d9aecf40c6a23a676ce23e09bdaca2073d99c207f864af" +dependencies = [ + "if_chain", + "lazy_static", + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "validator_types", +] + +[[package]] +name = "validator_types" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "111abfe30072511849c5910134e8baf8dc05de4c0e5903d681cbd5c9c4d611e3" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.39", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" + +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winnow" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +dependencies = [ + "memchr", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zerocopy" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] diff --git a/examples/without-db/Cargo.toml b/examples/without-db/Cargo.toml new file mode 100644 index 000000000..72e7abb7b --- /dev/null +++ b/examples/without-db/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "blo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +rustyrails = { version = "*", path = "../../", default-features = false, features = [ + "cli", +] } +serde = "*" +serde_json = "*" +eyre = "*" +tokio = { version = "1.33.0", features = ["full"] } +async-trait = "0.1.74" +tracing = "0.1.40" +chrono = "*" +validator = { version = "*" } + +axum = "*" +include_dir = "*" +uuid = { version = "*", features = ["v4"] } +tracing-subscriber = { version = "0.3.17", features = ["env-filter", "json"] } + +[patch.crates-io] +# see https://github.com/heim-rs/darwin-libproc/pull/9 +# rusty-sidekiq needs robotty/simple-process-stats which depends on darwin-libproc, which depends on +# a too old memchr version which sqlx needs. because libproc is native and not pure rust, +# cargo cannot resolve it. so we patch the libproc dependency. +# since simple_process_stats use by rusty-sidekiq is minimal, its better to replace it with something +# that has more velocity on updating dependencies. +darwin-libproc = { git = "https://github.com/codota/darwin-libproc" } + + +[[bin]] +name = "demo" +path = "src/bin/main.rs" +required-features = [] + +[dev-dependencies] +serial_test = "*" +rstest = "*" +rustyrails = { version = "*", path = "../../", default-features = false, features = [ + "testing", + "cli", +] } +trycmd = "0.14.19" +insta = { version = "*", features = ["redactions", "yaml", "filters"] } diff --git a/examples/without-db/config/development.yaml b/examples/without-db/config/development.yaml new file mode 100644 index 000000000..da6f135b4 --- /dev/null +++ b/examples/without-db/config/development.yaml @@ -0,0 +1,33 @@ +logger: + enable: true + level: info + format: compact + # filters: + # - sea_orm_migration=error +server: + port: 3000 + middlewares: + limit_payload: + enable: true + body_limit: 5mb + logger: + enable: true + catch_panic: + enable: true +workers: + mode: BackgroundQueue +mailer: + smtp: + enable: true + host: localhost + port: 1025 + secure: false + # auth: + # user: + # password: +redis: + uri: redis://127.0.0.1/ + dangerously_flush: false +auth: + secret: PqRwLF2rhHe8J22oBeHy + expiration: 604800 diff --git a/examples/without-db/config/production.yaml b/examples/without-db/config/production.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/examples/without-db/config/test.yaml b/examples/without-db/config/test.yaml new file mode 100644 index 000000000..5d983e61d --- /dev/null +++ b/examples/without-db/config/test.yaml @@ -0,0 +1,31 @@ +logger: + enable: false + level: info + format: compact +server: + port: 3000 + middlewares: + limit_payload: + enable: true + body_limit: 5mb + logger: + enable: true + catch_panic: + enable: true +workers: + mode: ForegroundBlocking +mailer: + smtp: + enable: true + host: localhost + port: 1025 + secure: false + # auth: + # user: + # password: +redis: + uri: redis://127.0.0.1/ + dangerously_flush: true +auth: + secret: PqRwLF2rhHe8J22oBeHy + expiration: 604800 diff --git a/examples/without-db/src/app.rs b/examples/without-db/src/app.rs new file mode 100644 index 000000000..2b2aa4544 --- /dev/null +++ b/examples/without-db/src/app.rs @@ -0,0 +1,25 @@ +use async_trait::async_trait; +use rustyrails::{ + app::{AppContext, Hooks}, + controller::AppRoutes, + task::Tasks, + worker::{AppWorker, Processor}, +}; + +use crate::{controllers, tasks, workers::downloader::DownloadWorker}; + +pub struct App; +#[async_trait] +impl Hooks for App { + fn routes() -> AppRoutes { + AppRoutes::with_default_routes().add_route(controllers::foo::routes()) + } + + fn connect_workers<'a>(p: &'a mut Processor, ctx: &'a AppContext) { + p.register(DownloadWorker::build(ctx)); + } + + fn register_tasks(tasks: &mut Tasks) { + tasks.register(tasks::example::ExpReport); + } +} diff --git a/examples/without-db/src/bin/main.rs b/examples/without-db/src/bin/main.rs new file mode 100644 index 000000000..d0a754e7c --- /dev/null +++ b/examples/without-db/src/bin/main.rs @@ -0,0 +1,7 @@ +use blo::app::App; +use rustyrails::cli; + +#[tokio::main] +async fn main() -> eyre::Result<()> { + cli::main::().await +} diff --git a/examples/without-db/src/controllers/foo.rs b/examples/without-db/src/controllers/foo.rs new file mode 100644 index 000000000..69ed52132 --- /dev/null +++ b/examples/without-db/src/controllers/foo.rs @@ -0,0 +1,21 @@ +use axum::{ + extract::State, + routing::{get, post}, +}; +use rustyrails::{ + app::AppContext, + controller::{format, Routes}, + Result, +}; + +async fn index(State(_ctx): State) -> Result { + format::text("Rustyrails") +} + +pub async fn echo(req_body: String) -> String { + req_body +} + +pub fn routes() -> Routes { + Routes::new().add("/", get(index)).add("/echo", post(echo)) +} diff --git a/examples/without-db/src/controllers/mod.rs b/examples/without-db/src/controllers/mod.rs new file mode 100644 index 000000000..b52703b25 --- /dev/null +++ b/examples/without-db/src/controllers/mod.rs @@ -0,0 +1 @@ +pub mod foo; diff --git a/examples/without-db/src/lib.rs b/examples/without-db/src/lib.rs new file mode 100644 index 000000000..c365fecc7 --- /dev/null +++ b/examples/without-db/src/lib.rs @@ -0,0 +1,6 @@ +pub mod app; +pub mod controllers; +pub mod mailers; +pub mod tasks; +pub mod views; +pub mod workers; diff --git a/examples/without-db/src/mailers/auth.rs b/examples/without-db/src/mailers/auth.rs new file mode 100644 index 000000000..fa74f08dd --- /dev/null +++ b/examples/without-db/src/mailers/auth.rs @@ -0,0 +1,40 @@ +// auth mailer +#![allow(non_upper_case_globals)] + +use include_dir::{include_dir, Dir}; +use rustyrails::{ + app::AppContext, + mailer::{Args, Mailer}, + Result, +}; +use serde_json::json; + +static welcome: Dir<'_> = include_dir!("src/mailers/auth/welcome"); +// #[derive(Mailer)] // -- disabled for faster build speed. it works. but lets +// move on for now. + +#[allow(clippy::module_name_repetitions)] +pub struct AuthMailer {} +impl Mailer for AuthMailer {} +impl AuthMailer { + /// Sending welcome email the the given user + /// + /// # Errors + /// + /// When email sending is failed + pub async fn send_welcome(ctx: &AppContext, _user_id: &str) -> Result<()> { + Self::mail_template( + ctx, + &welcome, + Args { + to: "foo@example.com".to_string(), + locals: json!({ + "name": "joe" + }), + ..Default::default() + }, + ) + .await?; + Ok(()) + } +} diff --git a/examples/without-db/src/mailers/auth/forgot/html.ejs b/examples/without-db/src/mailers/auth/forgot/html.ejs new file mode 100644 index 000000000..9eecc95d3 --- /dev/null +++ b/examples/without-db/src/mailers/auth/forgot/html.ejs @@ -0,0 +1,8 @@ +; + + + You can + reset your password + + + diff --git a/examples/without-db/src/mailers/auth/forgot/subject.ejs b/examples/without-db/src/mailers/auth/forgot/subject.ejs new file mode 100644 index 000000000..4938df1e3 --- /dev/null +++ b/examples/without-db/src/mailers/auth/forgot/subject.ejs @@ -0,0 +1 @@ +Your reset password link diff --git a/examples/without-db/src/mailers/auth/forgot/text.ejs b/examples/without-db/src/mailers/auth/forgot/text.ejs new file mode 100644 index 000000000..faa520ab4 --- /dev/null +++ b/examples/without-db/src/mailers/auth/forgot/text.ejs @@ -0,0 +1,3 @@ +Reset your password with this link: + +http://localhost/reset/<%= resetToken %> diff --git a/examples/without-db/src/mailers/auth/welcome/html.t b/examples/without-db/src/mailers/auth/welcome/html.t new file mode 100644 index 000000000..e0eee75ea --- /dev/null +++ b/examples/without-db/src/mailers/auth/welcome/html.t @@ -0,0 +1,10 @@ +; + + + You can{' '} + + verify your account + + + + diff --git a/examples/without-db/src/mailers/auth/welcome/subject.t b/examples/without-db/src/mailers/auth/welcome/subject.t new file mode 100644 index 000000000..122d0922b --- /dev/null +++ b/examples/without-db/src/mailers/auth/welcome/subject.t @@ -0,0 +1 @@ +Welcome <%= name %> diff --git a/examples/without-db/src/mailers/auth/welcome/text.t b/examples/without-db/src/mailers/auth/welcome/text.t new file mode 100644 index 000000000..9ef614dd4 --- /dev/null +++ b/examples/without-db/src/mailers/auth/welcome/text.t @@ -0,0 +1,4 @@ +Welcome <%= name %>, you can now log in. + Verify your account with the link below: + + http://localhost/verify/<%= verifyToken %> diff --git a/examples/without-db/src/mailers/mod.rs b/examples/without-db/src/mailers/mod.rs new file mode 100644 index 000000000..0e4a05d59 --- /dev/null +++ b/examples/without-db/src/mailers/mod.rs @@ -0,0 +1 @@ +pub mod auth; diff --git a/examples/without-db/src/tasks/example.rs b/examples/without-db/src/tasks/example.rs new file mode 100644 index 000000000..4447e9e9d --- /dev/null +++ b/examples/without-db/src/tasks/example.rs @@ -0,0 +1,24 @@ +use std::collections::BTreeMap; + +use async_trait::async_trait; +use rustyrails::{ + app::AppContext, + task::{Task, TaskInfo}, + Result, +}; + +pub struct ExpReport; +#[async_trait] +impl Task for ExpReport { + fn task(&self) -> TaskInfo { + TaskInfo { + name: "example".to_string(), + detail: "output a example task".to_string(), + } + } + async fn run(&self, _app_context: &AppContext, _vars: &BTreeMap) -> Result<()> { + println!("example task executed"); + + Ok(()) + } +} diff --git a/examples/without-db/src/tasks/mod.rs b/examples/without-db/src/tasks/mod.rs new file mode 100644 index 000000000..d4d8a94c8 --- /dev/null +++ b/examples/without-db/src/tasks/mod.rs @@ -0,0 +1 @@ +pub mod example; diff --git a/examples/without-db/src/views/mod.rs b/examples/without-db/src/views/mod.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/without-db/src/views/mod.rs @@ -0,0 +1 @@ + diff --git a/examples/without-db/src/workers/downloader.rs b/examples/without-db/src/workers/downloader.rs new file mode 100644 index 000000000..3931baa32 --- /dev/null +++ b/examples/without-db/src/workers/downloader.rs @@ -0,0 +1,27 @@ +use async_trait::async_trait; +use rustyrails::{ + app::AppContext, + worker::{AppWorker, Result, Worker}, +}; +use serde::{Deserialize, Serialize}; + +pub struct DownloadWorker { + pub ctx: AppContext, +} + +#[derive(Deserialize, Debug, Serialize)] +pub struct DownloadWorkerArgs {} + +impl AppWorker for DownloadWorker { + fn build(ctx: &AppContext) -> Self { + Self { ctx: ctx.clone() } + } +} + +#[async_trait] +impl Worker for DownloadWorker { + async fn perform(&self, _args: DownloadWorkerArgs) -> Result<()> { + println!("Download worker started"); + Ok(()) + } +} diff --git a/examples/without-db/src/workers/mod.rs b/examples/without-db/src/workers/mod.rs new file mode 100644 index 000000000..acb5733da --- /dev/null +++ b/examples/without-db/src/workers/mod.rs @@ -0,0 +1 @@ +pub mod downloader; diff --git a/examples/without-db/tests/cli_tests.rs b/examples/without-db/tests/cli_tests.rs new file mode 100644 index 000000000..b5269d0ed --- /dev/null +++ b/examples/without-db/tests/cli_tests.rs @@ -0,0 +1,5 @@ +#[test] +fn cli_tests() { + let t = trycmd::TestCases::new(); + t.case("tests/cmd/*.trycmd"); +} diff --git a/examples/without-db/tests/cmd/cli.trycmd b/examples/without-db/tests/cmd/cli.trycmd new file mode 100644 index 000000000..f119fc329 --- /dev/null +++ b/examples/without-db/tests/cmd/cli.trycmd @@ -0,0 +1,47 @@ +```console +$ demo +? 2 +Work in progress + +Usage: demo [OPTIONS] + +Commands: + start Start an app + task Run a custom task + generate code generation creates a set of files and code templates based on a predefined set of rules + help Print this message or the help of the given subcommand(s) + +Options: + -e, --environment Specify the environment [default: development] + -h, --help Print help + -V, --version Print version + +``` + +```console +$ demo generate +? 2 +code generation creates a set of files and code templates based on a predefined set of rules + +Usage: demo generate [OPTIONS] + +Commands: + controller Generate a new controller with the given controller name, and test file + task Generate a Task based on the given name + worker Generate worker + mailer Generate mailer + help Print this message or the help of the given subcommand(s) + +Options: + -e, --environment Specify the environment [default: development] + -h, --help Print help + -V, --version Print version + +``` + +```console +$ demo task +example [output a example task] + +``` + diff --git a/examples/without-db/tests/cmd/mod.rs b/examples/without-db/tests/cmd/mod.rs new file mode 100644 index 000000000..c2e46cdd7 --- /dev/null +++ b/examples/without-db/tests/cmd/mod.rs @@ -0,0 +1 @@ +mod requests; diff --git a/examples/without-db/tests/mod.rs b/examples/without-db/tests/mod.rs new file mode 100644 index 000000000..c2e46cdd7 --- /dev/null +++ b/examples/without-db/tests/mod.rs @@ -0,0 +1 @@ +mod requests; diff --git a/examples/without-db/tests/requests/foo.rs b/examples/without-db/tests/requests/foo.rs new file mode 100644 index 000000000..8f7c0d7ce --- /dev/null +++ b/examples/without-db/tests/requests/foo.rs @@ -0,0 +1,42 @@ +use blo::app::App; +use insta::assert_debug_snapshot; +use rustyrails::testing; +use serial_test::serial; + +// TODO: see how to dedup / extract this to app-local test utils +// not to framework, because that would require a runtime dep on insta +macro_rules! configure_insta { + ($($expr:expr),*) => { + let mut settings = insta::Settings::clone_current(); + settings.set_prepend_module_to_snapshot(false); + let _guard = settings.bind_to_scope(); + }; +} + +#[tokio::test] +#[serial] +async fn can_get_index() { + testing::request::(|request, _ctx| async move { + let response = request.get("/").await; + + assert_eq!(response.text(), "Rustyrails"); + assert_eq!(response.status_code(), 200); + }) + .await; +} + +#[tokio::test] +#[serial] +async fn can_print_echo() { + configure_insta!(); + + testing::request::(|request, _ctx| async move { + let response = request + .post("/echo") + .json(&serde_json::json!({"site": "Rustyrails"})) + .await; + + assert_debug_snapshot!((response.status_code(), response.text())); + }) + .await; +} diff --git a/examples/without-db/tests/requests/mod.rs b/examples/without-db/tests/requests/mod.rs new file mode 100644 index 000000000..f4ad3bff5 --- /dev/null +++ b/examples/without-db/tests/requests/mod.rs @@ -0,0 +1 @@ +mod foo; diff --git a/examples/without-db/tests/requests/snapshots/can_print_echo.snap b/examples/without-db/tests/requests/snapshots/can_print_echo.snap new file mode 100644 index 000000000..e7cd296b7 --- /dev/null +++ b/examples/without-db/tests/requests/snapshots/can_print_echo.snap @@ -0,0 +1,8 @@ +--- +source: tests/requests/foo.rs +expression: "(response.status_code(), response.text())" +--- +( + 200, + "{\"site\":\"Rustyrails\"}", +) diff --git a/src/_meta.rs b/src/_meta.rs deleted file mode 100644 index 33fc8da30..000000000 --- a/src/_meta.rs +++ /dev/null @@ -1,121 +0,0 @@ -use url::Url; - -use crate::{errors::Error, Result}; - -pub async fn discover_table_names(database_url: &str) -> Result> { - let database_schema = "public"; - let max_connections = 2; - // The database should be a valid URL that can be parsed - // protocol://username:password@host/database_name - let url = Url::parse(database_url).map_err(Box::from)?; - let is_sqlite = url.scheme() == "sqlite"; - - let filter_hidden_tables = |table: &str| -> bool { !table.starts_with('_') }; - - let database_name = if !is_sqlite { - // The database name should be the first element of the path string - // - // Throwing an error if there is no database name since it might be - // accepted by the database without it, while we're looking to dump - // information from a particular database - let database_name = url - .path_segments() - .unwrap_or_else(|| { - panic!( - "There is no database name as part of the url path: {}", - url.as_str() - ) - }) - .next() - .unwrap(); - - // An empty string as the database name is also an error - if database_name.is_empty() { - panic!( - "There is no database name as part of the url path: {}", - url.as_str() - ); - } - - database_name - } else { - Default::default() - }; - - let names = match url.scheme() { - "mysql" => { - use sea_schema::mysql::discovery::SchemaDiscovery; - use sqlx::MySql; - let connection = connect::(max_connections, url.as_str(), None).await?; - let schema_discovery = SchemaDiscovery::new(connection, database_name); - let schema = schema_discovery.discover().await.map_err(Box::from)?; - let names: Vec = schema - .tables - .into_iter() - .filter(|schema| filter_hidden_tables(&schema.info.name)) - .map(|schema| schema.info.name.to_string()) - .collect(); - names - } - "sqlite" => { - use sea_schema::sqlite::discovery::SchemaDiscovery; - use sqlx::Sqlite; - - let connection = connect::(max_connections, url.as_str(), None).await?; - let schema_discovery = SchemaDiscovery::new(connection); - let schema = schema_discovery.discover().await.map_err(Box::from)?; - let names = schema - .tables - .into_iter() - .filter(|schema| filter_hidden_tables(&schema.name)) - .map(|schema| schema.name.to_string()) - .collect(); - names - } - "postgres" | "postgresql" => { - use sea_schema::postgres::discovery::SchemaDiscovery; - use sqlx::Postgres; - let schema = &database_schema; - let connection = connect::(max_connections, url.as_str(), Some(schema)) - .await - .map_err(|e| Error::Message(e.to_string()))?; - let schema_discovery = SchemaDiscovery::new(connection, schema); - let schema = schema_discovery.discover().await.map_err(Box::from)?; - let names = schema - .tables - .into_iter() - .filter(|schema| filter_hidden_tables(&schema.info.name)) - .map(|schema| schema.info.name.to_string()) - .collect(); - names - } - _ => unimplemented!("{} is not supported", url.scheme()), - }; - Ok(names) -} - -async fn connect( - max_connections: u32, - url: &str, - schema: Option<&str>, -) -> Result> -where - DB: sqlx::Database, - for<'a> &'a mut ::Connection: sqlx::Executor<'a>, -{ - let mut pool_options = sqlx::pool::PoolOptions::::new().max_connections(max_connections); - // Set search_path for Postgres, E.g. Some("public") by default - // MySQL & SQLite connection initialize with schema `None` - if let Some(schema) = schema { - let sql = format!("SET search_path = '{schema}'"); - pool_options = pool_options.after_connect(move |conn, _| { - let sql = sql.clone(); - Box::pin(async move { - sqlx::Executor::execute(conn, sql.as_str()) - .await - .map(|_| ()) - }) - }); - } - Ok(pool_options.connect(url).await.map_err(Box::from)?) -} diff --git a/src/app.rs b/src/app.rs index d6868c1cb..8948d752e 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,11 +1,14 @@ //! This module contains the core components and traits for building a web //! server application. - +#[cfg(feature = "with-db")] use std::path::Path; use async_trait::async_trait; +#[cfg(feature = "with-db")] use sea_orm::DatabaseConnection; +#[cfg(feature = "with-db")] +use crate::Result; use crate::{ config::Config, controller::AppRoutes, @@ -13,7 +16,6 @@ use crate::{ mailer::EmailSender, task::Tasks, worker::{Pool, Processor, RedisConnectionManager}, - Result, }; /// Represents the application context for a web server. @@ -27,7 +29,8 @@ use crate::{ pub struct AppContext { /// The environment in which the application is running. pub environment: Environment, - /// A database connection used by the application. + #[cfg(feature = "with-db")] + /// A database connection used by the application. pub db: DatabaseConnection, /// An optional connection pool for Redis, for worker tasks pub redis: Option>, @@ -47,6 +50,7 @@ pub struct AppContext { /// # Example /// /// ```rust +/// # #[cfg(feature = "with-db")] { /// use rustyrails::{ /// app::{AppContext, Hooks}, /// controller::AppRoutes, @@ -87,6 +91,7 @@ pub struct AppContext { /// Ok(()) /// } /// } +/// } /// ``` #[async_trait] pub trait Hooks { @@ -97,12 +102,14 @@ pub trait Hooks { fn connect_workers<'a>(p: &'a mut Processor, ctx: &'a AppContext); /// Registers custom tasks with the provided [`Tasks`] object. fn register_tasks(tasks: &mut Tasks); + #[cfg(feature = "with-db")] /// Truncates the database as required. Users should implement this /// function. The truncate controlled from the [`crate::config::Database`] /// by changing dangerously_truncate to true (default false). /// Truncate can be useful when you want to truncate the database before any - /// test. + /// test. async fn truncate(db: &DatabaseConnection) -> Result<()>; - /// Seeds the database with initial data. + #[cfg(feature = "with-db")] + /// Seeds the database with initial data. async fn seed(db: &DatabaseConnection, path: &Path) -> Result<()>; } diff --git a/src/boot.rs b/src/boot.rs index ac55fb23b..c45ad57de 100644 --- a/src/boot.rs +++ b/src/boot.rs @@ -7,6 +7,7 @@ //! This example hows manually bootstrapping the webserver. //! //! ```rust +//! # #[cfg(feature = "with-db")] { //! use async_trait::async_trait; //! use rustyrails::{ //! app::{AppContext, Hooks}, @@ -50,17 +51,20 @@ //! } //! //! let boot_result = boot::create_app::(StartMode::ServerAndWorker, "development"); +//! } //! ``` use std::{collections::BTreeMap, str::FromStr}; use axum::Router; +#[cfg(feature = "with-db")] use sea_orm_migration::MigratorTrait; use tracing::trace; +#[cfg(feature = "with-db")] +use crate::db; use crate::{ app::{AppContext, Hooks}, config::{self, Config}, - db, environment::Environment, errors::Error, logger, @@ -173,6 +177,7 @@ pub enum RunDbCommand { Truncate, } +#[cfg(feature = "with-db")] /// Handles database commands. /// /// # Errors @@ -230,6 +235,7 @@ pub async fn create_context(environment: &str) -> Result { if config.logger.enable { logger::init(&config.logger); } + #[cfg(feature = "with-db")] let db = db::connect(&config.database).await?; let mailer = if let Some(cfg) = config.mailer.as_ref() { @@ -241,6 +247,7 @@ pub async fn create_context(environment: &str) -> Result { let redis = connect_redis(&config).await; Ok(AppContext { environment, + #[cfg(feature = "with-db")] db, redis, config, @@ -248,6 +255,7 @@ pub async fn create_context(environment: &str) -> Result { }) } +#[cfg(feature = "with-db")] /// Creates an application based on the specified mode and environment. /// /// # Errors @@ -264,6 +272,25 @@ pub async fn create_app( redis::converge(pool, &app_context.config.redis).await?; } + run_app::(&mode, app_context) +} + +#[cfg(not(feature = "with-db"))] +pub async fn create_app(mode: StartMode, environment: &str) -> Result { + let app_context = create_context(environment).await?; + + if let Some(pool) = &app_context.redis { + redis::converge(pool, &app_context.config.redis).await?; + } + + run_app::(&mode, app_context) +} + +/// Run the application with the given mode +/// # Errors +/// +/// When could not create the application +pub fn run_app(mode: &StartMode, app_context: AppContext) -> Result { match mode { StartMode::ServerOnly => { let app = H::routes().to_router(app_context.clone())?; @@ -292,7 +319,6 @@ pub async fn create_app( } } } - /// Creates and configures a [`Processor`] for handling worker tasks. fn create_processor(app_context: &AppContext) -> Result { let queues = worker::get_queues(&app_context.config.workers.queues); diff --git a/src/cli.rs b/src/cli.rs index 9b021e551..4c8e244ae 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -19,11 +19,14 @@ use std::collections::BTreeMap; use clap::{Parser, Subcommand}; +#[cfg(feature = "with-db")] use sea_orm_migration::MigratorTrait; +#[cfg(feature = "with-db")] +use crate::boot::run_db; use crate::{ app::Hooks, - boot::{create_app, create_context, run_db, run_task, start, RunDbCommand, StartMode}, + boot::{create_app, create_context, run_task, start, RunDbCommand, StartMode}, gen::{self, Component}, }; @@ -50,6 +53,7 @@ enum Commands { #[arg(short, long, action)] server_and_worker: bool, }, + #[cfg(feature = "with-db")] /// Perform DB operations Db { #[command(subcommand)] @@ -74,6 +78,7 @@ enum Commands { #[derive(Subcommand)] enum ComponentArg { + #[cfg(feature = "with-db")] /// Generates a new model file for defining the data structure of your /// application, and test file logic. Model { @@ -109,6 +114,7 @@ enum ComponentArg { impl From for Component { fn from(value: ComponentArg) -> Self { match value { + #[cfg(feature = "with-db")] ComponentArg::Model { name, fields } => Self::Model { name, fields }, ComponentArg::Controller { name } => Self::Controller { name }, ComponentArg::Task { name } => Self::Task { name }, @@ -182,6 +188,7 @@ where /// cli::main::().await /// } /// ``` +#[cfg(feature = "with-db")] pub async fn main() -> eyre::Result<()> { let cli = Cli::parse(); match cli.command { @@ -200,6 +207,7 @@ pub async fn main() -> eyre::Result<()> { let boot_result = create_app::(start_mode, &cli.environment).await?; start(boot_result).await?; } + #[cfg(feature = "with-db")] Commands::Db { command } => { let app_context = create_context(&cli.environment).await?; run_db::(&app_context, command.into()).await?; @@ -218,3 +226,37 @@ pub async fn main() -> eyre::Result<()> { } Ok(()) } + +#[cfg(not(feature = "with-db"))] +pub async fn main() -> eyre::Result<()> { + let cli = Cli::parse(); + match cli.command { + Commands::Start { + worker, + server_and_worker, + } => { + let start_mode = if worker { + StartMode::WorkerOnly + } else if server_and_worker { + StartMode::ServerAndWorker + } else { + StartMode::ServerOnly + }; + + let boot_result = create_app::(start_mode, &cli.environment).await?; + start(boot_result).await?; + } + Commands::Task { name, params } => { + let mut hash = BTreeMap::new(); + for (k, v) in params { + hash.insert(k, v); + } + let app_context = create_context(&cli.environment).await?; + run_task::(&app_context, name.as_ref(), &hash).await?; + } + Commands::Generate { component } => { + gen::generate(component.into())?; + } + } + Ok(()) +} diff --git a/src/config.rs b/src/config.rs index 637eb5dfc..4b034508e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -23,6 +23,7 @@ lazy_static! { pub struct Config { pub logger: Logger, pub server: Server, + #[cfg(feature = "with-db")] pub database: Database, pub redis: Option, pub auth: Auth, diff --git a/src/controller/app_routes.rs b/src/controller/app_routes.rs index 7ff314d98..13ab821eb 100644 --- a/src/controller/app_routes.rs +++ b/src/controller/app_routes.rs @@ -10,7 +10,7 @@ use regex::Regex; use tower_http::{catch_panic::CatchPanicLayer, trace::TraceLayer}; use tower_request_id::{RequestId, RequestIdLayer}; -use super::{health, routes::Routes}; +use super::routes::Routes; use crate::{app::AppContext, Result}; lazy_static! { @@ -28,7 +28,11 @@ impl AppRoutes { /// Create a new instance with the default routes. #[must_use] pub fn with_default_routes() -> Self { - Self::empty().add_route(health::routes()) + let routes = Self::empty().add_route(super::ping::routes()); + #[cfg(feature = "with-db")] + let routes = routes.add_route(super::health::routes()); + + routes } /// Create an empty instance. diff --git a/src/controller/health.rs b/src/controller/health.rs index 4b5563e42..30e5cd0a9 100644 --- a/src/controller/health.rs +++ b/src/controller/health.rs @@ -33,14 +33,7 @@ async fn health(State(ctx): State) -> Result> { format::json(Health { ok: is_ok }) } -/// Check application ping endpoint -async fn ping() -> Result> { - format::json(Health { ok: true }) -} - /// Defines and returns the health-related routes. pub fn routes() -> Routes { - Routes::new() - .add("/_health", get(health)) - .add("/_ping", get(ping)) + Routes::new().add("/_health", get(health)) } diff --git a/src/controller/middleware/mod.rs b/src/controller/middleware/mod.rs index 0e4a05d59..8351c1d8e 100644 --- a/src/controller/middleware/mod.rs +++ b/src/controller/middleware/mod.rs @@ -1 +1,2 @@ +#[cfg(any(feature = "auth", feature = "with-db"))] pub mod auth; diff --git a/src/controller/mod.rs b/src/controller/mod.rs index 9c2c04440..f09183373 100644 --- a/src/controller/mod.rs +++ b/src/controller/mod.rs @@ -7,6 +7,7 @@ //! endpoints to your application //! //! ```rust +//! # #[cfg(feature = "with-db")] { //! use async_trait::async_trait; //! use rustyrails::{ //! app::{AppContext, Hooks}, @@ -48,12 +49,15 @@ //! Ok(()) //! } //! } +//! } //! ``` mod app_routes; pub mod format; +#[cfg(feature = "with-db")] mod health; pub mod middleware; +mod ping; mod routes; pub use app_routes::AppRoutes; diff --git a/src/controller/ping.rs b/src/controller/ping.rs new file mode 100644 index 000000000..f93878107 --- /dev/null +++ b/src/controller/ping.rs @@ -0,0 +1,25 @@ +//! This module contains a base routes related to health checks and status +//! reporting. These routes are commonly used to monitor the health of the +//! application and its dependencies. + +use axum::{routing::get, Json}; +use serde::Serialize; + +use super::{format, routes::Routes}; +use crate::Result; + +/// Represents the health status of the application. +#[derive(Serialize)] +struct Health { + pub ok: bool, +} + +/// Check application ping endpoint +async fn ping() -> Result> { + format::json(Health { ok: true }) +} + +/// Defines and returns the health-related routes. +pub fn routes() -> Routes { + Routes::new().add("/_ping", get(ping)) +} diff --git a/src/errors.rs b/src/errors.rs index 6f4b27dca..6146f3044 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -4,7 +4,7 @@ use axum::http::StatusCode; use config::ConfigError; use lettre::{address::AddressError, transport::smtp}; -use crate::{controller::ErrorDetail, model::ModelError}; +use crate::controller::ErrorDetail; #[derive(thiserror::Error, Debug)] pub enum Error { @@ -32,6 +32,7 @@ pub enum Error { #[error(transparent)] IO(#[from] std::io::Error), + #[cfg(feature = "with-db")] #[error(transparent)] DB(#[from] sea_orm::DbErr), @@ -54,9 +55,10 @@ pub enum Error { #[error("")] CustomError(StatusCode, ErrorDetail), + #[cfg(feature = "with-db")] // Model #[error(transparent)] - Model(#[from] ModelError), + Model(#[from] crate::model::ModelError), // TODO(review):. maybe change to to box instead expose all sidekiq errors #[error(transparent)] diff --git a/src/gen/mod.rs b/src/gen/mod.rs index 71785d7f5..937d799cb 100644 --- a/src/gen/mod.rs +++ b/src/gen/mod.rs @@ -1,15 +1,13 @@ -use cargo_metadata::{MetadataCommand, Package}; -use chrono::Utc; -use rrgen::{GenResult, RRgen}; +use rrgen::RRgen; use serde_json::json; -use crate::{errors::Error, Result}; +#[cfg(feature = "with-db")] +mod model; +use crate::Result; + const CONTROLLER_T: &str = include_str!("templates/controller.t"); const CONTROLLER_TEST_T: &str = include_str!("templates/request_test.t"); -const MODEL_T: &str = include_str!("templates/model.t"); -const MODEL_TEST_T: &str = include_str!("templates/model_test.t"); - const MAILER_T: &str = include_str!("templates/mailer.t"); const MAILER_SUB_T: &str = include_str!("templates/mailer_sub.t"); const MAILER_TEXT_T: &str = include_str!("templates/mailer_text.t"); @@ -20,6 +18,7 @@ const TASK_T: &str = include_str!("templates/task.t"); const WORKER_T: &str = include_str!("templates/worker.t"); pub enum Component { + #[cfg(feature = "with-db")] Model { /// Name of the thing to generate name: String, @@ -44,39 +43,14 @@ pub enum Component { name: String, }, } -fn collect_messages(results: Vec) -> String { - let mut messages = String::new(); - for res in results { - if let rrgen::GenResult::Generated { - message: Some(message), - } = res - { - messages.push_str(&format!("* {message}\n")); - } - } - messages -} + pub fn generate(component: Component) -> Result<()> { let rrgen = RRgen::default(); - let path = std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".to_string()); - let meta = MetadataCommand::new() - .manifest_path("./Cargo.toml") - .current_dir(&path) - .exec()?; - let root: &Package = meta - .root_package() - .ok_or_else(|| Error::Message("cannot find root package in Cargo.toml".to_string()))?; - let pkg_name: &str = &root.name; - let ts = Utc::now(); - match component { + #[cfg(feature = "with-db")] Component::Model { name, fields: _ } => { - let vars = json!({"name": name, "ts": ts, "pkg_name": pkg_name}); - let res1 = rrgen.generate(MODEL_T, &vars)?; - let res2 = rrgen.generate(MODEL_TEST_T, &vars)?; - let message = collect_messages(vec![res1, res2]); - println!("\n---\n{message}---\n"); + model::generate(&rrgen, &name)?; } Component::Controller { name } => { let vars = json!({"name": name}); diff --git a/src/gen/model.rs b/src/gen/model.rs new file mode 100644 index 000000000..712576122 --- /dev/null +++ b/src/gen/model.rs @@ -0,0 +1,40 @@ +use cargo_metadata::{MetadataCommand, Package}; +use chrono::Utc; +use rrgen::{GenResult, RRgen}; +use serde_json::json; + +const MODEL_T: &str = include_str!("templates/model.t"); +const MODEL_TEST_T: &str = include_str!("templates/model_test.t"); + +use crate::{errors::Error, Result}; + +pub fn generate(rrgen: &RRgen, name: &str) -> Result<()> { + let path = std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".to_string()); + let meta = MetadataCommand::new() + .manifest_path("./Cargo.toml") + .current_dir(&path) + .exec()?; + let root: &Package = meta + .root_package() + .ok_or_else(|| Error::Message("cannot find root package in Cargo.toml".to_string()))?; + let pkg_name: &str = &root.name; + let ts = Utc::now(); + let vars = json!({"name": name, "ts": ts, "pkg_name": pkg_name}); + let res1 = rrgen.generate(MODEL_T, &vars)?; + let res2 = rrgen.generate(MODEL_TEST_T, &vars)?; + collect_messages(vec![res1, res2]); + Ok(()) +} + +fn collect_messages(results: Vec) -> String { + let mut messages = String::new(); + for res in results { + if let rrgen::GenResult::Generated { + message: Some(message), + } = res + { + messages.push_str(&format!("* {message}\n")); + } + } + messages +} diff --git a/src/lib.rs b/src/lib.rs index af3955ccf..83685bbf2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,12 @@ //! | `testing | true | Expose Cli commands. | use self::errors::Error; +#[cfg(feature = "with-db")] pub mod db; +#[cfg(feature = "with-db")] +pub mod model; +#[cfg(feature = "with-db")] +pub mod schema; pub mod app; #[cfg(feature = "cli")] @@ -39,9 +44,7 @@ pub mod errors; mod gen; mod logger; pub mod mailer; -pub mod model; mod redis; -pub mod schema; pub mod task; #[cfg(feature = "testing")] pub mod testing; diff --git a/src/redis.rs b/src/redis.rs index dd93f1035..5ebe17fcb 100644 --- a/src/redis.rs +++ b/src/redis.rs @@ -26,6 +26,7 @@ pub async fn converge( Ok(()) } +#[cfg(feature = "with-db")] /// Run Redis ping command pub async fn ping(pool: &Pool) -> Result<()> { let mut conn = pool.get().await?; diff --git a/src/testing.rs b/src/testing.rs index 6f12728e3..f252556dc 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -6,7 +6,9 @@ use axum_test::{TestServer, TestServerConfig}; use lazy_static::lazy_static; +#[cfg(feature = "with-db")] use sea_orm::DatabaseConnection; +#[cfg(feature = "with-db")] use sea_orm_migration::MigratorTrait; use crate::{ @@ -76,6 +78,7 @@ pub fn cleanup_user_model() -> Vec<(&'static str, &'static str)> { combined_filters } +#[cfg(feature = "with-db")] /// Bootstraps test application with test environment hard coded. /// /// # Example @@ -102,6 +105,14 @@ pub async fn boot_test() -> BootResult { .unwrap() } +#[cfg(not(feature = "with-db"))] +pub async fn boot_test() -> BootResult { + boot::create_app::(boot::StartMode::ServerOnly, "test") + .await + .unwrap() +} + +#[cfg(feature = "with-db")] /// Seeds data into the database. /// /// @@ -132,6 +143,7 @@ pub async fn seed(db: &DatabaseConnection) -> eyre::Result<()> { Ok(H::seed(db, path).await?) } +#[cfg(feature = "with-db")] /// Initiates a test request with a provided callback. /// /// # Example @@ -174,3 +186,20 @@ where callback(server, boot.app_context.clone()).await; } + +#[cfg(not(feature = "with-db"))] +pub async fn request(callback: F) +where + F: FnOnce(TestServer, AppContext) -> Fut, + Fut: std::future::Future, +{ + let boot = boot_test::().await; + + let config = TestServerConfig::builder() + .default_content_type("application/json") + .build(); + + let server = TestServer::new_with_config(boot.router.unwrap(), config).unwrap(); + + callback(server, boot.app_context.clone()).await; +} diff --git a/src/validation.rs b/src/validation.rs index 23b460b00..b90af425b 100644 --- a/src/validation.rs +++ b/src/validation.rs @@ -53,9 +53,15 @@ //! ``` use std::collections::HashMap; +use serde::{Deserialize, Serialize}; use validator::{ValidationError, ValidationErrors}; -use crate::model::ModelValidation; +#[derive(Debug, Deserialize, Serialize)] +#[allow(clippy::module_name_repetitions)] +pub struct ModelValidation { + pub code: String, + pub message: Option, +} /// Validate the given email /// @@ -71,7 +77,8 @@ pub fn is_valid_email(email: &str) -> Result<(), ValidationError> { } /// Convert `ValidationErrors` into a `HashMap` of field errors. -fn into_errors(errors: ValidationErrors) -> HashMap> { +#[must_use] +pub fn into_errors(errors: ValidationErrors) -> HashMap> { errors .field_errors() .iter() @@ -89,13 +96,17 @@ fn into_errors(errors: ValidationErrors) -> HashMap } /// Convert `ValidationErrors` into a JSON `Value`. -fn into_json_errors( +/// +/// # Errors +/// when could not convert errors hashmap into a serde value +pub fn into_json_errors( errors: ValidationErrors, ) -> Result { let error_data = into_errors(errors); serde_json::to_value(error_data) } +#[cfg(feature = "with-db")] /// Convert `ValidationErrors` into a `DbErr` for database handling. #[must_use] pub fn into_db_error(errors: ValidationErrors) -> sea_orm::DbErr { @@ -130,6 +141,7 @@ mod tests { assert_eq!(is_valid_email(test_name).is_ok(), expected); } + #[cfg(feature = "with-db")] #[rstest] #[case("foo")] #[case("foo-bar")]