From 65ad20d197d943b03d46b079a398ccbc558fe8f7 Mon Sep 17 00:00:00 2001 From: Nicole Tietz-Sokolskaya Date: Sun, 2 Jun 2024 18:37:15 +0000 Subject: [PATCH] Switch DB layer to Diesel from SeaORM and Fjall (#2) Refactors Pique to use Diesel for the backing database layer instead of the previous choices of SeaORM and Fjall (with a custom DB on top of the KV store). This choice was made to speed up development. I found SeaORM much more challenging to discover things in than Diesel, and with Fjall I was getting mired in building things that already exist. This is a migration to a boring choice, and that's the right decision for this moment in time. Among other things, the diff stats wind up being `47 files changed, 926 insertions(+), 950 deletions(-)` when you exclude lockfile changes and markdown changes. This validates that the code is not significantly more or less verbose, but is simply structured differently. So we're not giving anything up in brevity. I decided to structure query calls into their own submodules, called `q` (short for `query`). I shortened the names to make it easier to type and make lines shorter, which may be a controversial take, but I think that it will wind up being worth it and will be easy to get used to. I also renamed `Context` to `Provider`, because I think `Context` implies things like cancellation, while `Provider` implies giving access to resources, which is more precisely what's going on here. Reviewed-on: https://git.kittencollective.com/nicole/pique/pulls/2 --- Cargo.lock | 1399 ++++------ Cargo.toml | 14 +- README.md | 11 +- .../decisions/0004-uuids-for-primary-keys.md | 47 + diesel.toml | 9 + migration/Cargo.lock | 2351 ----------------- migration/Cargo.toml | 19 - migration/README.md | 41 - migration/src/lib.rs | 14 - .../m20240316_155147_create_users_table.rs | 69 - migration/src/main.rs | 6 - migrations/.keep | 0 migrations/2024-05-31-175324_users/down.sql | 1 + migrations/2024-05-31-175324_users/up.sql | 7 + .../down.sql | 2 + .../up.sql | 18 + .../2024-05-31-204416_permissions/down.sql | 1 + .../2024-05-31-204416_permissions/up.sql | 8 + model_derive/Cargo.lock | 46 - model_derive/Cargo.toml | 11 - model_derive/src/lib.rs | 48 - rustfmt.toml | 5 + src/bin/admin.rs | 58 +- src/bin/pique.rs | 1 - src/context.rs | 42 - src/db.rs | 125 +- src/entity/mod.rs | 5 - src/entity/prelude.rs | 3 - src/entity/user.rs | 22 - src/handler.rs | 16 +- src/handler/documents.rs | 192 +- src/handler/home.rs | 18 +- src/handler/login.rs | 107 +- src/handler/projects.rs | 91 +- src/kv.rs | 42 - src/lib.rs | 8 +- src/logging.rs | 4 +- src/models.rs | 198 +- src/models/documents.rs | 79 + src/models/project_memberships.rs | 92 + src/models/projects.rs | 54 + src/models/users.rs | 85 + src/password.rs | 8 +- src/permissions.rs | 128 + src/prelude.rs | 8 +- src/provider.rs | 55 + src/schema.rs | 42 + src/serialize.rs | 16 - src/server.rs | 41 +- src/session.rs | 39 +- src/templates.rs | 11 +- src/validation.rs | 13 + 52 files changed, 1514 insertions(+), 4216 deletions(-) create mode 100644 _docs/decisions/0004-uuids-for-primary-keys.md create mode 100644 diesel.toml delete mode 100644 migration/Cargo.lock delete mode 100644 migration/Cargo.toml delete mode 100644 migration/README.md delete mode 100644 migration/src/lib.rs delete mode 100644 migration/src/m20240316_155147_create_users_table.rs delete mode 100644 migration/src/main.rs create mode 100644 migrations/.keep create mode 100644 migrations/2024-05-31-175324_users/down.sql create mode 100644 migrations/2024-05-31-175324_users/up.sql create mode 100644 migrations/2024-05-31-203133_projects_and_documents/down.sql create mode 100644 migrations/2024-05-31-203133_projects_and_documents/up.sql create mode 100644 migrations/2024-05-31-204416_permissions/down.sql create mode 100644 migrations/2024-05-31-204416_permissions/up.sql delete mode 100644 model_derive/Cargo.lock delete mode 100644 model_derive/Cargo.toml delete mode 100644 model_derive/src/lib.rs create mode 100644 rustfmt.toml delete mode 100644 src/context.rs delete mode 100644 src/entity/mod.rs delete mode 100644 src/entity/prelude.rs delete mode 100644 src/entity/user.rs delete mode 100644 src/kv.rs create mode 100644 src/models/documents.rs create mode 100644 src/models/project_memberships.rs create mode 100644 src/models/projects.rs create mode 100644 src/models/users.rs create mode 100644 src/permissions.rs create mode 100644 src/provider.rs create mode 100644 src/schema.rs delete mode 100644 src/serialize.rs create mode 100644 src/validation.rs diff --git a/Cargo.lock b/Cargo.lock index b5f13e8..5e7341a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -52,24 +52,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] -[[package]] -name = "aliasable" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" - [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "android-tzdata" @@ -88,47 +82,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -136,9 +131,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "argon2" @@ -152,52 +147,26 @@ dependencies = [ "password-hash", ] -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - [[package]] name = "async-lock" -version = "2.8.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" dependencies = [ - "event-listener", -] - -[[package]] -name = "async-stream" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" -dependencies = [ - "async-stream-impl", - "futures-core", + "event-listener 4.0.3", + "event-listener-strategy", "pin-project-lite", ] -[[package]] -name = "async-stream-impl" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.61", -] - [[package]] name = "async-trait" -version = "0.1.78" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.66", ] [[package]] @@ -217,15 +186,15 @@ checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", "axum-core", @@ -247,7 +216,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 1.0.1", "tokio", "tower", "tower-layer", @@ -270,7 +239,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper", + "sync_wrapper 0.1.2", "tower-layer", "tower-service", "tracing", @@ -294,15 +263,15 @@ dependencies = [ [[package]] name = "axum-login" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7d8260dd72d25b5d97f47a0ac6436fb7d07237ff6df10620ee21351de7df5a" +checksum = "b0fbc0d7bd2577dda9aa9cac096e53b30342725d8eea5798169ff2537a214f45" dependencies = [ "async-trait", "axum", "form_urlencoded", - "ring", "serde", + "subtle", "thiserror", "tower-cookies", "tower-layer", @@ -314,9 +283,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" dependencies = [ "addr2line", "cc", @@ -335,9 +304,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64-simd" @@ -356,10 +325,12 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bigdecimal" -version = "0.3.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +checksum = "9324c8014cd04590682b34f1e9448d38f0674d0f7b2dc553331016ef0e4e9ebc" dependencies = [ + "autocfg", + "libm", "num-bigint", "num-integer", "num-traits", @@ -401,9 +372,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" dependencies = [ "serde", ] @@ -438,35 +409,11 @@ dependencies = [ "generic-array", ] -[[package]] -name = "borsh" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" -dependencies = [ - "borsh-derive", - "cfg_aliases", -] - -[[package]] -name = "borsh-derive" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" -dependencies = [ - "once_cell", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.61", - "syn_derive", -] - [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecheck" @@ -490,12 +437,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "bytecount" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" - [[package]] name = "byteorder" version = "1.5.0" @@ -504,9 +445,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cache-advisor" @@ -517,45 +458,15 @@ dependencies = [ "crossbeam-queue", ] -[[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.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", -] - [[package]] name = "cc" -version = "1.0.90" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -564,12 +475,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "chrono" version = "0.4.38" @@ -580,16 +485,15 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", - "serde", "wasm-bindgen", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] name = "clap" -version = "4.5.3" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -609,14 +513,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.3" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.66", ] [[package]] @@ -627,9 +531,9 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "concurrent-map" @@ -642,6 +546,15 @@ dependencies = [ "stack-map", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -679,9 +592,9 @@ dependencies = [ [[package]] name = "cookie" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ "percent-encoding", "time", @@ -705,9 +618,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.0.1" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" dependencies = [ "crc-catalog", ] @@ -720,18 +633,18 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] @@ -764,21 +677,11 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-skiplist" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df29de440c58ca2cc6e587ec3d22347551a32435fbde9d2bff64e78a9ffa151b" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crypto-common" @@ -819,7 +722,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.61", + "syn 2.0.66", +] + +[[package]] +name = "darling" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.66", +] + +[[package]] +name = "darling_macro" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.66", ] [[package]] @@ -829,7 +767,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -852,9 +790,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -872,14 +810,57 @@ dependencies = [ ] [[package]] -name = "derivative" +name = "diesel" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +checksum = "35b696af9ff4c0d2a507db2c5faafa8aa0205e297e5f11e203a24226d5355e7a" dependencies = [ + "bigdecimal", + "chrono", + "diesel_derives", + "ipnetwork", + "libc", + "libsqlite3-sys", + "num-bigint", + "num-integer", + "num-traits", + "r2d2", + "serde_json", + "time", + "uuid", +] + +[[package]] +name = "diesel_derives" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6fdd83d5947068817016e939596d246e5367279453f2a3433287894f2f2996" +dependencies = [ + "diesel_table_macro_syntax", + "dsl_auto_type", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.66", +] + +[[package]] +name = "diesel_migrations" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a73ce704bad4231f001bff3314d91dce4aba0770cee8b233991859abc15c1f6" +dependencies = [ + "diesel", + "migrations_internals", + "migrations_macros", +] + +[[package]] +name = "diesel_table_macro_syntax" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" +dependencies = [ + "syn 2.0.66", ] [[package]] @@ -901,10 +882,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] -name = "double-ended-peekable" +name = "dsl_auto_type" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0d05e1c0dbad51b52c38bda7adceef61b9efc2baf04acfe8726a8c4630a6f57" +checksum = "ab32c18ea6760d951659768a3e35ea72fc1ba0916d665a88dfe048b2a41e543f" +dependencies = [ + "darling", + "either", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.66", +] [[package]] name = "dtoa" @@ -932,9 +921,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" dependencies = [ "serde", ] @@ -970,23 +959,14 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", ] -[[package]] -name = "error-chain" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" -dependencies = [ - "version_check", -] - [[package]] name = "etcetera" version = "0.8.0" @@ -1005,10 +985,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] -name = "fastrand" -version = "2.0.1" +name = "event-listener" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fault-injection" @@ -1024,32 +1036,10 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.4.1", "windows-sys 0.52.0", ] -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - -[[package]] -name = "fjall" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caa8b3cbbdfa775c311965846c523ae291327a5cc3e433479583922ff9527594" -dependencies = [ - "byteorder", - "crc32fast", - "fs_extra", - "log", - "lsm-tree", - "path-absolutize", - "std-semaphore", - "tempfile", -] - [[package]] name = "flate2" version = "1.0.30" @@ -1112,12 +1102,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - [[package]] name = "fsevent-sys" version = "4.1.0" @@ -1205,7 +1189,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.66", ] [[package]] @@ -1226,7 +1210,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ - "futures-channel", "futures-core", "futures-io", "futures-macro", @@ -1259,9 +1242,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -1270,40 +1253,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "guardian" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6817154789d2e9bb2af0486500e774af579d0e6539247044f06d803b141448b5" - -[[package]] -name = "h2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "hashbrown" @@ -1326,9 +1278,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash 0.8.11", "allocator-api2", @@ -1340,7 +1292,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -1433,9 +1385,9 @@ dependencies = [ [[package]] name = "http-range-header" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ce4ef31cda248bbdb6e6820603b82dfcd9e833db65a43e997a0ccec777d11fe" +checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a" [[package]] name = "httparse" @@ -1457,14 +1409,13 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", "http", "http-body", "httparse", @@ -1477,9 +1428,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" dependencies = [ "bytes", "futures-util", @@ -1487,7 +1438,6 @@ dependencies = [ "http-body", "hyper", "pin-project-lite", - "socket2", "tokio", ] @@ -1514,6 +1464,12 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.5.0" @@ -1526,23 +1482,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", -] - -[[package]] -name = "inherent" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.61", + "hashbrown 0.14.5", ] [[package]] @@ -1575,6 +1520,21 @@ dependencies = [ "libc", ] +[[package]] +name = "ipnetwork" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e" +dependencies = [ + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.10.5" @@ -1595,9 +1555,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" @@ -1648,9 +1608,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libm" @@ -1671,12 +1631,12 @@ dependencies = [ [[package]] name = "lightningcss" -version = "1.0.0-alpha.55" +version = "1.0.0-alpha.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd5bed3814fb631bfc1e24c2be6f7e86a9837c660909acab79a38374dcb8798" +checksum = "10bc10261f46b8df263b80e7779d1748b1880488cd951fbb9e096430cead10e6" dependencies = [ "ahash 0.8.11", - "bitflags 2.4.2", + "bitflags 2.5.0", "const-str", "cssparser", "cssparser-color", @@ -1696,15 +1656,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1717,38 +1677,6 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" -[[package]] -name = "lsm-tree" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "792f0f9d75b518035f7247774580ba60ee211d381237946e1a40609433f5573f" -dependencies = [ - "byteorder", - "chrono", - "crc32fast", - "crossbeam-skiplist", - "double-ended-peekable", - "fs_extra", - "guardian", - "log", - "lz4_flex", - "path-absolutize", - "quick_cache", - "rand 0.8.5", - "serde", - "serde_json", - "tempfile", -] - -[[package]] -name = "lz4_flex" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" -dependencies = [ - "twox-hash", -] - [[package]] name = "matchers" version = "0.1.0" @@ -1782,9 +1710,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "memo-map" @@ -1792,6 +1720,27 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "374c335b2df19e62d4cb323103473cbc6510980253119180de862d89184f6a83" +[[package]] +name = "migrations_internals" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd01039851e82f8799046eabbb354056283fb265c8ec0996af940f4e85a380ff" +dependencies = [ + "serde", + "toml", +] + +[[package]] +name = "migrations_macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb161cc72176cb37aa47f1fc520d3ef02263d67d661f44f05d05a079e1237fd" +dependencies = [ + "migrations_internals", + "proc-macro2", + "quote", +] + [[package]] name = "mime" version = "0.3.17" @@ -1851,9 +1800,9 @@ dependencies = [ [[package]] name = "minijinja" -version = "1.0.14" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe5b00f90b3542f74bb9aaaccd2627920c16367787de103883461365580e5481" +checksum = "55e877d961d4f96ce13615862322df7c0b6d169d40cab71a7ef3f9b9e594451e" dependencies = [ "memo-map", "self_cell", @@ -1864,9 +1813,9 @@ dependencies = [ [[package]] name = "minijinja-autoreload" -version = "1.0.14" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e801e49837411d30c0cb82234d9eac577c9edf12401783aac4a89c4af7a6a2" +checksum = "5d734de43ac09c38de7a53b552dff044a01d6c374831efa489cdc456f72907bc" dependencies = [ "minijinja", "notify", @@ -1880,9 +1829,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] @@ -1899,31 +1848,23 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "model_derive" -version = "0.1.0" -dependencies = [ - "quote", - "syn 2.0.61", -] - [[package]] name = "moka" -version = "0.12.5" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1911e88d5831f748a4097a43862d129e3c6fca831eecac9b8db6d01d93c9de2" +checksum = "9e0d88686dc561d743b40de8269b26eaf0dc58781bde087b0984646602021d08" dependencies = [ "async-lock", "async-trait", "crossbeam-channel", "crossbeam-epoch", "crossbeam-utils", + "event-listener 5.3.1", "futures-util", "once_cell", "parking_lot", "quanta", "rustc_version", - "skeptic", "smallvec", "tagptr", "thiserror", @@ -1970,11 +1911,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -2013,9 +1953,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -2024,9 +1964,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -2044,9 +1984,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" dependencies = [ "memchr", ] @@ -2057,39 +1997,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "ordered-float" -version = "3.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" -dependencies = [ - "num-traits", -] - -[[package]] -name = "ouroboros" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2ba07320d39dfea882faa70554b4bd342a5f273ed59ba7c1c6b4c840492c954" -dependencies = [ - "aliasable", - "ouroboros_macro", - "static_assertions", -] - -[[package]] -name = "ouroboros_macro" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" -dependencies = [ - "heck 0.4.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.61", -] - [[package]] name = "outref" version = "0.1.0" @@ -2110,11 +2017,11 @@ checksum = "92a516a35619e87f5c17e7a5dd0e0313aa01aecbd39b3c650b22a4500d74f6e0" [[package]] name = "parcel_selectors" -version = "0.26.4" +version = "0.26.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d74befe2d076330d9a58bf9ca2da424568724ab278adf15fb5718253133887" +checksum = "ce9c47a67c66fee4a5a42756f9784d92941bd0ab2b653539a9e90521a44b66f0" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "cssparser", "fxhash", "log", @@ -2139,10 +2046,16 @@ dependencies = [ ] [[package]] -name = "parking_lot" -version = "0.12.1" +name = "parking" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2150,15 +2063,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.1", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -2187,27 +2100,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "path-absolutize" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4af381fe79fa195b4909485d99f73a80792331df0625188e707854f0b3383f5" -dependencies = [ - "path-dedot", -] - -[[package]] -name = "path-dedot" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ba0ad7e047712414213ff67533e6dd477af0a4e1d14fb52343e53d30ea9397" -dependencies = [ - "once_cell", -] +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pathdiff" @@ -2289,7 +2184,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.66", ] [[package]] @@ -2327,14 +2222,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.66", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2353,17 +2248,17 @@ dependencies = [ "axum-htmx", "axum-login", "bincode 1.3.3", + "chrono", "clap", + "diesel", + "diesel_migrations", "dotenvy", "env_logger", - "fjall", "free-icons", "minijinja", "minijinja-autoreload", - "model_derive", "rand 0.8.5", "redb", - "sea-orm", "serde", "sled", "thiserror", @@ -2422,44 +2317,11 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" -[[package]] -name = "proc-macro-crate" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" -dependencies = [ - "toml_edit", -] - -[[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.82" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" dependencies = [ "unicode-ident", ] @@ -2484,22 +2346,11 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "pulldown-cmark" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" -dependencies = [ - "bitflags 2.4.2", - "memchr", - "unicase", -] - [[package]] name = "quanta" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca0b7bac0b97248c40bb77288fc52029cf1459c0461ea1b05ee32ccf011de2c" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" dependencies = [ "crossbeam-utils", "libc", @@ -2510,16 +2361,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "quick_cache" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "347e1a588d1de074eeb3c00eadff93db4db65aeb62aee852b1efd0949fe65b6c" -dependencies = [ - "equivalent", - "hashbrown 0.14.3", -] - [[package]] name = "quote" version = "1.0.36" @@ -2529,6 +2370,17 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + [[package]] name = "radium" version = "0.7.0" @@ -2595,11 +2447,11 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "11.0.1" +version = "11.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d86a7c4638d42c44551f4791a20e687dbb4c3de1f33c43dd71e355cd429def1" +checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", ] [[package]] @@ -2650,15 +2502,24 @@ dependencies = [ ] [[package]] -name = "regex" -version = "1.10.3" +name = "redox_syscall" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" dependencies = [ - "aho-corasick 1.1.2", + "bitflags 2.5.0", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick 1.1.3", "memchr", "regex-automata 0.4.6", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -2676,9 +2537,9 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ - "aho-corasick 1.1.2", + "aho-corasick 1.1.3", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -2689,9 +2550,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "remove_dir_all" @@ -2711,21 +2572,6 @@ dependencies = [ "bytecheck", ] -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "spin 0.9.8", - "untrusted", - "windows-sys 0.52.0", -] - [[package]] name = "rkyv" version = "0.7.44" @@ -2757,9 +2603,9 @@ dependencies = [ [[package]] name = "rmp" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" dependencies = [ "byteorder", "num-traits", @@ -2768,9 +2614,9 @@ dependencies = [ [[package]] name = "rmp-serde" -version = "1.1.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" +checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" dependencies = [ "byteorder", "rmp", @@ -2797,27 +2643,11 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rust_decimal" -version = "1.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39449a79f45e8da28c57c341891b69a183044b29518bb8f86dbac9df60bb7df" -dependencies = [ - "arrayvec", - "borsh", - "bytes", - "num-traits", - "rand 0.8.5", - "rkyv", - "serde", - "serde_json", -] - [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -2836,58 +2666,28 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.21.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" -dependencies = [ - "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.7", -] - -[[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" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -2898,110 +2698,21 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scheduled-thread-pool" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" +dependencies = [ + "parking_lot", +] + [[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 = "sea-bae" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd3534a9978d0aa7edd2808dc1f8f31c4d0ecd31ddf71d997b3c98e9f3c9114" -dependencies = [ - "heck 0.4.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.61", -] - -[[package]] -name = "sea-orm" -version = "0.12.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8814e37dc25de54398ee62228323657520b7f29713b8e238649385dbe473ee0" -dependencies = [ - "async-stream", - "async-trait", - "bigdecimal", - "chrono", - "futures", - "log", - "ouroboros", - "rust_decimal", - "sea-orm-macros", - "sea-query", - "sea-query-binder", - "serde", - "serde_json", - "sqlx", - "strum", - "thiserror", - "time", - "tracing", - "url", - "uuid", -] - -[[package]] -name = "sea-orm-macros" -version = "0.12.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e115c6b078e013aa963cc2d38c196c2c40b05f03d0ac872fe06b6e0d5265603" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "sea-bae", - "syn 2.0.61", - "unicode-ident", -] - -[[package]] -name = "sea-query" -version = "0.30.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4166a1e072292d46dc91f31617c2a1cdaf55a8be4b5c9f4bf2ba248e3ac4999b" -dependencies = [ - "bigdecimal", - "chrono", - "derivative", - "inherent", - "ordered-float", - "rust_decimal", - "serde_json", - "time", - "uuid", -] - -[[package]] -name = "sea-query-binder" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36bbb68df92e820e4d5aeb17b4acd5cc8b5d18b2c36a4dd6f4626aabfa7ab1b9" -dependencies = [ - "bigdecimal", - "chrono", - "rust_decimal", - "sea-query", - "serde_json", - "sqlx", - "time", - "uuid", -] - [[package]] name = "seahash" version = "4.1.0" @@ -3010,37 +2721,34 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "self_cell" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" +checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" -dependencies = [ - "serde", -] +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.201" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.201" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.66", ] [[package]] @@ -3064,6 +2772,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3118,9 +2835,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -3156,21 +2873,6 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" -[[package]] -name = "skeptic" -version = "0.13.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8" -dependencies = [ - "bytecount", - "cargo_metadata", - "error-chain", - "glob", - "pulldown-cmark", - "tempfile", - "walkdir", -] - [[package]] name = "slab" version = "0.4.9" @@ -3209,15 +2911,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3280,14 +2982,12 @@ checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" dependencies = [ "ahash 0.8.11", "atoi", - "bigdecimal", "byteorder", "bytes", - "chrono", "crc", "crossbeam-queue", "either", - "event-listener", + "event-listener 2.5.3", "futures-channel", "futures-core", "futures-intrusive", @@ -3301,9 +3001,6 @@ dependencies = [ "once_cell", "paste", "percent-encoding", - "rust_decimal", - "rustls", - "rustls-pemfile", "serde", "serde_json", "sha2", @@ -3315,8 +3012,6 @@ dependencies = [ "tokio-stream", "tracing", "url", - "uuid", - "webpki-roots", ] [[package]] @@ -3366,11 +3061,9 @@ checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" dependencies = [ "atoi", "base64 0.21.7", - "bigdecimal", - "bitflags 2.4.2", + "bitflags 2.5.0", "byteorder", "bytes", - "chrono", "crc", "digest", "dotenvy", @@ -3391,7 +3084,6 @@ dependencies = [ "percent-encoding", "rand 0.8.5", "rsa", - "rust_decimal", "serde", "sha1", "sha2", @@ -3401,7 +3093,6 @@ dependencies = [ "thiserror", "time", "tracing", - "uuid", "whoami", ] @@ -3413,10 +3104,8 @@ checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" dependencies = [ "atoi", "base64 0.21.7", - "bigdecimal", - "bitflags 2.4.2", + "bitflags 2.5.0", "byteorder", - "chrono", "crc", "dotenvy", "etcetera", @@ -3432,10 +3121,8 @@ dependencies = [ "log", "md-5", "memchr", - "num-bigint", "once_cell", "rand 0.8.5", - "rust_decimal", "serde", "serde_json", "sha2", @@ -3445,7 +3132,6 @@ dependencies = [ "thiserror", "time", "tracing", - "uuid", "whoami", ] @@ -3456,7 +3142,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" dependencies = [ "atoi", - "chrono", "flume", "futures-channel", "futures-core", @@ -3472,7 +3157,6 @@ dependencies = [ "tracing", "url", "urlencoding", - "uuid", ] [[package]] @@ -3484,40 +3168,22 @@ dependencies = [ "serde", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "std-semaphore" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ae9eec00137a8eed469fb4148acd9fc6ac8c3f9b110f52cd34698c8b5bfa0e" - [[package]] name = "stringprep" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" dependencies = [ - "finl_unicode", "unicode-bidi", "unicode-normalization", + "unicode-properties", ] [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" - -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" @@ -3538,33 +3204,27 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.61" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.61", -] - [[package]] name = "sync_wrapper" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + [[package]] name = "tagptr" version = "0.2.0" @@ -3601,22 +3261,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.66", ] [[package]] @@ -3631,9 +3291,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -3652,9 +3312,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -3677,9 +3337,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", @@ -3696,20 +3356,20 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.66", ] [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", @@ -3718,31 +3378,47 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", +] + +[[package]] +name = "toml" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" -version = "0.21.1" +version = "0.22.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" dependencies = [ "indexmap", + "serde", + "serde_spanned", "toml_datetime", "winnow", ] @@ -3786,7 +3462,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "bytes", "futures-util", "http", @@ -3819,9 +3495,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tower-sessions" -version = "0.11.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b27326208b21807803c5f5aa1020d30ca0432b78cfe251b51a67a05e0baea102" +checksum = "c2d9b6f0c4938eed0eefd9cce19319b4bdad10e11ca9d8c3be373ce734bbfd63" dependencies = [ "async-trait", "http", @@ -3837,13 +3513,13 @@ dependencies = [ [[package]] name = "tower-sessions-core" -version = "0.11.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afd1c5040577134115d8cc758d7757da29e171f83102de3ed1b86e3a2405533f" +checksum = "38767064990c327ec1d92bba2576dce0944750e9c9ae021f12ebc72de77ac406" dependencies = [ "async-trait", "axum-core", - "base64 0.22.0", + "base64 0.22.1", "futures", "http", "parking_lot", @@ -3858,9 +3534,9 @@ dependencies = [ [[package]] name = "tower-sessions-memory-store" -version = "0.11.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ac75309918b8f6ba16d09865a2a64f81e01b05cf42d5e88e5d3c6cbf775486" +checksum = "a8b09bbe2c138a9b0ebf307dc6e6a4f7723c59545e0f4fe5e329a89868164ae3" dependencies = [ "async-trait", "time", @@ -3870,9 +3546,9 @@ dependencies = [ [[package]] name = "tower-sessions-moka-store" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c99aaf32e2558da682d2cf620e7ca8c5ca1486111f03db60c21c3a71e4c1a655" +checksum = "adb9ea7e2905bd7b19315d9035f8c6a911abc366f15207992c819425b0d1bfe1" dependencies = [ "async-trait", "moka", @@ -3882,9 +3558,9 @@ dependencies = [ [[package]] name = "tower-sessions-sqlx-store" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7ac8c2edae9edad541f4087865e811565d124c9048eda7004537832066ede6" +checksum = "9442116d8ec67af57e2213f5b4007b6bb55d74c19eae429cd6525b7527844807" dependencies = [ "async-trait", "rmp-serde", @@ -3914,7 +3590,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.66", ] [[package]] @@ -3958,19 +3634,9 @@ dependencies = [ [[package]] name = "triomphe" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" - -[[package]] -name = "twox-hash" -version = "1.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" -dependencies = [ - "cfg-if", - "static_assertions", -] +checksum = "1b2cb4fbb9995eeb36ac86fadf24031ccd58f99d6b4b2d7b911db70bddb80d90" [[package]] name = "typenum" @@ -4008,6 +3674,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-properties" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" + [[package]] name = "unicode-segmentation" version = "1.11.0" @@ -4020,12 +3692,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "url" version = "2.5.0" @@ -4140,7 +3806,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -4162,7 +3828,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4183,19 +3849,13 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "whoami" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" dependencies = [ - "redox_syscall", + "redox_syscall 0.4.1", "wasite", ] @@ -4217,11 +3877,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -4236,7 +3896,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -4263,7 +3923,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -4298,17 +3958,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -4325,9 +3986,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -4343,9 +4004,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -4361,9 +4022,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -4379,9 +4046,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -4397,9 +4064,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -4415,9 +4082,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -4433,15 +4100,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" -version = "0.5.40" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +checksum = "86c949fede1d13936a99f14fafd3e76fd642b556dd2ce96287fbe2e0151bfac6" dependencies = [ "memchr", ] @@ -4457,29 +4124,29 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn 2.0.66", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zstd" diff --git a/Cargo.toml b/Cargo.toml index 6308e34..b5b484e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,27 +12,27 @@ argon2 = { version = "0.5.3", features = ["rand", "std"] } async-trait = "0.1.78" axum = "0.7.4" axum-htmx = { version = "0.5.0", features = ["guards", "serde"] } -axum-login = "0.14.0" +axum-login = "0.15" bincode = "1.3.3" +chrono = "0.4.38" clap = { version = "4.5.3", features = ["derive", "env"] } +diesel = { version = "2.2.0", features = ["extras", "returning_clauses_for_sqlite_3_35", "sqlite"] } +diesel_migrations = { version = "2.2.0", features = ["sqlite"] } dotenvy = "0.15.7" env_logger = "0.11.3" -fjall = "0.6.5" free-icons = "0.7.0" minijinja = { version = "1.0.14", features = ["loader", "json", "builtins"] } minijinja-autoreload = "1.0.14" -model_derive = { path = "./model_derive" } rand = "0.8.5" redb = "2.1.0" -sea-orm = { version = "0.12.15", features = ["sqlx-sqlite", "macros", "runtime-tokio-rustls"] } serde = { version = "1.0.197", features = ["derive"] } sled = "=1.0.0-alpha.121" thiserror = "1.0.58" tokio = { version = "1.36.0", features = ["rt", "full"] } tower-http = { version = "0.5.2", features = ["fs", "trace"] } -tower-sessions = "0.11.1" -tower-sessions-moka-store = "0.11.0" -tower-sessions-sqlx-store = { version = "0.11.0", features = ["sqlite"] } +tower-sessions = "0.12" +tower-sessions-moka-store = "0.12" +tower-sessions-sqlx-store = { version = "0.12", features = ["sqlite"] } tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } uuid = { version = "1.8.0", features = ["v4", "fast-rng", "v7", "serde"] } diff --git a/README.md b/README.md index 8e90a88..3eefd11 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,15 @@ We use nightly, and installation and management using [rustup][rustup] is recommended. -### SeaORM +### DB (Diesel) -We use SeaORM for database interaction. You'll want the CLI, which you can -install with `cargo install sea-orm-cli`. +We use [Diesel](https://diesel.rs/) for database interaction. You'll want the +CLI, which you can install with the following command. This will install it for +your user on your system, including support for SQLite. + +```bash +cargo install diesel_cli --no-default-features -F sqlite-bundled +``` ### Tailwind diff --git a/_docs/decisions/0004-uuids-for-primary-keys.md b/_docs/decisions/0004-uuids-for-primary-keys.md new file mode 100644 index 0000000..36e1df2 --- /dev/null +++ b/_docs/decisions/0004-uuids-for-primary-keys.md @@ -0,0 +1,47 @@ +# 4. UUIDs for primary keys + +Date: 2024-05-31 + +## Status + +Proposed + + + +## Context + +We need primary keys in our database. + +I've used integers and UUIDs for this in different contexts. Ultimately, we have +to decide on which one to use. + + +## Decision + +We're going to use UUIDs for our primary keys. + +The primary motivation here is that it will give us the ability to generate IDs +before inserting records, and it lets us expose the IDs more easily. Instead of +either leaking information (count of users, etc.) or having a secondary mapping +for URLs, we can easily use the ID in a URL to map to a record for lookup. + + +## Consequences + +There are some drawbacks: + +- We lose some type safety, becasue SQLite only supports text/blob types and + it's been a blocker trying to implement custom sql types in Diesel, so this is + going to be done by converting to strings and operating on these IDs as + strings. +- They take up more space + +However, we get these benefits: + +- We can expose primary keys without leaking information. This makes it so we + do not need secondary IDs (and associated indexes) for looking up specific + records and putting them in URLs, where if we used integers we'd need that or + we would have to accept exposing the number of records we have. +- IDs are unique across tables, so they should give us the ability to find a + particular row even if we don't know the table. This also means we could link + events, like edit events, to any table via UUID. diff --git a/diesel.toml b/diesel.toml new file mode 100644 index 0000000..be78c73 --- /dev/null +++ b/diesel.toml @@ -0,0 +1,9 @@ +# For documentation on how to configure this file, +# see https://diesel.rs/guides/configuring-diesel-cli + +[print_schema] +file = "src/schema.rs" +custom_type_derives = ["diesel::query_builder::QueryId", "Clone"] + +[migrations_directory] +dir = "/home/nicole/Code/pique/migrations" diff --git a/migration/Cargo.lock b/migration/Cargo.lock deleted file mode 100644 index 257d4ac..0000000 --- a/migration/Cargo.lock +++ /dev/null @@ -1,2351 +0,0 @@ -# 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.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "getrandom", - "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 = "aliasable" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" - -[[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.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" - -[[package]] -name = "anstyle-parse" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - -[[package]] -name = "async-attributes" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - -[[package]] -name = "async-channel" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" -dependencies = [ - "concurrent-queue", - "event-listener 5.2.0", - "event-listener-strategy 0.5.0", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" -dependencies = [ - "async-lock 3.3.0", - "async-task", - "concurrent-queue", - "fastrand 2.0.1", - "futures-lite 2.2.0", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" -dependencies = [ - "async-channel 2.2.0", - "async-executor", - "async-io 2.3.2", - "async-lock 3.3.0", - "blocking", - "futures-lite 2.2.0", - "once_cell", - "tokio", -] - -[[package]] -name = "async-io" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" -dependencies = [ - "async-lock 2.8.0", - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-lite 1.13.0", - "log", - "parking", - "polling 2.8.0", - "rustix 0.37.27", - "slab", - "socket2 0.4.10", - "waker-fn", -] - -[[package]] -name = "async-io" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" -dependencies = [ - "async-lock 3.3.0", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite 2.2.0", - "parking", - "polling 3.5.0", - "rustix 0.38.31", - "slab", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener 2.5.3", -] - -[[package]] -name = "async-lock" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" -dependencies = [ - "event-listener 4.0.3", - "event-listener-strategy 0.4.0", - "pin-project-lite", -] - -[[package]] -name = "async-std" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" -dependencies = [ - "async-attributes", - "async-channel 1.9.0", - "async-global-executor", - "async-io 1.13.0", - "async-lock 2.8.0", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite 1.13.0", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-stream" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "async-task" -version = "4.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" - -[[package]] -name = "async-trait" -version = "0.1.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "atoi" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" -dependencies = [ - "num-traits", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[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.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" - -[[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 = "blocking" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" -dependencies = [ - "async-channel 2.2.0", - "async-lock 3.3.0", - "async-task", - "fastrand 2.0.1", - "futures-io", - "futures-lite 2.2.0", - "piper", - "tracing", -] - -[[package]] -name = "bumpalo" -version = "3.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" - -[[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 = "cc" -version = "1.0.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" - -[[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.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "windows-targets 0.52.4", -] - -[[package]] -name = "clap" -version = "4.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "clap_lex" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "concurrent-queue" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "cpufeatures" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" -dependencies = [ - "libc", -] - -[[package]] -name = "crc" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" - -[[package]] -name = "crossbeam-queue" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" - -[[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 = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[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 = "dotenvy" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" - -[[package]] -name = "either" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" -dependencies = [ - "serde", -] - -[[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.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "event-listener" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener" -version = "5.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5fb89194fa3cad959b833185b3063ba881dbfc7030680b314250779fb4cc91" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" -dependencies = [ - "event-listener 4.0.3", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" -dependencies = [ - "event-listener 5.2.0", - "pin-project-lite", -] - -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - -[[package]] -name = "flume" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" -dependencies = [ - "futures-core", - "futures-sink", - "spin", -] - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-intrusive" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" -dependencies = [ - "futures-core", - "lock_api", - "parking_lot", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] -name = "futures-lite" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" -dependencies = [ - "fastrand 2.0.1", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash", - "allocator-api2", -] - -[[package]] -name = "hashlink" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" -dependencies = [ - "hashbrown", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "iana-time-zone" -version = "0.1.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -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.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "2.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "inherent" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.153" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" - -[[package]] -name = "libsqlite3-sys" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - -[[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.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" -dependencies = [ - "value-bag", -] - -[[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 = "memchr" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" - -[[package]] -name = "migration" -version = "0.1.0" -dependencies = [ - "async-std", - "sea-orm-migration", -] - -[[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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -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 = "num-traits" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" -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", - "libc", -] - -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "ordered-float" -version = "3.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" -dependencies = [ - "num-traits", -] - -[[package]] -name = "ouroboros" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2ba07320d39dfea882faa70554b4bd342a5f273ed59ba7c1c6b4c840492c954" -dependencies = [ - "aliasable", - "ouroboros_macro", - "static_assertions", -] - -[[package]] -name = "ouroboros_macro" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" -dependencies = [ - "heck 0.4.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "parking" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" - -[[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", - "smallvec", - "windows-targets 0.48.5", -] - -[[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[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 = "piper" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" -dependencies = [ - "atomic-waker", - "fastrand 2.0.1", - "futures-io", -] - -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - -[[package]] -name = "polling" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "concurrent-queue", - "libc", - "log", - "pin-project-lite", - "windows-sys 0.48.0", -] - -[[package]] -name = "polling" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24f040dee2588b4963afb4e420540439d126f73fdacf4a9c486a96d840bac3c9" -dependencies = [ - "cfg-if", - "concurrent-queue", - "pin-project-lite", - "rustix 0.38.31", - "tracing", - "windows-sys 0.52.0", -] - -[[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.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[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 = "regex" -version = "1.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.6", - "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.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" -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 = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "spin", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustix" -version = "0.37.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustix" -version = "0.38.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" -dependencies = [ - "bitflags 2.4.2", - "errno", - "libc", - "linux-raw-sys 0.4.13", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.21.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" -dependencies = [ - "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", -] - -[[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 = "ryu" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" - -[[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 = "sea-bae" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd3534a9978d0aa7edd2808dc1f8f31c4d0ecd31ddf71d997b3c98e9f3c9114" -dependencies = [ - "heck 0.4.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "sea-orm" -version = "0.12.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8814e37dc25de54398ee62228323657520b7f29713b8e238649385dbe473ee0" -dependencies = [ - "async-stream", - "async-trait", - "futures", - "log", - "ouroboros", - "sea-orm-macros", - "sea-query", - "sea-query-binder", - "serde", - "sqlx", - "strum", - "thiserror", - "tracing", - "url", -] - -[[package]] -name = "sea-orm-cli" -version = "0.12.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "620bc560062ae251b1366bde43b3f1508445cab5c2c8cbdb397034638ab1b357" -dependencies = [ - "chrono", - "clap", - "dotenvy", - "glob", - "regex", - "sea-schema", - "tracing", - "tracing-subscriber", - "url", -] - -[[package]] -name = "sea-orm-macros" -version = "0.12.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e115c6b078e013aa963cc2d38c196c2c40b05f03d0ac872fe06b6e0d5265603" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "sea-bae", - "syn 2.0.52", - "unicode-ident", -] - -[[package]] -name = "sea-orm-migration" -version = "0.12.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8269bc6ff71afd6b78aa4333ac237a69eebd2cdb439036291e64fb4b8db23c" -dependencies = [ - "async-trait", - "clap", - "dotenvy", - "futures", - "sea-orm", - "sea-orm-cli", - "sea-schema", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "sea-query" -version = "0.30.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4166a1e072292d46dc91f31617c2a1cdaf55a8be4b5c9f4bf2ba248e3ac4999b" -dependencies = [ - "derivative", - "inherent", - "ordered-float", - "sea-query-derive", -] - -[[package]] -name = "sea-query-binder" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36bbb68df92e820e4d5aeb17b4acd5cc8b5d18b2c36a4dd6f4626aabfa7ab1b9" -dependencies = [ - "sea-query", - "sqlx", -] - -[[package]] -name = "sea-query-derive" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a82fcb49253abcb45cdcb2adf92956060ec0928635eb21b4f7a6d8f25ab0bc" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 2.0.52", - "thiserror", -] - -[[package]] -name = "sea-schema" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d148608012d25222442d1ebbfafd1228dbc5221baf4ec35596494e27a2394e" -dependencies = [ - "futures", - "sea-query", - "sea-schema-derive", -] - -[[package]] -name = "sea-schema-derive" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f686050f76bffc4f635cda8aea6df5548666b830b52387e8bc7de11056d11e" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "serde" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "serde_json" -version = "1.0.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[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 = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" - -[[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.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - -[[package]] -name = "sqlformat" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" -dependencies = [ - "itertools", - "nom", - "unicode_categories", -] - -[[package]] -name = "sqlx" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" -dependencies = [ - "sqlx-core", - "sqlx-macros", - "sqlx-sqlite", -] - -[[package]] -name = "sqlx-core" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" -dependencies = [ - "ahash", - "atoi", - "byteorder", - "bytes", - "crc", - "crossbeam-queue", - "either", - "event-listener 2.5.3", - "futures-channel", - "futures-core", - "futures-intrusive", - "futures-io", - "futures-util", - "hashlink", - "hex", - "indexmap", - "log", - "memchr", - "once_cell", - "paste", - "percent-encoding", - "rustls", - "rustls-pemfile", - "serde", - "sha2", - "smallvec", - "sqlformat", - "thiserror", - "tokio", - "tokio-stream", - "tracing", - "url", - "webpki-roots", -] - -[[package]] -name = "sqlx-macros" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" -dependencies = [ - "proc-macro2", - "quote", - "sqlx-core", - "sqlx-macros-core", - "syn 1.0.109", -] - -[[package]] -name = "sqlx-macros-core" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" -dependencies = [ - "dotenvy", - "either", - "heck 0.4.1", - "hex", - "once_cell", - "proc-macro2", - "quote", - "serde", - "serde_json", - "sha2", - "sqlx-core", - "sqlx-sqlite", - "syn 1.0.109", - "tempfile", - "tokio", - "url", -] - -[[package]] -name = "sqlx-sqlite" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" -dependencies = [ - "atoi", - "flume", - "futures-channel", - "futures-core", - "futures-executor", - "futures-intrusive", - "futures-util", - "libsqlite3-sys", - "log", - "percent-encoding", - "serde", - "sqlx-core", - "tracing", - "url", - "urlencoding", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strsim" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" - -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" - -[[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.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand 2.0.1", - "rustix 0.38.31", - "windows-sys 0.52.0", -] - -[[package]] -name = "thiserror" -version = "1.0.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[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.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "pin-project-lite", - "socket2 0.5.6", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-stream" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[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.52", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "once_cell", - "regex", - "sharded-slab", - "thread_local", - "tracing", - "tracing-core", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[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.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" - -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "urlencoding" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "value-bag" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec26a25bd6fca441cdd0f769fd7f891bae119f996de31f86a5eddccef54c1d" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "waker-fn" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" - -[[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.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.52", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "web-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - -[[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-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.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.4", -] - -[[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-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.4", -] - -[[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-targets" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" -dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", -] - -[[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_gnullvm" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" - -[[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_gnu" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" - -[[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_gnu" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" - -[[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_gnullvm" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" - -[[package]] -name = "zerocopy" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] diff --git a/migration/Cargo.toml b/migration/Cargo.toml deleted file mode 100644 index 3fe7d1f..0000000 --- a/migration/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "migration" -version = "0.1.0" -edition = "2021" -publish = false - -[lib] -name = "migration" -path = "src/lib.rs" - -[dependencies] -async-std = { version = "1", features = ["attributes", "tokio1"] } - -[dependencies.sea-orm-migration] -version = "0.12.0" -features = [ - "runtime-tokio-rustls", - "sqlx-sqlite", -] diff --git a/migration/README.md b/migration/README.md deleted file mode 100644 index 3b438d8..0000000 --- a/migration/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# Running Migrator CLI - -- Generate a new migration file - ```sh - cargo run -- generate MIGRATION_NAME - ``` -- Apply all pending migrations - ```sh - cargo run - ``` - ```sh - cargo run -- up - ``` -- Apply first 10 pending migrations - ```sh - cargo run -- up -n 10 - ``` -- Rollback last applied migrations - ```sh - cargo run -- down - ``` -- Rollback last 10 applied migrations - ```sh - cargo run -- down -n 10 - ``` -- Drop all tables from the database, then reapply all migrations - ```sh - cargo run -- fresh - ``` -- Rollback all applied migrations, then reapply all migrations - ```sh - cargo run -- refresh - ``` -- Rollback all applied migrations - ```sh - cargo run -- reset - ``` -- Check the status of all migrations - ```sh - cargo run -- status - ``` diff --git a/migration/src/lib.rs b/migration/src/lib.rs deleted file mode 100644 index c4ad367..0000000 --- a/migration/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub use sea_orm_migration::prelude::*; - -mod m20240316_155147_create_users_table; - -pub struct Migrator; - -#[async_trait::async_trait] -impl MigratorTrait for Migrator { - fn migrations() -> Vec> { - vec![ - Box::new(m20240316_155147_create_users_table::Migration), - ] - } -} diff --git a/migration/src/m20240316_155147_create_users_table.rs b/migration/src/m20240316_155147_create_users_table.rs deleted file mode 100644 index 7f3f7a2..0000000 --- a/migration/src/m20240316_155147_create_users_table.rs +++ /dev/null @@ -1,69 +0,0 @@ -use sea_orm_migration::prelude::*; - -#[derive(DeriveMigrationName)] -pub struct Migration; - -#[async_trait::async_trait] -impl MigrationTrait for Migration { - async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .create_table( - Table::create() - .table(User::Table) - .if_not_exists() - .col( - ColumnDef::new(User::Id) - .integer() - .not_null() - .auto_increment() - .primary_key(), - ) - .col(ColumnDef::new(User::FullName).string_len(100).not_null()) - .col( - ColumnDef::new(User::Email) - .string_len(100) - .unique() - .not_null(), - ) - .col( - ColumnDef::new(User::Username) - .string_len(32) - .unique() - .not_null(), - ) - .col(ColumnDef::new(User::PasswordHash).string().not_null()) - .col( - ColumnDef::new(User::Created) - .date_time() - .default(Expr::current_timestamp()) - .not_null(), - ) - .col( - ColumnDef::new(User::Updated) - .date_time() - .default(Expr::current_timestamp()) - .not_null(), - ) - .to_owned(), - ) - .await - } - - async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .drop_table(Table::drop().table(User::Table).to_owned()) - .await - } -} - -#[derive(DeriveIden)] -enum User { - Table, - Id, - FullName, - Email, - Username, - PasswordHash, - Created, - Updated, -} diff --git a/migration/src/main.rs b/migration/src/main.rs deleted file mode 100644 index c6b6e48..0000000 --- a/migration/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use sea_orm_migration::prelude::*; - -#[async_std::main] -async fn main() { - cli::run_cli(migration::Migrator).await; -} diff --git a/migrations/.keep b/migrations/.keep new file mode 100644 index 0000000..e69de29 diff --git a/migrations/2024-05-31-175324_users/down.sql b/migrations/2024-05-31-175324_users/down.sql new file mode 100644 index 0000000..c99ddcd --- /dev/null +++ b/migrations/2024-05-31-175324_users/down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS users; diff --git a/migrations/2024-05-31-175324_users/up.sql b/migrations/2024-05-31-175324_users/up.sql new file mode 100644 index 0000000..09a52b3 --- /dev/null +++ b/migrations/2024-05-31-175324_users/up.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS users ( + id UUID_TEXT PRIMARY KEY NOT NULL UNIQUE, + username TEXT NOT NULL UNIQUE CHECK (LENGTH(username) <= 32), + password_hash TEXT NOT NULL, + email TEXT NOT NULL UNIQUE CHECK (LENGTH(email) <= 100), + name TEXT NOT NULL CHECK (LENGTH(name) <= 100) +); diff --git a/migrations/2024-05-31-203133_projects_and_documents/down.sql b/migrations/2024-05-31-203133_projects_and_documents/down.sql new file mode 100644 index 0000000..5f271f1 --- /dev/null +++ b/migrations/2024-05-31-203133_projects_and_documents/down.sql @@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS projects; +DROP TABLE IF EXISTS documents; diff --git a/migrations/2024-05-31-203133_projects_and_documents/up.sql b/migrations/2024-05-31-203133_projects_and_documents/up.sql new file mode 100644 index 0000000..9de4432 --- /dev/null +++ b/migrations/2024-05-31-203133_projects_and_documents/up.sql @@ -0,0 +1,18 @@ +CREATE TABLE IF NOT EXISTS projects ( + id UUID_TEXT PRIMARY KEY NOT NULL UNIQUE, + creator_id UUID_TEXT NOT NULL, + + name TEXT NOT NULL, + description TEXT NOT NULL, + + key TEXT NOT NULL +); + +CREATE TABLE IF NOT EXISTS documents ( + id UUID_TEXT PRIMARY KEY NOT NULL UNIQUE, + creator_id UUID_TEXT NOT NULL, + project_id UUID_TEXT NOT NULL, + + title TEXT NOT NULL, + content TEXT NOT NULL +); diff --git a/migrations/2024-05-31-204416_permissions/down.sql b/migrations/2024-05-31-204416_permissions/down.sql new file mode 100644 index 0000000..a7f4c83 --- /dev/null +++ b/migrations/2024-05-31-204416_permissions/down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS project_memberships; diff --git a/migrations/2024-05-31-204416_permissions/up.sql b/migrations/2024-05-31-204416_permissions/up.sql new file mode 100644 index 0000000..fd9f817 --- /dev/null +++ b/migrations/2024-05-31-204416_permissions/up.sql @@ -0,0 +1,8 @@ + +CREATE TABLE IF NOT EXISTS project_memberships( + id INTEGER PRIMARY KEY NOT NULL UNIQUE, + + user_id UUID_TEXT NOT NULL, + project_id UUID_TEXT NOT NULL, + role TEXT NOT NULL +); diff --git a/model_derive/Cargo.lock b/model_derive/Cargo.lock deleted file mode 100644 index 93b7aef..0000000 --- a/model_derive/Cargo.lock +++ /dev/null @@ -1,46 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "model_derive" -version = "0.1.0" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "proc-macro2" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "syn" -version = "2.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/model_derive/Cargo.toml b/model_derive/Cargo.toml deleted file mode 100644 index 3489eb2..0000000 --- a/model_derive/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "model_derive" -version = "0.1.0" -edition = "2021" - -[lib] -proc-macro = true - -[dependencies] -quote = "1.0.36" -syn = { version = "2.0.61", features = ["full", "derive"] } diff --git a/model_derive/src/lib.rs b/model_derive/src/lib.rs deleted file mode 100644 index 996a23d..0000000 --- a/model_derive/src/lib.rs +++ /dev/null @@ -1,48 +0,0 @@ -use proc_macro::TokenStream; -use quote::{format_ident, quote}; -use syn::{parse_macro_input, DeriveInput, LitInt}; - -#[proc_macro_derive(Model, attributes(model_version))] -pub fn model(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - - let name = input.ident; - let attrs = input.attrs; - - let model_version = attrs.iter().find_map(|attr| { - if attr.path().is_ident("model_version") { - attr.parse_args::().ok().and_then(|lit| { - Some(lit.base10_parse::().unwrap()) - }) - } else { - None - } - }).unwrap_or(0); - - let lower_name = name.to_string().to_lowercase(); - let lower_name_ident = format_ident!("{}", lower_name); - - - let expanded = quote! { - impl Model for #name { - type Id = uuid::Uuid; - - fn id(&self) -> Self::Id { - self.id - } - - fn key(id: Self::Id) -> Vec { - let mut key = vec![]; - key.extend_from_slice(format!("{}:{}:", #lower_name, #model_version).as_bytes()); - key.extend_from_slice(&id.into_bytes()); - key - } - - fn partition(kv_handle: &KvHandle) -> &PartitionHandle { - &kv_handle.#lower_name_ident - } - } - }; - - TokenStream::from(expanded) -} diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..b786903 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,5 @@ +imports_granularity = "Module" +group_imports = "StdExternalCrate" +wrap_comments = true +use_small_heuristics = "Max" +edition = "2021" diff --git a/src/bin/admin.rs b/src/bin/admin.rs index 6ee6a40..307ad5a 100644 --- a/src/bin/admin.rs +++ b/src/bin/admin.rs @@ -1,24 +1,17 @@ use anyhow::Result; use clap::{Parser, Subcommand}; -use pique::{ - db::{NewUser, UserQuery}, - prelude::*, -}; -use rand::distributions::Alphanumeric; -use rand::{distributions::DistString, thread_rng}; -use sea_orm::Database; +use pique::db::establish_connection; +use pique::models::users::{self, NewUser}; +use rand::distributions::{Alphanumeric, DistString}; +use rand::thread_rng; #[tokio::main] pub async fn main() -> Result<()> { dotenvy::dotenv()?; + let db_url = dotenvy::var("DATABASE_URL")?; match AdminCli::parse().command { - AdminCommand::CreateUser { - full_name, - email, - username, - password, - } => { + AdminCommand::CreateUser { name, email, username, password } => { let password = match password { Some(p) => p, None => { @@ -29,15 +22,9 @@ pub async fn main() -> Result<()> { password } }; - handle_create_user(NewUser { - full_name, - email, - username, - password, - }) - .await? + handle_create_user(&db_url, NewUser::new(name, username, email, password)).await? } - AdminCommand::ListUsers => handle_list_users().await?, + AdminCommand::ListUsers => handle_list_users(&db_url).await?, }; Ok(()) @@ -51,40 +38,29 @@ struct AdminCli { #[derive(Subcommand, Debug)] pub enum AdminCommand { - CreateUser { - full_name: String, - email: String, - username: String, - password: Option, - }, + CreateUser { name: String, email: String, username: String, password: Option }, ListUsers, } -async fn handle_create_user(new_user: NewUser) -> Result<()> { - let db = connect_to_db().await?; +async fn handle_create_user(db_url: &str, new_user: NewUser) -> Result<()> { + let mut db = establish_connection(db_url); - let user = UserQuery(&db).insert(new_user).await?; - println!("User created successfully with id = {}", user.id.unwrap()); + let user = users::q::create(&mut db, new_user)?; + println!("User created successfully with id = {}", user.id); Ok(()) } -async fn handle_list_users() -> Result<()> { - let db = connect_to_db().await?; +async fn handle_list_users(db_url: &str) -> Result<()> { + let mut db = establish_connection(db_url); - let users = UserQuery(&db).all().await?; + let users = users::q::all(&mut db)?; println!("Found {} users.", users.len()); for user in users { - println!(" > {}: {} ({})", user.id, user.username, user.full_name); + println!(" > {}: {} ({})", user.id, user.username, user.name); } Ok(()) } - -async fn connect_to_db() -> Result { - let db_url = dotenvy::var("DATABASE_URL")?; - let db = Database::connect(db_url).await?; - Ok(db) -} diff --git a/src/bin/pique.rs b/src/bin/pique.rs index 7c3bd81..b965a13 100644 --- a/src/bin/pique.rs +++ b/src/bin/pique.rs @@ -1,5 +1,4 @@ use anyhow::Result; - use pique::server; #[tokio::main] diff --git a/src/context.rs b/src/context.rs deleted file mode 100644 index 0df1143..0000000 --- a/src/context.rs +++ /dev/null @@ -1,42 +0,0 @@ -use std::sync::Arc; - -use minijinja_autoreload::AutoReloader; - -use crate::{handler::internal_server_error, kv::KvHandle, prelude::*}; - -#[derive(Clone)] -pub struct Context { - pub db: DatabaseConnection, - // TODO: add a design doc explaining why this not relational - pub kv_handles: KvHandle, - template_loader: Arc, -} - -impl Context { - pub fn new(db: DatabaseConnection, kv_handles: KvHandle, template_loader: AutoReloader) -> Context { - Context { - db, - kv_handles, - template_loader: Arc::new(template_loader), - } - } - - pub fn render(&self, path: &str, data: T) -> anyhow::Result { - // TODO: more graceful handling of the potential errors here; this should not use anyhow - let env = self.template_loader.acquire_env().unwrap(); - let template = env.get_template(path)?; - let rendered = template.render(data)?; - Ok(rendered) - } - - pub fn render_resp(&self, path: &str, data: T) -> Response { - let rendered = self.render(path, data); - match rendered { - Ok(rendered) => Html(rendered).into_response(), - Err(err) => { - error!(?err, "error while rendering template"); - internal_server_error() - } - } - } -} diff --git a/src/db.rs b/src/db.rs index 31ab176..cc8dce6 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,96 +1,43 @@ -use sea_orm::Set; -use thiserror::Error; +use diesel::prelude::*; +use diesel::r2d2::{ConnectionManager, Pool}; +use diesel::SqliteConnection; +use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; -use crate::{entity::user, password, prelude::*}; +pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!(); -pub struct NewUser { - pub full_name: String, - pub email: String, - pub username: String, - pub password: String, +/// Establishes a connection to the database using the given URL. +/// +/// # Arguments +/// * `url` - The database URL to connect to. +/// +/// # Panics +/// Panics if the database URL is not set or if the connection cannot be +/// established. +pub fn establish_connection(url: &str) -> SqliteConnection { + SqliteConnection::establish(url).unwrap_or_else(|_| panic!("Error connecting to {}", url)) } -impl NewUser { - pub fn validate(&self) -> Result<(), Vec> { - let mut validation_errors = vec![]; - - if self.full_name.len() > 100 { - validation_errors.push(ValidationError::on("full_name", "too long (max=100)")); - } - - if self.email.len() > 100 { - validation_errors.push(ValidationError::on("email", "too long (max=100)")); - } - - if self.username.len() > 100 { - validation_errors.push(ValidationError::on("username", "too long (max=32)")); - } - - if validation_errors.is_empty() { - Ok(()) - } else { - Err(validation_errors) - } - } - - pub fn hash_password(&self) -> String { - password::hash(&self.password) - } +/// Builds a connection pool for the given URL. +/// +/// # Arguments +/// * `url` - The database URL to connect to. +/// +/// # Panics +/// Panics if the connection pool cannot be created. +pub fn build_connection_pool(url: &str) -> Pool> { + let manager = ConnectionManager::::new(url); + Pool::builder().build(manager).expect("Failed to create connection pool.") } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct ValidationError { - pub field: String, - pub message: String, -} - -impl ValidationError { - pub fn on(field: &str, message: &str) -> ValidationError { - ValidationError { - field: field.to_owned(), - message: message.to_owned(), - } - } -} - -#[derive(Debug, Error)] -pub enum DbError { - #[error("internal database error")] - Internal(#[from] sea_orm::DbErr), -} - -pub struct UserQuery<'a>(pub &'a DatabaseConnection); - -impl UserQuery<'_> { - pub async fn insert(&self, new_user: NewUser) -> Result { - let password_hash = new_user.hash_password(); - let user = user::ActiveModel { - full_name: Set(new_user.full_name), - email: Set(new_user.email), - username: Set(new_user.username), - password_hash: Set(password_hash), - ..Default::default() - } - .save(self.0) - .await?; - Ok(user) - } - - pub async fn all(&self) -> Result, DbError> { - let users = User::find().all(self.0).await?; - Ok(users) - } - - pub async fn by_id(&self, id: i32) -> Result, DbError> { - let user = User::find_by_id(id).one(self.0).await?; - Ok(user) - } - - pub async fn by_username(&self, username: &str) -> Result, DbError> { - let user = User::find() - .filter(user::Column::Username.eq(username)) - .one(self.0) - .await?; - Ok(user) - } +/// Runs any pending migrations. +/// +/// This function should be called before the application starts. +/// +/// # Arguments +/// * `conn` - The database connection to run the migrations on. +/// +/// # Panics +/// Panics if there is an error running the migrations. +pub fn migrate(conn: &mut SqliteConnection) { + conn.run_pending_migrations(MIGRATIONS).unwrap(); } diff --git a/src/entity/mod.rs b/src/entity/mod.rs deleted file mode 100644 index 412b614..0000000 --- a/src/entity/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.15 - -pub mod prelude; - -pub mod user; diff --git a/src/entity/prelude.rs b/src/entity/prelude.rs deleted file mode 100644 index d60b621..0000000 --- a/src/entity/prelude.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.15 - -pub use super::user::Entity as User; diff --git a/src/entity/user.rs b/src/entity/user.rs deleted file mode 100644 index f2f2b52..0000000 --- a/src/entity/user.rs +++ /dev/null @@ -1,22 +0,0 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.15 - -use sea_orm::entity::prelude::*; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] -#[sea_orm(table_name = "user")] -pub struct Model { - #[sea_orm(primary_key)] - pub id: i32, - pub full_name: String, - pub email: String, - pub username: String, - pub password_hash: String, - pub created: String, - pub updated: String, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation {} - -impl ActiveModelBehavior for ActiveModel {} diff --git a/src/handler.rs b/src/handler.rs index 566411a..6d220f5 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -4,13 +4,13 @@ pub mod login; pub mod projects; use axum::http::StatusCode; -use axum::response::Response; -pub use login::login_page; -pub use login::login_submit; +pub use login::{login_page, login_submit}; +use tracing::error; -pub fn internal_server_error() -> Response { - Response::builder() - .status(StatusCode::INTERNAL_SERVER_ERROR) - .body("Internal Server Error".into()) - .unwrap() +pub fn internal_error(err: E) -> (StatusCode, String) +where + E: std::error::Error, +{ + error!(?err, "internal error"); + (StatusCode::INTERNAL_SERVER_ERROR, "Internal Server Error".into()) } diff --git a/src/handler/documents.rs b/src/handler/documents.rs index 52c7992..449219f 100644 --- a/src/handler/documents.rs +++ b/src/handler/documents.rs @@ -1,46 +1,65 @@ -use axum::{extract::Path, response::Redirect, Form}; +use axum::extract::Path; +use axum::http::StatusCode; +use axum::response::Redirect; +use axum::Form; use axum_login::AuthSession; -use crate::{handler::internal_server_error, models::{Document, ModelPermission, ModelType, Permission}, prelude::*}; +use crate::handler::internal_error; +use crate::models::documents::{self, NewDocument}; +use crate::models::users::User; +use crate::permissions::q::Permission; +use crate::permissions::{self}; +use crate::prelude::*; pub async fn documents_page( - State(ctx): State, - auth_session: AuthSession, -) -> Response { + State(provider): State, + auth_session: AuthSession, +) -> Result { if let Some(user) = auth_session.user { - render_documents_page(ctx, user).await + render_documents_page(provider, user).await } else { - Redirect::to("/login").into_response() + Ok(Redirect::to("/login").into_response()) } } -async fn render_documents_page(ctx: Context, user: crate::entity::user::Model) -> Response { - let documents = ModelPermission::user_documents(&ctx.kv_handles, user.id).unwrap_or_default(); +async fn render_documents_page( + provider: Provider, + user: User, +) -> Result { + let mut db = provider.db_pool.get().map_err(internal_error)?; + let documents = + permissions::q::accessible_documents(&mut db, &user.id).map_err(internal_error)?; + let projects = + permissions::q::accessible_projects(&mut db, &user.id).map_err(internal_error)?; let values = context! { user => user, documents => documents, + projects => projects, }; - ctx.render_resp("documents/list_documents.html", values) + provider.render_resp("documents/list_documents.html", values) } pub async fn create_document_page( - State(ctx): State, - auth_session: AuthSession, -) -> Response { + State(provider): State, + auth_session: AuthSession, +) -> Result { let user = match auth_session.user { Some(user) => user, - None => return Redirect::to("/login").into_response(), + None => return Ok(Redirect::to("/login").into_response()), }; - let projects = ModelPermission::user_projects(&ctx.kv_handles, user.id).unwrap_or_default(); + let mut db = provider.db_pool.get().map_err(internal_error)?; + + let projects = + permissions::q::accessible_projects(&mut db, &user.id).map_err(internal_error)?; let values = context! { user => user, projects => projects, }; - ctx.render_resp("documents/create_document.html", values) + provider.render_resp("documents/create_document.html", values) } #[derive(Debug, Deserialize)] @@ -50,80 +69,72 @@ pub struct CreateDocumentSubmission { } pub async fn create_document_submit( - State(ctx): State, - auth_session: AuthSession, + State(provider): State, + auth_session: AuthSession, form: Form, -) -> Response { +) -> Result { let user = match auth_session.user { Some(user) => user, - None => return Redirect::to("/login").into_response(), + None => return Ok(Redirect::to("/login").into_response()), }; + let mut db = provider.db_pool.get().map_err(internal_error)?; - let project = match ModelPermission::user_project(&ctx.kv_handles, user.id, form.project_id) { - Ok(Some(project)) => project, - Ok(None) => return Redirect::to("/documents/create").into_response(), - Err(err) => { - error!(?err, "failed to access kv store"); - return Redirect::to("/documents/create").into_response(); - } - }; + let project_allowed = permissions::q::check_user_project( + &mut db, + &user.id, + &form.project_id.to_string(), + Permission::Write, + ) + .map_err(internal_error)?; - let document = Document { - id: Uuid::now_v7(), - project_id: project.id, - title: form.title.to_owned(), - content: "".to_owned(), - }; - - if let Err(err) = document.save(&ctx.kv_handles) { - error!(?err, "failed to save document"); - return internal_server_error(); + if !project_allowed { + return Err((StatusCode::FORBIDDEN, "permission denied".to_owned())); } + + let new_document = NewDocument::new( + &user.id, + &form.project_id.to_string(), + form.title.to_owned(), + "".to_owned(), + ); + + let document = documents::q::create(&mut db, new_document).map_err(internal_error)?; info!(?document, "document created"); - let permission = ModelPermission { - user_id: user.id, - model_type: ModelType::Document, - role: Permission::Admin, - model_id: document.id, - }; - - if let Err(err) = permission.add(&ctx.kv_handles) { - error!(?err, "failed to save new project permission"); - return internal_server_error(); - } - - - - Redirect::to("/documents").into_response() + Ok(Redirect::to("/documents").into_response()) } pub async fn edit_document_page( - State(ctx): State, - auth_session: AuthSession, + State(provider): State, + auth_session: AuthSession, Path((id,)): Path<(Uuid,)>, -) -> Response { +) -> Result { let user = match auth_session.user { Some(user) => user, - None => return Redirect::to("/login").into_response(), + None => return Ok(Redirect::to("/login").into_response()), }; - let document = match ModelPermission::user_document(&ctx.kv_handles, user.id, id) { - Ok(Some(document)) => document, - Ok(None) => return Redirect::to("/documents").into_response(), - Err(err) => { - error!(?err, "failed to load document"); - return internal_server_error(); - } - }; + let mut db = provider.db_pool.get().map_err(internal_error)?; + + let document_allowed = + permissions::q::check_user_document(&mut db, &user.id, &id.to_string(), Permission::Write) + .map_err(internal_error)?; + + if !document_allowed { + return Err((StatusCode::FORBIDDEN, "permission denied".to_owned())); + } + + let document = documents::q::by_id(&mut db, &id.to_string()).map_err(internal_error)?; + let projects = + permissions::q::accessible_projects(&mut db, &user.id).map_err(internal_error)?; - dbg!(&document); let values = context! { user => user, document => document, + projects => projects, }; - ctx.render_resp("documents/edit_document.html", values) + provider.render_resp("documents/edit_document.html", values) } #[derive(Debug, Deserialize)] @@ -132,39 +143,38 @@ pub struct EditDocumentSubmission { pub content: String, } - pub async fn edit_document_submit( - State(ctx): State, - auth_session: AuthSession, + State(provider): State, + auth_session: AuthSession, Path((document_id,)): Path<(Uuid,)>, form: Form, -) -> Response { +) -> Result { let user = match auth_session.user { Some(user) => user, - None => return Redirect::to("/login").into_response(), + None => return Ok(Redirect::to("/login").into_response()), }; - let mut document = match ModelPermission::user_document(&ctx.kv_handles, user.id, document_id) { - Ok(Some(document)) => document, - Ok(None) => return Redirect::to("/documents").into_response(), - Err(err) => { - error!(?err, "failed to load document"); - return internal_server_error(); - } - }; + let mut db = provider.db_pool.get().map_err(internal_error)?; - let new_document = Document { - id: document.id, - project_id: document.id, - title: form.title.to_owned(), - content: form.content.to_owned(), - }; + let document_allowed = permissions::q::check_user_document( + &mut db, + &user.id, + &document_id.to_string(), + Permission::Write, + ) + .map_err(internal_error)?; - if let Err(err) = new_document.save(&ctx.kv_handles) { - error!(?err, "failed to save document"); - return internal_server_error(); + if !document_allowed { + return Err((StatusCode::FORBIDDEN, "permission denied".to_owned())); } - info!(?new_document, "document updated"); - Redirect::to("/documents").into_response() + documents::q::update( + &mut db, + &document_id.to_string(), + form.title.to_owned(), + form.content.to_owned(), + ) + .map_err(internal_error)?; + + Ok(Redirect::to("/documents").into_response()) } diff --git a/src/handler/home.rs b/src/handler/home.rs index 8077eb5..cdf7dcc 100644 --- a/src/handler/home.rs +++ b/src/handler/home.rs @@ -1,19 +1,27 @@ +use axum::http::StatusCode; use axum::response::Redirect; use axum_login::AuthSession; -use crate::{models::{ModelPermission, Project}, prelude::*}; +use crate::models::projects::Project; +use crate::permissions; +use crate::prelude::*; -pub async fn home_page(State(ctx): State, auth_session: AuthSession) -> Response { +pub async fn home_page( + State(provider): State, + auth_session: AuthSession, +) -> Result { if let Some(user) = auth_session.user { - let projects: Vec = ModelPermission::user_projects(&ctx.kv_handles, user.id).unwrap_or_default(); + let mut db = provider.db_pool.get().unwrap(); + let projects: Vec = + permissions::q::accessible_projects(&mut db, &user.id).unwrap(); let values = context! { user => user, projects => projects, }; - ctx.render_resp("home.html", values) + provider.render_resp("home.html", values) } else { - Redirect::to("/login").into_response() + Ok(Redirect::to("/login").into_response()) } } diff --git a/src/handler/login.rs b/src/handler/login.rs index 61472c3..4dbfb25 100644 --- a/src/handler/login.rs +++ b/src/handler/login.rs @@ -1,7 +1,11 @@ -use axum::{response::Redirect, Form}; +use axum::http::StatusCode; +use axum::response::Redirect; +use axum::Form; use axum_login::AuthSession; -use crate::{handler::internal_server_error, prelude::*, session::Credentials}; +use super::internal_error; +use crate::prelude::*; +use crate::session::Credentials; pub struct LoginTemplate { pub username: String, @@ -10,23 +14,23 @@ pub struct LoginTemplate { } pub async fn login_page( - State(ctx): State, - auth_session: AuthSession, -) -> Response { - if auth_session.user.is_some() { - return Redirect::to("/").into_response(); + State(provider): State, + auth_session: AuthSession, +) -> Result { + if let Some(_user) = auth_session.user { + Ok(Redirect::to("/").into_response()) + } else { + render_login_page(&provider, "", "", None) } - - render_login_page(&ctx, "", "", None) } fn render_login_page( - ctx: &Context, + provider: &Provider, username: &str, password: &str, error: Option<&'static str>, -) -> Response { - ctx.render_resp( +) -> Result { + provider.render_resp( "login.html", context! { username => username, @@ -39,83 +43,22 @@ fn render_login_page( const LOGIN_ERROR_MSG: &str = "Invalid username or password"; pub async fn login_submit( - State(ctx): State, - mut auth_session: AuthSession, + State(provider): State, + mut auth_session: AuthSession, Form(creds): Form, -) -> Response { - match auth_session.authenticate(creds).await { - Ok(Some(user)) => { - if let Err(err) = auth_session.login(&user).await { - error!(?err, "error while logging in user"); - return internal_server_error(); - } - - Redirect::to("/").into_response() - } - Ok(None) => render_login_page(&ctx, "", "", Some(LOGIN_ERROR_MSG)), - Err(err) => { - error!(?err, "error while authenticating user"); - internal_server_error() - } +) -> Result { + if let Some(user) = auth_session.authenticate(creds).await.map_err(internal_error)? { + let _ = auth_session.login(&user).await.map_err(internal_error)?; + Ok(Redirect::to("/").into_response()) + } else { + render_login_page(&provider, "", "", Some(LOGIN_ERROR_MSG)) } } -pub async fn logout(mut auth_session: AuthSession) -> Response { +pub async fn logout(mut auth_session: AuthSession) -> Response { if let Err(err) = auth_session.logout().await { error!(?err, "error while logging out user"); } Redirect::to("/login").into_response() } - -//const INVALID_LOGIN_MESSAGE: &str = "Invalid username/password, please try again."; -// -//pub async fn login_submission( -// request: HttpRequest, -// context: web::Data, -// form: web::Form, -//) -> impl Responder { -// let mut conn = match context.pool.get() { -// Ok(conn) => conn, -// Err(_) => return internal_server_error(), -// }; -// -// let user = match fetch_user_by_username(&mut conn, &form.username) { -// Ok(Some(user)) => user, -// Ok(None) => { -// return LoginTemplate { -// username: form.username.clone(), -// password: String::new(), -// error: Some(INVALID_LOGIN_MESSAGE.into()), -// } -// .to_response() -// } -// Err(_) => return internal_server_error(), -// }; -// -// if !user.check_password(&form.password) { -// return LoginTemplate { -// username: form.username.clone(), -// password: String::new(), -// error: Some(INVALID_LOGIN_MESSAGE.into()), -// } -// .to_response(); -// } -// -// if Identity::login(&request.extensions(), user.id.to_string()).is_err() { -// return internal_server_error(); -// } -// -// return HttpResponse::Found() -// .append_header(("Location", "/")) -// .finish(); -//} -// -//#[get("/logout")] -//pub async fn logout(user: Option) -> impl Responder { -// if let Some(user) = user { -// user.logout(); -// } -// -// redirect_to_login() -//} diff --git a/src/handler/projects.rs b/src/handler/projects.rs index 14baa30..a652305 100644 --- a/src/handler/projects.rs +++ b/src/handler/projects.rs @@ -1,92 +1,87 @@ -use axum::{response::Redirect, Form}; +use axum::http::StatusCode; +use axum::response::Redirect; +use axum::Form; use axum_login::AuthSession; -use crate::{ - handler::internal_server_error, - models::{ModelPermission, ModelType, Permission, Project}, - prelude::*, -}; +use super::internal_error; +use crate::models::project_memberships::{self, ProjectRole}; +use crate::models::projects::{self, NewProject}; +use crate::models::users::User; +use crate::permissions; +use crate::prelude::*; pub async fn projects_page( - State(ctx): State, - auth_session: AuthSession, -) -> Response { + State(provider): State, + auth_session: AuthSession, +) -> Result { if let Some(user) = auth_session.user { - render_projects_page(ctx, user).await + render_projects_page(provider, user).await } else { - Redirect::to("/login").into_response() + Ok(Redirect::to("/login").into_response()) } } -async fn render_projects_page(ctx: Context, user: crate::entity::user::Model) -> Response { - let projects = ModelPermission::user_projects(&ctx.kv_handles, user.id).unwrap_or_default(); +async fn render_projects_page( + provider: Provider, + user: User, +) -> Result { + let mut db = provider.db_pool.get().map_err(internal_error)?; + let projects = permissions::q::accessible_projects(&mut db, &user.id).unwrap_or_default(); let values = context! { user => user, projects => projects, }; - ctx.render_resp("projects/list_projects.html", values) + provider.render_resp("projects/list_projects.html", values) } pub async fn create_project_page( - State(ctx): State, - auth_session: AuthSession, -) -> Response { + State(provider): State, + auth_session: AuthSession, +) -> Result { let user = match auth_session.user { Some(user) => user, - None => return Redirect::to("/login").into_response(), + None => return Ok(Redirect::to("/login").into_response()), }; let values = context! { user => user, }; - ctx.render_resp("projects/create_project.html", values) + provider.render_resp("projects/create_project.html", values) } #[derive(Debug, Deserialize)] pub struct CreateProjectSubmission { pub name: String, - pub key: String, pub description: String, + pub key: String, } pub async fn create_project_submit( - State(ctx): State, - auth_session: AuthSession, + State(provider): State, + auth_session: AuthSession, form: Form, -) -> Response { +) -> Result { + let mut db = provider.db_pool.get().map_err(internal_error)?; + let user = match auth_session.user { Some(user) => user, - None => return Redirect::to("/login").into_response(), + None => return Ok(Redirect::to("/login").into_response()), }; - let project = Project { - id: Uuid::now_v7(), - owner_id: user.id, - - name: form.name.clone(), - key: form.key.clone(), - description: form.description.clone(), - }; + let new_project = NewProject::new( + user.id.clone(), + form.name.clone(), + form.description.clone(), + form.key.clone(), + ); // TODO: validation - if let Err(err) = project.save(&ctx.kv_handles) { - error!(?err, "failed to save new project"); - return internal_server_error(); - } + let project = projects::q::create(&mut db, new_project).map_err(internal_error)?; - let permission = ModelPermission { - user_id: user.id, - model_type: ModelType::Project, - role: Permission::Admin, - model_id: project.id, - }; + let _ = project_memberships::q::create(&mut db, &user.id, &project.id, ProjectRole::Admin) + .map_err(internal_error)?; - if let Err(err) = permission.add(&ctx.kv_handles) { - error!(?err, "failed to save new project permission"); - return internal_server_error(); - } - - Redirect::to("/projects").into_response() + Ok(Redirect::to("/projects").into_response()) } diff --git a/src/kv.rs b/src/kv.rs deleted file mode 100644 index 0d68fa0..0000000 --- a/src/kv.rs +++ /dev/null @@ -1,42 +0,0 @@ -use std::path::Path; - -use anyhow::Result; -use fjall::{Config, Keyspace, PartitionCreateOptions, PartitionHandle}; - -/// Contains the handles needed to reference key-value data. -/// -/// This contains both the Keyspace and multiple PartitionHandle. -/// The Keyspace allows operational control and reporting at the top level, -/// while each PartitionHandle controls reading, writing, and removing from a -/// particular partition of the data. -/// -/// All fields are public, because this is meant to be used internally as a -/// wrapper to pass everything around, instead of passing each handle around by -/// itself. -#[derive(Clone)] -pub struct KvHandle { - pub keyspace: Keyspace, - - pub project: PartitionHandle, - pub document: PartitionHandle, - pub permissions: PartitionHandle, -} - -impl KvHandle { - pub fn open>(p: P) -> Result { - // TODO: those should probably be configurable, or like, not just hard coded. - let config = Config::new(p).flush_workers(4).compaction_workers(4); - let keyspace = Keyspace::open(config)?; - - let project = keyspace.open_partition("project", PartitionCreateOptions::default())?; - let document = keyspace.open_partition("document", PartitionCreateOptions::default())?; - let permissions = keyspace.open_partition("permissions", PartitionCreateOptions::default())?; - - Ok(KvHandle { - keyspace, - project, - document, - permissions, - }) - } -} diff --git a/src/lib.rs b/src/lib.rs index 4f3e2ba..ca70937 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,14 @@ pub mod config; -pub mod context; pub mod db; -pub mod entity; pub mod handler; pub mod logging; pub mod models; pub mod password; +pub mod permissions; pub mod prelude; -pub mod serialize; +pub mod provider; +pub mod schema; pub mod server; pub mod session; pub mod templates; -pub mod kv; +pub mod validation; diff --git a/src/logging.rs b/src/logging.rs index 5e03789..a961a3d 100644 --- a/src/logging.rs +++ b/src/logging.rs @@ -1,7 +1,5 @@ use tracing_subscriber::EnvFilter; pub fn setup_logging() { - tracing_subscriber::fmt() - .with_env_filter(EnvFilter::from_default_env()) - .init(); + tracing_subscriber::fmt().with_env_filter(EnvFilter::from_default_env()).init(); } diff --git a/src/models.rs b/src/models.rs index 60d2893..a707258 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,190 +1,18 @@ -use core::fmt::{self, Display}; -use crate::prelude::*; +use thiserror::Error; -use anyhow::Result; -use fjall::PartitionHandle; -use model_derive::Model; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; +pub mod documents; +pub mod project_memberships; +pub mod projects; +pub mod users; -use crate::kv::KvHandle; +#[derive(Error, Debug)] +pub enum DbError { + #[error("Diesel error: {0}")] + DieselError(#[from] diesel::result::Error), -pub trait Model: Sized + Serialize + for<'a> Deserialize<'a> { - type Id; + #[error("Diesel connection error: {0}")] + ConnectionError(#[from] diesel::ConnectionError), - fn id(&self) -> Self::Id; - fn key(id: Self::Id) -> Vec; - fn partition(kv_handle: &KvHandle) -> &PartitionHandle; - - fn save(&self, kv_handle: &KvHandle) -> Result<()> { - let key = Self::key(self.id()); - let value = bincode::serialize(self)?; - let partition = Self::partition(kv_handle); - - partition.insert(key, value)?; - - Ok(()) - } - - fn load(kv_handle: &KvHandle, id: Self::Id) -> Result> { - let key = Self::key(id); - let partition = Self::partition(kv_handle); - - match partition.get(key.as_slice())? { - Some(bytes) => { - let bytes = bytes.to_vec(); - let value: Self = bincode::deserialize(&bytes)?; - Ok(Some(value)) - } - None => Ok(None), - } - } -} - -#[derive(Debug, Model, Serialize, Deserialize, PartialEq)] -#[model_version(0)] -pub struct Project { - pub id: Uuid, - pub owner_id: i32, - - pub name: String, - pub description: String, - - // The key is the short code, like BUG, which is used to refer to a project - // quickly and to display it more compactly. This must be unique across the - // projects a user owns. - pub key: String, -} - -#[derive(Debug, Model, Serialize, Deserialize, PartialEq)] -#[model_version(0)] -pub struct Document { - pub id: Uuid, - pub project_id: Uuid, - - pub title: String, - pub content: String, -} - -#[derive(Debug, Serialize, Deserialize, PartialEq)] -#[repr(u8)] -pub enum ModelType { - Project = 0, - Document = 1, -} - -impl Display for ModelType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ModelType::Project => write!(f, "project"), - ModelType::Document => write!(f, "document"), - } - } -} - -#[derive(Debug, Serialize, Deserialize, PartialEq)] -#[repr(u8)] -pub enum Permission { - Admin = 0, - Read = 1, -} - -impl Display for Permission { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Permission::Admin => write!(f, "admin"), - Permission::Read => write!(f, "read"), - } - } -} - -#[derive(Debug, Serialize, Deserialize, PartialEq)] -pub struct ModelPermission { - pub user_id: i32, - pub model_type: ModelType, - pub role: Permission, - pub model_id: Uuid, -} - -impl ModelPermission { - pub fn add(&self, kv_handle: &KvHandle) -> Result<()> { - let key = format!( - "{}:{}:{}:{}", - self.user_id, self.model_type, self.role, self.model_id - ); - let value = bincode::serialize(self)?; - - kv_handle.permissions.insert(key, value)?; - - Ok(()) - } - - pub fn user_projects(kv_handle: &KvHandle, user_id: i32) -> Result> { - let prefix = format!("{}:{}:", user_id, ModelType::Project); - - let mut ids = vec![]; - for row in kv_handle.permissions.prefix(prefix).into_iter() { - let (_key, value) = row?; - let permission: ModelPermission = bincode::deserialize(&value)?; - ids.push(permission.model_id); - } - - let projects: Vec = ids - .into_iter() - .filter_map(|id| { - let res = Project::load(kv_handle, id); - res.ok().flatten() - }) - .collect(); - - Ok(projects) - } - - pub fn user_project(kv_handle: &KvHandle, user_id: i32, project_id: Uuid) -> Result> { - let key = format!("{}:{}:{}:{}", user_id, ModelType::Project, Permission::Admin, project_id); - let value = kv_handle.permissions.get(key)?; - - match value { - Some(value) => { - let permission: ModelPermission = bincode::deserialize(&value)?; - let project = Project::load(kv_handle, permission.model_id)?; - Ok(project) - } - None => Ok(None), - } - } - - pub fn user_documents(kv_handle: &KvHandle, user_id: i32) -> Result> { - let prefix = format!("{}:{}:", user_id, ModelType::Document); - - let mut ids = vec![]; - for row in kv_handle.permissions.prefix(prefix).into_iter() { - let (_key, value) = row?; - let permission: ModelPermission = bincode::deserialize(&value)?; - ids.push(permission.model_id); - } - dbg!(&ids); - - let documents: Vec = ids - .into_iter() - .filter_map(|id| Document::load(kv_handle, id).ok().flatten()) - .collect(); - dbg!(&documents); - - Ok(documents) - } - - pub fn user_document(kv_handle: &KvHandle, user_id: i32, document_id: Uuid) -> Result> { - let key = format!("{}:{}:{}:{}", user_id, ModelType::Document, Permission::Admin, document_id); - let value = kv_handle.permissions.get(key)?; - - match value { - Some(value) => { - let permission: ModelPermission = bincode::deserialize(&value)?; - let document = Document::load(kv_handle, permission.model_id)?; - Ok(document) - } - None => Ok(None), - } - } + #[error("Connection pool error: {0}")] + PoolError(#[from] diesel::r2d2::PoolError), } diff --git a/src/models/documents.rs b/src/models/documents.rs new file mode 100644 index 0000000..0067275 --- /dev/null +++ b/src/models/documents.rs @@ -0,0 +1,79 @@ +use diesel::prelude::*; +use serde::Serialize; +use uuid::Uuid; + +use super::DbError; +use crate::schema::documents::dsl; + +#[derive(Queryable, Selectable, Debug, Clone, Serialize)] +#[diesel(table_name = crate::schema::documents)] +#[diesel(check_for_backend(diesel::sqlite::Sqlite))] +pub struct Document { + pub id: String, + pub creator_id: String, + pub project_id: String, + pub title: String, + pub content: String, +} + +#[derive(Insertable)] +#[diesel(table_name = crate::schema::documents)] +pub struct NewDocument { + pub id: String, + pub creator_id: String, + pub project_id: String, + pub title: String, + pub content: String, +} + +impl NewDocument { + pub fn new(creator_id: &str, project_id: &str, title: String, content: String) -> Self { + Self { + id: Uuid::now_v7().to_string(), + creator_id: creator_id.to_string(), + project_id: project_id.to_string(), + title, + content, + } + } +} + +pub mod q { + use super::*; + + pub fn create( + conn: &mut SqliteConnection, + new_document: NewDocument, + ) -> Result { + diesel::insert_into(dsl::documents).values(&new_document).execute(conn)?; + + let document = dsl::documents.filter(dsl::id.eq(&new_document.id)).first(conn)?; + + Ok(document) + } + + pub fn update( + conn: &mut SqliteConnection, + document_id: &str, + title: String, + content: String, + ) -> Result { + diesel::update(dsl::documents.filter(dsl::id.eq(document_id))) + .set((dsl::title.eq(title), dsl::content.eq(content))) + .execute(conn)?; + + let document = dsl::documents.filter(dsl::id.eq(document_id)).first(conn)?; + + Ok(document) + } + + pub fn by_id( + conn: &mut SqliteConnection, + document_id: &str, + ) -> Result, DbError> { + let document = + dsl::documents.filter(dsl::id.eq(document_id)).first::(conn).optional()?; + + Ok(document) + } +} diff --git a/src/models/project_memberships.rs b/src/models/project_memberships.rs new file mode 100644 index 0000000..dc7388f --- /dev/null +++ b/src/models/project_memberships.rs @@ -0,0 +1,92 @@ +use std::fmt; + +use diesel::expression::AsExpression; +use diesel::prelude::*; +use diesel::sql_types::Text; + +#[derive(AsExpression, Debug, Clone)] +#[diesel(sql_type = Text)] +pub enum ProjectRole { + Member, + Admin, +} + +impl fmt::Display for ProjectRole { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + ProjectRole::Member => write!(f, "member"), + ProjectRole::Admin => write!(f, "admin"), + } + } +} + +impl From for ProjectRole +where + S: AsRef, + String: std::convert::From, +{ + fn from(status: S) -> Self { + match status.as_ref() { + "member" => ProjectRole::Member, + "admin" => ProjectRole::Admin, + _ => ProjectRole::Member, + } + } +} + +impl From for String { + fn from(role: ProjectRole) -> Self { + match role { + ProjectRole::Member => "member".to_string(), + ProjectRole::Admin => "admin".to_string(), + } + } +} + +#[derive(Queryable, Selectable, Debug, Clone)] +#[diesel(table_name = crate::schema::project_memberships)] +#[diesel(check_for_backend(diesel::sqlite::Sqlite))] +pub struct ProjectMembership { + pub id: i32, + pub user_id: String, + pub project_id: String, + + #[diesel(serialize_as = String, deserialize_as = String)] + pub role: ProjectRole, +} + +#[derive(Insertable)] +#[diesel(table_name = crate::schema::project_memberships)] +pub struct NewProjectMembership { + pub user_id: String, + pub project_id: String, + + #[diesel(serialize_as = String, deserialize_as = String)] + pub role: ProjectRole, +} + +pub mod q { + use diesel::SqliteConnection; + + use super::*; + + pub fn create( + conn: &mut SqliteConnection, + user_id: &str, + project_id: &str, + role: ProjectRole, + ) -> Result { + use crate::schema::project_memberships::dsl as pm; + + let new_membership = NewProjectMembership { + user_id: user_id.to_string(), + project_id: project_id.to_string(), + role, + }; + + let membership = + diesel::insert_into(pm::project_memberships).values(new_membership).get_result(conn)?; + + Ok(membership) + } +} diff --git a/src/models/projects.rs b/src/models/projects.rs new file mode 100644 index 0000000..0db87c2 --- /dev/null +++ b/src/models/projects.rs @@ -0,0 +1,54 @@ +use diesel::prelude::*; +use serde::Serialize; +use uuid::Uuid; + +use super::DbError; +use crate::schema::projects::dsl; + +#[derive(Queryable, Selectable, Debug, Clone, Serialize)] +#[diesel(table_name = crate::schema::projects)] +#[diesel(check_for_backend(diesel::sqlite::Sqlite))] +pub struct Project { + pub id: String, + pub creator_id: String, + pub name: String, + pub description: String, + pub key: String, +} + +#[derive(Insertable)] +#[diesel(table_name = crate::schema::projects)] +pub struct NewProject { + pub id: String, + pub creator_id: String, + pub name: String, + pub description: String, + pub key: String, +} + +impl NewProject { + pub fn new(creator_id: String, name: String, description: String, key: String) -> Self { + Self { id: Uuid::now_v7().to_string(), creator_id, name, description, key } + } +} + +pub mod q { + use super::*; + + pub fn for_user(conn: &mut SqliteConnection, user_id: String) -> Result, DbError> { + let projects = + dsl::projects.filter(dsl::creator_id.eq(user_id.to_string())).load::(conn)?; + Ok(projects) + } + + pub fn create( + conn: &mut SqliteConnection, + new_project: NewProject, + ) -> Result { + use crate::schema::projects::dsl as p; + + let project = diesel::insert_into(p::projects).values(new_project).get_result(conn)?; + + Ok(project) + } +} diff --git a/src/models/users.rs b/src/models/users.rs new file mode 100644 index 0000000..eeb1aee --- /dev/null +++ b/src/models/users.rs @@ -0,0 +1,85 @@ +use diesel::prelude::*; +use serde::Serialize; +use uuid::Uuid; + +use super::DbError; +use crate::password; +use crate::schema::users::dsl; +use crate::validation::ValidationError; + +#[derive(Queryable, Selectable, Debug, Clone, Serialize)] +#[diesel(table_name = crate::schema::users)] +#[diesel(check_for_backend(diesel::sqlite::Sqlite))] +pub struct User { + pub id: String, + pub username: String, + pub password_hash: String, + pub email: String, + pub name: String, +} + +#[derive(Insertable)] +#[diesel(table_name = crate::schema::users)] +pub struct NewUser { + pub id: String, + pub name: String, + pub username: String, + pub email: String, + pub password_hash: String, +} + +impl NewUser { + pub fn new(name: String, username: String, email: String, password: String) -> Self { + let password_hash = password::hash(&password); + Self { id: Uuid::now_v7().to_string(), name, username, email, password_hash } + } + + pub fn validate(&self) -> Result<(), Vec> { + let mut validation_errors = vec![]; + + if self.name.len() > 100 { + validation_errors.push(ValidationError::on("name", "too long (max=100)")); + } + + if self.email.len() > 100 { + validation_errors.push(ValidationError::on("email", "too long (max=100)")); + } + + if self.username.len() > 32 { + validation_errors.push(ValidationError::on("username", "too long (max=32)")); + } + + if validation_errors.is_empty() { + Ok(()) + } else { + Err(validation_errors) + } + } +} + +pub mod q { + use super::*; + + pub fn all(conn: &mut SqliteConnection) -> Result, DbError> { + let user_list = dsl::users.load::(conn)?; + Ok(user_list) + } + + pub fn by_id(conn: &mut SqliteConnection, id: &str) -> Result { + let user = dsl::users.filter(dsl::id.eq(id)).first::(conn)?; + Ok(user) + } + + pub fn by_username(conn: &mut SqliteConnection, username: &str) -> Result { + let user = dsl::users.filter(dsl::username.eq(username)).first::(conn)?; + Ok(user) + } + + pub fn create(conn: &mut SqliteConnection, new_user: NewUser) -> Result { + let _ = diesel::insert_into(dsl::users).values(&new_user).execute(conn)?; + + let new_user = dsl::users.filter(dsl::id.eq(&new_user.id)).first::(conn)?; + + Ok(new_user) + } +} diff --git a/src/password.rs b/src/password.rs index e2bebc7..68dc061 100644 --- a/src/password.rs +++ b/src/password.rs @@ -9,18 +9,14 @@ pub fn verify(hash: &str, password: &str) -> bool { Err(_) => return false, // TODO: log an error }; - Argon2::default() - .verify_password(password.as_bytes(), &parsed_hash) - .is_ok() + Argon2::default().verify_password(password.as_bytes(), &parsed_hash).is_ok() } /// Hashes the given password. pub fn hash(password: &str) -> String { let salt = SaltString::generate(&mut OsRng); - let hash = Argon2::default() - .hash_password(password.as_bytes(), &salt) - .unwrap(); + let hash = Argon2::default().hash_password(password.as_bytes(), &salt).unwrap(); hash.to_string() } diff --git a/src/permissions.rs b/src/permissions.rs new file mode 100644 index 0000000..a7c64d2 --- /dev/null +++ b/src/permissions.rs @@ -0,0 +1,128 @@ +pub mod q { + use diesel::prelude::*; + use diesel::SqliteConnection; + + use crate::models::documents::Document; + use crate::models::project_memberships::ProjectRole; + use crate::models::projects::Project; + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + pub enum Permission { + Read, + Write, + Admin, + } + + pub fn check_user_project( + db: &mut SqliteConnection, + user_id: &str, + project_id: &str, + permission: Permission, + ) -> Result { + use crate::schema::project_memberships::dsl as pm; + + if permission == Permission::Admin { + let is_admin = pm::project_memberships + .filter(pm::user_id.eq(user_id)) + .filter(pm::project_id.eq(project_id)) + .filter(pm::role.eq(ProjectRole::Admin.to_string())) + .count() + .get_result::(db)?; + + Ok(is_admin > 0) + } else { + let is_member = pm::project_memberships + .filter(pm::user_id.eq(user_id)) + .filter(pm::project_id.eq(project_id)) + .count() + .get_result::(db)?; + + Ok(is_member > 0) + } + } + + pub fn check_user_document( + db: &mut SqliteConnection, + user_id: &str, + document_id: &str, + permission: Permission, + ) -> Result { + use crate::schema::documents::dsl as d; + + let document = + d::documents.filter(d::id.eq(document_id)).first::(db).optional()?; + + match document { + Some(doc) => check_user_project(db, user_id, &doc.project_id, permission), + None => Ok(false), + } + } + + /// Users have permissions directly on projects which they are members of. + pub fn accessible_project_ids( + db: &mut SqliteConnection, + user_id: &str, + ) -> Result, diesel::result::Error> { + use crate::schema::project_memberships::dsl as pm; + + let project_ids = pm::project_memberships + .filter(pm::user_id.eq(user_id)) + .select(pm::project_id) + .load::(db)?; + + Ok(project_ids) + } + + /// Users have permissions directly on projects which they are members of. + pub fn accessible_projects( + db: &mut SqliteConnection, + user_id: &str, + ) -> Result, diesel::result::Error> { + use crate::schema::projects::dsl as p; + + let project_ids = accessible_project_ids(db, user_id)?; + let projects = p::projects.filter(p::id.eq_any(project_ids)).load::(db)?; + + Ok(projects) + } + + /// Users can access documents which they are members of or which are in + /// projects they're members of. + pub fn accessible_document_ids( + db: &mut SqliteConnection, + user_id: &str, + ) -> Result, diesel::result::Error> { + use crate::schema::documents::dsl as d; + use crate::schema::project_memberships::dsl as pm; + + let project_ids = accessible_project_ids(db, user_id)?; + + let direct_documents = pm::project_memberships + .filter(pm::user_id.eq(user_id)) + .select(pm::project_id) + .load::(db)?; + + let project_documents = d::documents + .filter(d::project_id.eq_any(project_ids)) + .select(d::id) + .load::(db)?; + + let document_ids = direct_documents.into_iter().chain(project_documents).collect(); + + Ok(document_ids) + } + + /// Users can access documents which they are members of or which are in + /// projects they're members of. + pub fn accessible_documents( + db: &mut SqliteConnection, + user_id: &str, + ) -> Result, diesel::result::Error> { + use crate::schema::documents::dsl as d; + + let document_ids = accessible_document_ids(db, user_id)?; + let documents = d::documents.filter(d::id.eq_any(document_ids)).load::(db)?; + + Ok(documents) + } +} diff --git a/src/prelude.rs b/src/prelude.rs index e24c43a..d693cb9 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -1,10 +1,8 @@ -pub use crate::context::Context; -pub use crate::entity::prelude::*; -pub use crate::models::Model; pub use axum::extract::State; pub use axum::response::{Html, IntoResponse, Response}; pub use minijinja::context; -pub use sea_orm::prelude::*; -pub use sea_orm::{ActiveModelTrait, DatabaseConnection}; pub use serde::{Deserialize, Serialize}; pub use tracing::{debug, error, info, warn}; +pub use uuid::Uuid; + +pub use crate::provider::Provider; diff --git a/src/provider.rs b/src/provider.rs new file mode 100644 index 0000000..8016fbd --- /dev/null +++ b/src/provider.rs @@ -0,0 +1,55 @@ +use std::sync::Arc; + +use axum::http::StatusCode; +use diesel::r2d2::{ConnectionManager, Pool}; +use diesel::SqliteConnection; +use minijinja_autoreload::AutoReloader; +use thiserror::Error; + +use crate::handler::internal_error; +use crate::prelude::*; + +pub type ConnectionPool = Pool>; +pub type PooledConnection = diesel::r2d2::PooledConnection>; + +#[derive(Clone)] +pub struct Provider { + pub db_pool: ConnectionPool, + template_loader: Arc, +} + +#[derive(Error, Debug)] +pub enum ProviderError { + #[error("Error while using the connection pool: {0}")] + R2D2Error(#[from] diesel::r2d2::PoolError), + + #[error("Error while rendering template: {0}")] + TemplateError(#[from] minijinja::Error), +} + +impl Provider { + pub fn new(db: ConnectionPool, template_loader: AutoReloader) -> Provider { + Provider { db_pool: db, template_loader: Arc::new(template_loader) } + } + + pub fn db_conn(&self) -> Result { + let conn = self.db_pool.get()?; + Ok(conn) + } + + pub fn render(&self, path: &str, data: T) -> Result { + let env = self.template_loader.acquire_env().unwrap(); + let template = env.get_template(path)?; + let rendered = template.render(data)?; + Ok(rendered) + } + + pub fn render_resp( + &self, + path: &str, + data: T, + ) -> Result { + let rendered = self.render(path, data).map_err(internal_error)?; + Ok(Html(rendered).into_response()) + } +} diff --git a/src/schema.rs b/src/schema.rs new file mode 100644 index 0000000..9df8c05 --- /dev/null +++ b/src/schema.rs @@ -0,0 +1,42 @@ +// @generated automatically by Diesel CLI. + +diesel::table! { + documents (id) { + id -> Text, + creator_id -> Text, + project_id -> Text, + title -> Text, + content -> Text, + } +} + +diesel::table! { + project_memberships (id) { + id -> Integer, + user_id -> Text, + project_id -> Text, + role -> Text, + } +} + +diesel::table! { + projects (id) { + id -> Text, + creator_id -> Text, + name -> Text, + description -> Text, + key -> Text, + } +} + +diesel::table! { + users (id) { + id -> Text, + username -> Text, + password_hash -> Text, + email -> Text, + name -> Text, + } +} + +diesel::allow_tables_to_appear_in_same_query!(documents, project_memberships, projects, users,); diff --git a/src/serialize.rs b/src/serialize.rs deleted file mode 100644 index 7d790f8..0000000 --- a/src/serialize.rs +++ /dev/null @@ -1,16 +0,0 @@ -use bincode::{DefaultOptions, Options}; -use serde::{Deserialize, Serialize}; - -fn bincode_options() -> impl Options { - DefaultOptions::new().with_big_endian() -} - -pub fn serialize(value: &T) -> Result, bincode::Error> { - let options = bincode_options(); - options.serialize(value) -} - -pub fn deserialize<'a, T: Deserialize<'a>>(bytes: &'a [u8]) -> Result { - let options = bincode_options(); - options.deserialize(bytes) -} diff --git a/src/server.rs b/src/server.rs index e6e96b8..873ecbd 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,16 +1,33 @@ use std::str::FromStr; use anyhow::Result; -use axum::{routing::{get, post}, Router}; +use axum::routing::{get, post}; +use axum::Router; use axum_login::AuthManagerLayerBuilder; use clap::Parser; -use sea_orm::Database; -use tower_http::{services::ServeDir, trace::{DefaultOnRequest, DefaultOnResponse, TraceLayer}}; +use diesel_migrations::{embed_migrations, EmbeddedMigrations}; +use tower_http::services::ServeDir; +use tower_http::trace::{DefaultOnRequest, DefaultOnResponse, TraceLayer}; use tower_sessions::SessionManagerLayer; -use tower_sessions_sqlx_store::{sqlx::SqlitePool, SqliteStore}; +use tower_sessions_sqlx_store::sqlx::SqlitePool; +use tower_sessions_sqlx_store::SqliteStore; use tracing::Level; -use crate::{config::CommandLineOptions, context::Context, handler::{documents::{create_document_page, create_document_submit, documents_page, edit_document_page, edit_document_submit}, home::home_page, login::logout, login_page, login_submit, projects::{create_project_page, create_project_submit, projects_page}}, kv::KvHandle, logging::setup_logging, templates::make_template_loader}; +use crate::config::CommandLineOptions; +use crate::db; +use crate::handler::documents::{ + create_document_page, create_document_submit, documents_page, edit_document_page, + edit_document_submit, +}; +use crate::handler::home::home_page; +use crate::handler::login::logout; +use crate::handler::projects::{create_project_page, create_project_submit, projects_page}; +use crate::handler::{login_page, login_submit}; +use crate::logging::setup_logging; +use crate::provider::Provider; +use crate::templates::make_template_loader; + +pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("./migrations/"); pub async fn run() -> Result<()> { dotenvy::dotenv()?; @@ -21,16 +38,16 @@ pub async fn run() -> Result<()> { let template_loader = make_template_loader(opts.reload_templates); let db_url = dotenvy::var("DATABASE_URL")?; - let db = Database::connect(db_url).await?; + let mut db_conn = db::establish_connection(&db_url); + db::migrate(&mut db_conn); + + let db_pool = db::build_connection_pool(&db_url); let session_layer = create_session_manager_layer().await?; - // TODO: better name, also make it an option - let kv_handles = KvHandle::open("./kvdata/")?; + let provider = Provider::new(db_pool, template_loader); - let context = Context::new(db, kv_handles, template_loader); - - let auth_backend = context.clone(); + let auth_backend = provider.clone(); let auth_layer = AuthManagerLayerBuilder::new(auth_backend, session_layer.clone()).build(); let trace_layer = TraceLayer::new_for_http() @@ -54,7 +71,7 @@ pub async fn run() -> Result<()> { .layer(trace_layer) .layer(session_layer) .layer(auth_layer) - .with_state(context); + .with_state(provider); let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap(); axum::serve(listener, app).await.unwrap(); diff --git a/src/session.rs b/src/session.rs index f361889..197cb84 100644 --- a/src/session.rs +++ b/src/session.rs @@ -1,24 +1,21 @@ use async_trait::async_trait; use axum_login::{AuthUser, AuthnBackend, UserId}; -use crate::{ - db::{DbError, UserQuery}, - entity::user, - password, - prelude::*, -}; +use crate::models::{self, users, DbError}; +use crate::password; +use crate::prelude::*; -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub struct Credentials { pub username: String, pub password: String, } -impl AuthUser for user::Model { - type Id = i32; +impl AuthUser for models::users::User { + type Id = String; fn id(&self) -> Self::Id { - self.id + self.id.clone() } fn session_auth_hash(&self) -> &[u8] { @@ -27,8 +24,8 @@ impl AuthUser for user::Model { } #[async_trait] -impl AuthnBackend for Context { - type User = user::Model; +impl AuthnBackend for Provider { + type User = models::users::User; type Credentials = Credentials; type Error = DbError; @@ -36,14 +33,20 @@ impl AuthnBackend for Context { &self, creds: Self::Credentials, ) -> Result, Self::Error> { - let user = UserQuery(&self.db) - .by_username(&creds.username) - .await? - .filter(|u| password::verify(&u.password_hash, &creds.password)); - Ok(user) + let mut db = self.db_pool.get()?; + let user = users::q::by_username(&mut db, &creds.username)?; + + if password::verify(&user.password_hash, &creds.password) { + Ok(Some(user)) + } else { + Ok(None) + } } async fn get_user(&self, user_id: &UserId) -> Result, Self::Error> { - UserQuery(&self.db).by_id(*user_id).await + let mut db = self.db_pool.get()?; + let user = users::q::by_id(&mut db, user_id)?; + + Ok(Some(user)) } } diff --git a/src/templates.rs b/src/templates.rs index 9090c7f..9e45fb5 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -1,6 +1,5 @@ -use minijinja::{Error, ErrorKind}; use free_icons::IconAttrs; -use minijinja::{path_loader, Environment}; +use minijinja::{path_loader, Environment, Error, ErrorKind}; use minijinja_autoreload::AutoReloader; pub fn make_template_loader(auto_reload: bool) -> AutoReloader { @@ -25,10 +24,8 @@ pub fn setup_filters(env: &mut Environment) { pub fn heroicon_filter(name: String, classes: Option) -> Result { let class = classes.unwrap_or_else(|| "".to_owned()); - let attrs = IconAttrs::default() - .class(&class) - .fill("none") - .stroke_color("currentColor"); + let attrs = IconAttrs::default().class(&class).fill("none").stroke_color("currentColor"); - free_icons::heroicons(&name, true, attrs).ok_or(Error::new(ErrorKind::TemplateNotFound, "cannot find template for requested icon")) + free_icons::heroicons(&name, true, attrs) + .ok_or(Error::new(ErrorKind::TemplateNotFound, "cannot find template for requested icon")) } diff --git a/src/validation.rs b/src/validation.rs new file mode 100644 index 0000000..19946b0 --- /dev/null +++ b/src/validation.rs @@ -0,0 +1,13 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ValidationError { + pub field: String, + pub message: String, +} + +impl ValidationError { + pub fn on(field: &str, message: &str) -> ValidationError { + ValidationError { field: field.to_owned(), message: message.to_owned() } + } +}