diff --git a/.github/ISSUE_TEMPLATE/flag-request.md b/.github/ISSUE_TEMPLATE/flag-request.md
new file mode 100644
index 000000000..a969674df
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/flag-request.md
@@ -0,0 +1,19 @@
+---
+name: Flag Request
+about: Template for requesting new flags to be added to the Stats Viewer
+title: "[FLAGS]"
+labels: ''
+assignees: ''
+
+---
+
+
+
+Please add the following missing flag to the pointercrate stats viewer:
+
+**Country**:
+**Subdivision**:
+**ISO-Code**:
+**Link to PUBLIC DOMAIN `.svg` of flag**:
+
+Thanks
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000..8d75ff209
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,14 @@
+version: 2
+updates:
+ - package-ecosystem: "cargo"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ day: "sunday"
+ allow:
+ - dependency-type: "all"
+ open-pull-requests-limit: 1
+ groups:
+ pointercrate:
+ patterns:
+ - "*"
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 000000000..3adb3c674
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,3 @@
+## License Acceptance
+
+By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
diff --git a/.github/workflows/rustfmt.yml b/.github/workflows/rustfmt.yml
index c381bf67d..1c5c51335 100644
--- a/.github/workflows/rustfmt.yml
+++ b/.github/workflows/rustfmt.yml
@@ -22,7 +22,7 @@ jobs:
- uses: actions-rs/toolchain@v1
with:
profile: minimal
- toolchain: nightly
+ toolchain: stable
override: true
components: rustfmt
- run: rustup component add rustfmt
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index c1283fe56..126391a9d 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -66,3 +66,21 @@ jobs:
DATABASE_URL: postgresql://pointercrate:postgres@localhost/postgres
RUST_BACKTRACE: 1
RUSTFLAGS: -Cinstrument-coverage
+ LIST_SIZE: 75
+ EXNTEDED_LIST_SIZE: 150
+
+ - name: Install grcov
+ uses: actions-rs/cargo@v1
+ with:
+ command: install
+ args: grcov
+
+ - name: Generate coverage report
+ run: grcov . -s . --binary-path ./target/debug/ -t lcov --ignore-not-existing -o ./target/debug/coverage.lcov --ignore "pointercrate-test/*" --ignore "pointercrate-example/*" --keep-only "pointercrate-*"
+
+ - name: Upload coverage to Codecov
+ uses: codecov/codecov-action@v4
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+ with:
+ files: ./target/debug/coverage.lcov
diff --git a/.gitignore b/.gitignore
index 3f20d61b2..7ec79fc94 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,5 +2,4 @@
.env
.secret
.idea
-run_coverage.sh
-codecov
\ No newline at end of file
+.vscode
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index 67e959e92..db9d2d6a6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 3
+[[package]]
+name = "addr2line"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
+dependencies = [
+ "gimli",
+]
+
[[package]]
name = "adler"
version = "1.0.2"
@@ -10,15 +19,38 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
-version = "0.7.6"
+version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
+checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
+ "cfg-if",
"getrandom",
"once_cell",
"version_check",
+ "zerocopy",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
]
+[[package]]
+name = "allocator-api2"
+version = "0.2.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
+
+[[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"
@@ -47,77 +79,94 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.58",
]
[[package]]
name = "async-trait"
-version = "0.1.68"
+version = "0.1.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
+checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.58",
]
[[package]]
name = "atoi"
-version = "1.0.0"
+version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e"
+checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
dependencies = [
"num-traits",
]
[[package]]
name = "atomic"
-version = "0.5.1"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba"
+
+[[package]]
+name = "atomic"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c"
+checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994"
dependencies = [
- "autocfg",
+ "bytemuck",
]
[[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 = "base64"
-version = "0.11.0"
+name = "backtrace"
+version = "0.3.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
+checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
+dependencies = [
+ "addr2line",
+ "cc",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
[[package]]
name = "base64"
-version = "0.12.3"
+version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
+checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
-version = "0.13.1"
+version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
-name = "base64"
-version = "0.21.0"
+name = "base64ct"
+version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
+checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
name = "bcrypt"
-version = "0.9.0"
+version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4d0faafe9e089674fc3efdb311ff5253d445c79d85d1d28bd3ace76d45e7164"
+checksum = "e65938ed058ef47d92cf8b346cc76ef48984572ade631927e9937b5ffc7662c7"
dependencies = [
- "base64 0.13.1",
+ "base64 0.22.1",
"blowfish",
"getrandom",
+ "subtle",
+ "zeroize",
]
[[package]]
@@ -143,9 +192,12 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
-version = "2.2.1"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813"
+checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
+dependencies = [
+ "serde",
+]
[[package]]
name = "block-buffer"
@@ -158,38 +210,43 @@ dependencies = [
[[package]]
name = "blowfish"
-version = "0.7.0"
+version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32fa6a061124e37baba002e496d203e23ba3d7b73750be82dbfbc92913048a5b"
+checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7"
dependencies = [
"byteorder",
"cipher",
- "opaque-debug",
]
[[package]]
name = "bumpalo"
-version = "3.12.1"
+version = "3.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+
+[[package]]
+name = "bytemuck"
+version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8"
+checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e"
[[package]]
name = "byteorder"
-version = "1.4.3"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
-version = "1.4.0"
+version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
+checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
[[package]]
name = "cc"
-version = "1.0.79"
+version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+checksum = "2755ff20a1d93490d26ba33a6f092a38a508398a5320df5d4b3014fcccce9410"
[[package]]
name = "cfg-if"
@@ -199,38 +256,34 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
-version = "0.4.24"
+version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b"
+checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
+ "android-tzdata",
"iana-time-zone",
"js-sys",
- "num-integer",
"num-traits",
"serde",
- "time 0.1.43",
"wasm-bindgen",
- "winapi",
+ "windows-targets 0.52.0",
]
[[package]]
name = "cipher"
-version = "0.2.5"
+version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801"
+checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
- "generic-array",
+ "crypto-common",
+ "inout",
]
[[package]]
-name = "codespan-reporting"
-version = "0.11.1"
+name = "const-oid"
+version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
-dependencies = [
- "termcolor",
- "unicode-width",
-]
+checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "convert_case"
@@ -240,20 +293,20 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]]
name = "cookie"
-version = "0.17.0"
+version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24"
+checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
dependencies = [
"percent-encoding",
- "time 0.3.20",
+ "time",
"version_check",
]
[[package]]
name = "core-foundation"
-version = "0.9.3"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
+checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
@@ -261,61 +314,57 @@ dependencies = [
[[package]]
name = "core-foundation-sys"
-version = "0.8.4"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
+checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "cpufeatures"
-version = "0.2.7"
+version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58"
+checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
dependencies = [
"libc",
]
[[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",
]
[[package]]
name = "crc-catalog"
-version = "2.2.0"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484"
+checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
[[package]]
name = "crc32fast"
-version = "1.3.2"
+version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-queue"
-version = "0.3.8"
+version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
+checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
dependencies = [
- "cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
-version = "0.8.15"
+version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
-dependencies = [
- "cfg-if",
-]
+checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "crypto-common"
@@ -328,88 +377,77 @@ dependencies = [
]
[[package]]
-name = "cxx"
-version = "1.0.94"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93"
+name = "dash-rs"
+version = "0.1.0"
+source = "git+https://github.com/qimiko/dash-rs?rev=21b8e86aa3ffe9ba4ba4bfd147b94abf2afa50ef#21b8e86aa3ffe9ba4ba4bfd147b94abf2afa50ef"
dependencies = [
- "cc",
- "cxxbridge-flags",
- "cxxbridge-macro",
- "link-cplusplus",
+ "base64 0.21.7",
+ "dash-rs-derive",
+ "dtoa",
+ "flate2",
+ "itoa",
+ "log",
+ "percent-encoding",
+ "serde",
+ "serde_yaml",
+ "thiserror",
+ "variant_partial_eq",
]
[[package]]
-name = "cxx-build"
-version = "1.0.94"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b"
+name = "dash-rs-derive"
+version = "0.1.0"
+source = "git+https://github.com/qimiko/dash-rs?rev=21b8e86aa3ffe9ba4ba4bfd147b94abf2afa50ef#21b8e86aa3ffe9ba4ba4bfd147b94abf2afa50ef"
dependencies = [
- "cc",
- "codespan-reporting",
- "once_cell",
"proc-macro2",
"quote",
- "scratch",
- "syn 2.0.15",
+ "syn 2.0.58",
]
[[package]]
-name = "cxxbridge-flags"
-version = "1.0.94"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb"
-
-[[package]]
-name = "cxxbridge-macro"
-version = "1.0.94"
+name = "dashmap"
+version = "5.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5"
+checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.15",
+ "cfg-if",
+ "hashbrown",
+ "lock_api",
+ "once_cell",
+ "parking_lot_core",
]
[[package]]
-name = "dash-rs"
-version = "0.1.0"
-source = "git+https://github.com/qimiko/dash-rs#d935929542035fa845db7ddc9a565cb3881fa1a8"
+name = "der"
+version = "0.7.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
dependencies = [
- "base64 0.11.0",
- "dtoa",
- "flate2",
- "itoa 0.4.8",
- "log",
- "percent-encoding",
- "serde",
- "serde_yaml",
+ "const-oid",
+ "pem-rfc7468",
+ "zeroize",
]
[[package]]
-name = "dashmap"
-version = "5.4.0"
+name = "deranged"
+version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
+checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [
- "cfg-if",
- "hashbrown",
- "lock_api",
- "once_cell",
- "parking_lot_core 0.9.7",
+ "powerfmt",
]
[[package]]
name = "derive_more"
-version = "0.99.17"
+version = "0.99.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
+checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"rustc_version",
- "syn 1.0.109",
+ "syn 2.0.58",
]
[[package]]
@@ -438,44 +476,25 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a"
dependencies = [
- "bitflags 2.2.1",
+ "bitflags 2.4.1",
"proc-macro2",
"proc-macro2-diagnostics",
"quote",
- "syn 2.0.15",
+ "syn 2.0.58",
]
[[package]]
name = "digest"
-version = "0.10.6"
+version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
+ "const-oid",
"crypto-common",
"subtle",
]
-[[package]]
-name = "dirs"
-version = "4.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
-dependencies = [
- "dirs-sys",
-]
-
-[[package]]
-name = "dirs-sys"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
-dependencies = [
- "libc",
- "redox_users",
- "winapi",
-]
-
[[package]]
name = "dotenv"
version = "0.15.0"
@@ -490,47 +509,53 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
name = "dtoa"
-version = "0.4.8"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
+checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653"
[[package]]
name = "either"
-version = "1.8.1"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
+checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
dependencies = [
"serde",
]
[[package]]
name = "encoding_rs"
-version = "0.8.32"
+version = "0.8.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
+checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
dependencies = [
"cfg-if",
]
+[[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.1"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
+checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
- "errno-dragonfly",
"libc",
- "windows-sys 0.48.0",
+ "windows-sys 0.52.0",
]
[[package]]
-name = "errno-dragonfly"
-version = "0.1.2"
+name = "etcetera"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
dependencies = [
- "cc",
- "libc",
+ "cfg-if",
+ "home",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -541,20 +566,17 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "fastrand"
-version = "1.9.0"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
-dependencies = [
- "instant",
-]
+checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
[[package]]
name = "figment"
-version = "0.10.8"
+version = "0.10.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e56602b469b2201400dec66a66aec5a9b8761ee97cd1b8c96ab2483fcc16cc9"
+checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3"
dependencies = [
- "atomic",
+ "atomic 0.6.0",
"pear",
"serde",
"toml",
@@ -564,15 +586,26 @@ dependencies = [
[[package]]
name = "flate2"
-version = "1.0.26"
+version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
+checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
dependencies = [
"crc32fast",
"libz-sys",
"miniz_oxide",
]
+[[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 = "fnv"
version = "1.0.7"
@@ -596,18 +629,18 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
-version = "1.1.0"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [
"percent-encoding",
]
[[package]]
name = "futures"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
+checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
dependencies = [
"futures-channel",
"futures-core",
@@ -620,9 +653,9 @@ dependencies = [
[[package]]
name = "futures-channel"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
+checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
dependencies = [
"futures-core",
"futures-sink",
@@ -630,15 +663,15 @@ dependencies = [
[[package]]
name = "futures-core"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
+checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-executor"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
+checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
dependencies = [
"futures-core",
"futures-task",
@@ -647,55 +680,55 @@ dependencies = [
[[package]]
name = "futures-intrusive"
-version = "0.4.2"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5"
+checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
dependencies = [
"futures-core",
"lock_api",
- "parking_lot 0.11.2",
+ "parking_lot",
]
[[package]]
name = "futures-io"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
+checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-macro"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
+checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.58",
]
[[package]]
name = "futures-sink"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
+checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
[[package]]
name = "futures-task"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
+checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
[[package]]
name = "futures-timer"
-version = "3.0.2"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
+checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24"
[[package]]
name = "futures-util"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
+checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-channel",
"futures-core",
@@ -711,9 +744,9 @@ dependencies = [
[[package]]
name = "generator"
-version = "0.7.4"
+version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3e123d9ae7c02966b4d892e550bdc32164f05853cd40ab570650ad600596a8a"
+checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e"
dependencies = [
"cc",
"libc",
@@ -734,15 +767,23 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.9"
+version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
+checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
+ "js-sys",
"libc",
- "wasi 0.11.0+wasi-snapshot-preview1",
+ "wasi",
+ "wasm-bindgen",
]
+[[package]]
+name = "gimli"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
+
[[package]]
name = "glob"
version = "0.3.1"
@@ -751,9 +792,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "governor"
-version = "0.5.1"
+version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c390a940a5d157878dd057c78680a33ce3415bcd05b4799509ea44210914b4d5"
+checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b"
dependencies = [
"cfg-if",
"dashmap",
@@ -761,24 +802,45 @@ dependencies = [
"futures-timer",
"no-std-compat",
"nonzero_ext",
- "parking_lot 0.12.1",
+ "parking_lot",
+ "portable-atomic",
"quanta",
"rand",
"smallvec",
+ "spinning_top",
]
[[package]]
name = "h2"
-version = "0.3.18"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
+dependencies = [
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http 0.2.12",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "h2"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21"
+checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
- "http",
+ "http 1.1.0",
"indexmap",
"slab",
"tokio",
@@ -788,18 +850,19 @@ dependencies = [
[[package]]
name = "hashbrown"
-version = "0.12.3"
+version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
+ "allocator-api2",
]
[[package]]
name = "hashlink"
-version = "0.8.1"
+version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa"
+checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
dependencies = [
"hashbrown",
]
@@ -815,18 +878,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.3.1"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
+checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "hex"
@@ -836,9 +890,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hkdf"
-version = "0.12.3"
+version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437"
+checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
dependencies = [
"hmac",
]
@@ -852,56 +906,99 @@ dependencies = [
"digest",
]
+[[package]]
+name = "home"
+version = "0.5.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
+dependencies = [
+ "windows-sys 0.52.0",
+]
+
[[package]]
name = "http"
-version = "0.2.9"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
+checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
dependencies = [
"bytes",
"fnv",
- "itoa 1.0.6",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
+dependencies = [
+ "bytes",
+ "http 0.2.12",
+ "pin-project-lite",
]
[[package]]
name = "http-body"
-version = "0.4.5"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
+dependencies = [
+ "bytes",
+ "http 1.1.0",
+]
+
+[[package]]
+name = "http-body-util"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
dependencies = [
"bytes",
- "http",
+ "futures-util",
+ "http 1.1.0",
+ "http-body 1.0.0",
"pin-project-lite",
]
[[package]]
name = "httparse"
-version = "1.8.0"
+version = "1.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
+checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
[[package]]
name = "httpdate"
-version = "1.0.2"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
+checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
-version = "0.14.26"
+version = "0.14.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
+checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
- "h2",
- "http",
- "http-body",
+ "h2 0.3.26",
+ "http 0.2.12",
+ "http-body 0.4.6",
"httparse",
"httpdate",
- "itoa 1.0.6",
+ "itoa",
"pin-project-lite",
"socket2",
"tokio",
@@ -911,144 +1008,177 @@ dependencies = [
]
[[package]]
-name = "hyper-tls"
-version = "0.5.0"
+name = "hyper"
+version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
+checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d"
dependencies = [
"bytes",
- "hyper",
- "native-tls",
+ "futures-channel",
+ "futures-util",
+ "h2 0.4.3",
+ "http 1.1.0",
+ "http-body 1.0.0",
+ "httparse",
+ "itoa",
+ "pin-project-lite",
+ "smallvec",
"tokio",
- "tokio-native-tls",
+ "want",
]
[[package]]
-name = "iana-time-zone"
-version = "0.1.56"
+name = "hyper-rustls"
+version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c"
+checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155"
dependencies = [
- "android_system_properties",
- "core-foundation-sys",
- "iana-time-zone-haiku",
- "js-sys",
- "wasm-bindgen",
- "windows",
+ "futures-util",
+ "http 1.1.0",
+ "hyper 1.3.1",
+ "hyper-util",
+ "rustls",
+ "rustls-pki-types",
+ "tokio",
+ "tokio-rustls",
+ "tower-service",
]
[[package]]
-name = "iana-time-zone-haiku"
-version = "0.1.1"
+name = "hyper-tls"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
+checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
dependencies = [
- "cxx",
- "cxx-build",
+ "bytes",
+ "http-body-util",
+ "hyper 1.3.1",
+ "hyper-util",
+ "native-tls",
+ "tokio",
+ "tokio-native-tls",
+ "tower-service",
]
[[package]]
-name = "idna"
-version = "0.3.0"
+name = "hyper-util"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56"
dependencies = [
- "unicode-bidi",
- "unicode-normalization",
-]
-
+ "bytes",
+ "futures-channel",
+ "futures-util",
+ "http 1.1.0",
+ "http-body 1.0.0",
+ "hyper 1.3.1",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower",
+ "tower-service",
+ "tracing",
+]
+
[[package]]
-name = "indexmap"
-version = "1.9.3"
+name = "iana-time-zone"
+version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
dependencies = [
- "autocfg",
- "hashbrown",
- "serde",
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "windows-core",
]
[[package]]
-name = "inlinable_string"
-version = "0.1.15"
+name = "iana-time-zone-haiku"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
[[package]]
-name = "instant"
-version = "0.1.12"
+name = "idna"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
- "cfg-if",
+ "unicode-bidi",
+ "unicode-normalization",
]
[[package]]
-name = "io-lifetimes"
-version = "1.0.10"
+name = "indexmap"
+version = "2.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
+checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
dependencies = [
- "hermit-abi 0.3.1",
- "libc",
- "windows-sys 0.48.0",
+ "equivalent",
+ "hashbrown",
+ "serde",
]
[[package]]
-name = "ipnet"
-version = "2.7.2"
+name = "inlinable_string"
+version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
+checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
[[package]]
-name = "is-terminal"
-version = "0.4.7"
+name = "inout"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
+checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [
- "hermit-abi 0.3.1",
- "io-lifetimes",
- "rustix",
- "windows-sys 0.48.0",
+ "generic-array",
]
[[package]]
-name = "itertools"
-version = "0.10.5"
+name = "ipnet"
+version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
-dependencies = [
- "either",
-]
+checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
-name = "itoa"
-version = "0.4.8"
+name = "is-terminal"
+version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
+checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "windows-sys 0.52.0",
+]
[[package]]
name = "itoa"
-version = "1.0.6"
+version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
+checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "js-sys"
-version = "0.3.61"
+version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
+checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "jsonwebtoken"
-version = "7.2.0"
+version = "9.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afabcc15e437a6484fc4f12d0fd63068fe457bf93f1c148d3d9649c60b103f32"
+checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f"
dependencies = [
- "base64 0.12.3",
+ "base64 0.21.7",
+ "js-sys",
"pem",
"ring",
"serde",
@@ -1058,21 +1188,30 @@ dependencies = [
[[package]]
name = "lazy_static"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+dependencies = [
+ "spin",
+]
[[package]]
name = "libc"
-version = "0.2.142"
+version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
-name = "libz-sys"
-version = "1.1.9"
+name = "libm"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
+
+[[package]]
+name = "libsqlite3-sys"
+version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db"
+checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716"
dependencies = [
"cc",
"pkg-config",
@@ -1080,31 +1219,27 @@ dependencies = [
]
[[package]]
-name = "link-cplusplus"
-version = "1.0.8"
+name = "libz-sys"
+version = "1.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
+checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e"
dependencies = [
"cc",
+ "pkg-config",
+ "vcpkg",
]
-[[package]]
-name = "linked-hash-map"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
-
[[package]]
name = "linux-raw-sys"
-version = "0.3.6"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b64f40e5e03e0d54f03845c8197d0291253cdbedfb1cb46b13c2c117554a9f4c"
+checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "lock_api"
-version = "0.4.9"
+version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
+checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
@@ -1112,12 +1247,9 @@ dependencies = [
[[package]]
name = "log"
-version = "0.4.17"
+version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
-dependencies = [
- "cfg-if",
-]
+checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "loom"
@@ -1134,60 +1266,52 @@ dependencies = [
"tracing-subscriber",
]
-[[package]]
-name = "mach"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
-dependencies = [
- "libc",
-]
-
[[package]]
name = "matchers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
- "regex-automata",
+ "regex-automata 0.1.10",
]
[[package]]
name = "maud"
-version = "0.25.0"
+version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0bab19cef8a7fe1c18a43e881793bfc9d4ea984befec3ae5bd0415abf3ecf00"
+checksum = "df518b75016b4289cdddffa1b01f2122f4a49802c93191f3133f6dc2472ebcaa"
dependencies = [
- "itoa 1.0.6",
+ "itoa",
"maud_macros",
]
[[package]]
name = "maud_macros"
-version = "0.25.0"
+version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0be95d66c3024ffce639216058e5bae17a83ecaf266ffc6e4d060ad447c9eed2"
+checksum = "fa453238ec218da0af6b11fc5978d3b5c3a45ed97b722391a2a11f3306274e18"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
- "syn 1.0.109",
+ "syn 2.0.58",
]
[[package]]
name = "md-5"
-version = "0.10.5"
+version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca"
+checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
dependencies = [
+ "cfg-if",
"digest",
]
[[package]]
name = "memchr"
-version = "2.5.0"
+version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "mime"
@@ -1203,40 +1327,38 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
-version = "0.7.1"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
+checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [
"adler",
]
[[package]]
name = "mio"
-version = "0.8.6"
+version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
+checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
- "log",
- "wasi 0.11.0+wasi-snapshot-preview1",
- "windows-sys 0.45.0",
+ "wasi",
+ "windows-sys 0.48.0",
]
[[package]]
name = "multer"
-version = "2.1.0"
+version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2"
+checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b"
dependencies = [
"bytes",
"encoding_rs",
"futures-util",
- "http",
+ "http 1.1.0",
"httparse",
- "log",
"memchr",
"mime",
- "spin 0.9.8",
+ "spin",
"tokio",
"tokio-util",
"version_check",
@@ -1244,11 +1366,10 @@ dependencies = [
[[package]]
name = "native-tls"
-version = "0.2.11"
+version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
+checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
dependencies = [
- "lazy_static",
"libc",
"log",
"openssl",
@@ -1294,63 +1415,99 @@ dependencies = [
[[package]]
name = "num-bigint"
-version = "0.2.6"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
+checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
- "autocfg",
"num-integer",
"num-traits",
]
+[[package]]
+name = "num-bigint-dig"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
+dependencies = [
+ "byteorder",
+ "lazy_static",
+ "libm",
+ "num-integer",
+ "num-iter",
+ "num-traits",
+ "rand",
+ "smallvec",
+ "zeroize",
+]
+
+[[package]]
+name = "num-conv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+
[[package]]
name = "num-integer"
+version = "0.1.46"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "num-iter"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
dependencies = [
"autocfg",
+ "num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
-version = "0.2.15"
+version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
+ "libm",
]
[[package]]
name = "num_cpus"
-version = "1.15.0"
+version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
- "hermit-abi 0.2.6",
+ "hermit-abi",
"libc",
]
[[package]]
-name = "once_cell"
-version = "1.17.1"
+name = "object"
+version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
+checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce"
+dependencies = [
+ "memchr",
+]
[[package]]
-name = "opaque-debug"
-version = "0.3.0"
+name = "once_cell"
+version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "openssl"
-version = "0.10.55"
+version = "0.10.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d"
+checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.4.1",
"cfg-if",
"foreign-types",
"libc",
@@ -1367,7 +1524,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.58",
]
[[package]]
@@ -1378,9 +1535,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
-version = "0.9.90"
+version = "0.9.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6"
+checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2"
dependencies = [
"cc",
"libc",
@@ -1396,63 +1553,38 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "parking_lot"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
-dependencies = [
- "instant",
- "lock_api",
- "parking_lot_core 0.8.6",
-]
-
-[[package]]
-name = "parking_lot"
-version = "0.12.1"
+version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
"lock_api",
- "parking_lot_core 0.9.7",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
-dependencies = [
- "cfg-if",
- "instant",
- "libc",
- "redox_syscall 0.2.16",
- "smallvec",
- "winapi",
+ "parking_lot_core",
]
[[package]]
name = "parking_lot_core"
-version = "0.9.7"
+version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
+checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
- "redox_syscall 0.2.16",
+ "redox_syscall 0.5.1",
"smallvec",
- "windows-sys 0.45.0",
+ "windows-targets 0.52.0",
]
[[package]]
name = "paste"
-version = "1.0.12"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pear"
-version = "0.2.4"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ec95680a7087503575284e5063e14b694b7a9c0b065e5dceec661e0497127e8"
+checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467"
dependencies = [
"inlinable_string",
"pear_codegen",
@@ -1461,38 +1593,66 @@ dependencies = [
[[package]]
name = "pear_codegen"
-version = "0.2.4"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9661a3a53f93f09f2ea882018e4d7c88f6ff2956d809a276060476fd8c879d3c"
+checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147"
dependencies = [
"proc-macro2",
"proc-macro2-diagnostics",
"quote",
- "syn 2.0.15",
+ "syn 2.0.58",
]
[[package]]
name = "pem"
-version = "0.8.3"
+version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb"
+checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae"
dependencies = [
- "base64 0.13.1",
- "once_cell",
- "regex",
+ "base64 0.22.1",
+ "serde",
+]
+
+[[package]]
+name = "pem-rfc7468"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
+dependencies = [
+ "base64ct",
]
[[package]]
name = "percent-encoding"
-version = "2.2.0"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+
+[[package]]
+name = "pin-project"
+version = "1.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
+dependencies = [
+ "pin-project-internal",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
+checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.58",
+]
[[package]]
name = "pin-project-lite"
-version = "0.2.9"
+version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "pin-utils"
@@ -1500,11 +1660,32 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+[[package]]
+name = "pkcs1"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
+dependencies = [
+ "der",
+ "pkcs8",
+ "spki",
+]
+
+[[package]]
+name = "pkcs8"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
+dependencies = [
+ "der",
+ "spki",
+]
+
[[package]]
name = "pkg-config"
-version = "0.3.26"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
+checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "pointercrate-core"
@@ -1550,6 +1731,7 @@ dependencies = [
"futures",
"log",
"pointercrate-core",
+ "pointercrate-user",
"serde",
"sqlx",
"tokio",
@@ -1572,6 +1754,7 @@ dependencies = [
"pointercrate-integrate",
"pointercrate-user",
"pointercrate-user-api",
+ "rand",
"reqwest",
"rocket",
"serde",
@@ -1597,6 +1780,24 @@ dependencies = [
"url",
]
+[[package]]
+name = "pointercrate-example"
+version = "0.1.0"
+dependencies = [
+ "dotenv",
+ "maud",
+ "pointercrate-core",
+ "pointercrate-core-api",
+ "pointercrate-core-pages",
+ "pointercrate-demonlist",
+ "pointercrate-demonlist-api",
+ "pointercrate-demonlist-pages",
+ "pointercrate-user",
+ "pointercrate-user-api",
+ "pointercrate-user-pages",
+ "rocket",
+]
+
[[package]]
name = "pointercrate-integrate"
version = "0.1.0"
@@ -1605,7 +1806,11 @@ dependencies = [
"chrono",
"dash-rs",
"futures",
+ "governor",
"log",
+ "nonzero_ext",
+ "pointercrate-core",
+ "pointercrate-demonlist",
"reqwest",
"sqlx",
"tokio",
@@ -1617,6 +1822,7 @@ version = "0.1.0"
dependencies = [
"dotenv",
"pointercrate-core",
+ "pointercrate-core-api",
"pointercrate-demonlist",
"pointercrate-demonlist-api",
"pointercrate-user",
@@ -1625,6 +1831,7 @@ dependencies = [
"rocket",
"serde",
"serde_json",
+ "serde_urlencoded",
"sqlx",
]
@@ -1632,7 +1839,7 @@ dependencies = [
name = "pointercrate-user"
version = "0.1.0"
dependencies = [
- "base64 0.13.1",
+ "base64 0.22.1",
"bcrypt",
"derive_more",
"futures",
@@ -1650,7 +1857,7 @@ dependencies = [
name = "pointercrate-user-api"
version = "0.1.0"
dependencies = [
- "base64 0.21.0",
+ "base64 0.22.1",
"governor",
"log",
"nonzero_ext",
@@ -1675,6 +1882,18 @@ dependencies = [
"pointercrate-user",
]
+[[package]]
+name = "portable-atomic"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
+
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
[[package]]
name = "ppv-lite86"
version = "0.2.17"
@@ -1690,7 +1909,6 @@ dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
- "syn 1.0.109",
"version_check",
]
@@ -1707,47 +1925,46 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.56"
+version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
[[package]]
name = "proc-macro2-diagnostics"
-version = "0.10.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "606c4ba35817e2922a308af55ad51bab3645b59eae5c570d4a6cf07e36bd493b"
+checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.58",
"version_check",
"yansi",
]
[[package]]
name = "quanta"
-version = "0.9.3"
+version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20afe714292d5e879d8b12740aa223c6a88f118af41870e8b6196e39a02238a8"
+checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5"
dependencies = [
"crossbeam-utils",
"libc",
- "mach",
"once_cell",
"raw-cpuid",
- "wasi 0.10.2+wasi-snapshot-preview1",
+ "wasi",
"web-sys",
"winapi",
]
[[package]]
name = "quote"
-version = "1.0.26"
+version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
+checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
@@ -1784,69 +2001,61 @@ dependencies = [
[[package]]
name = "raw-cpuid"
-version = "10.7.0"
+version = "11.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
+checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.4.1",
]
[[package]]
name = "redox_syscall"
-version = "0.2.16"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_syscall"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
-dependencies = [
- "bitflags 1.3.2",
-]
-
-[[package]]
-name = "redox_users"
-version = "0.4.3"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
+checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
dependencies = [
- "getrandom",
- "redox_syscall 0.2.16",
- "thiserror",
+ "bitflags 2.4.1",
]
[[package]]
name = "ref-cast"
-version = "1.0.16"
+version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f43faa91b1c8b36841ee70e97188a869d37ae21759da6846d4be66de5bf7b12c"
+checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931"
dependencies = [
"ref-cast-impl",
]
[[package]]
name = "ref-cast-impl"
-version = "1.0.16"
+version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d2275aab483050ab2a7364c1a46604865ee7d6906684e08db0f090acf74f9e7"
+checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.58",
]
[[package]]
name = "regex"
-version = "1.8.1"
+version = "1.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
+checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
dependencies = [
- "regex-syntax 0.7.1",
+ "aho-corasick",
+ "memchr",
+ "regex-automata 0.4.6",
+ "regex-syntax 0.8.2",
]
[[package]]
@@ -1858,6 +2067,17 @@ 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"
@@ -1866,26 +2086,29 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
-version = "0.7.1"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
+checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "reqwest"
-version = "0.11.17"
+version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91"
+checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37"
dependencies = [
- "base64 0.21.0",
+ "base64 0.22.1",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
- "h2",
- "http",
- "http-body",
- "hyper",
+ "h2 0.4.3",
+ "http 1.1.0",
+ "http-body 1.0.0",
+ "http-body-util",
+ "hyper 1.3.1",
+ "hyper-rustls",
"hyper-tls",
+ "hyper-util",
"ipnet",
"js-sys",
"log",
@@ -1894,9 +2117,12 @@ dependencies = [
"once_cell",
"percent-encoding",
"pin-project-lite",
+ "rustls-pemfile",
"serde",
"serde_json",
"serde_urlencoded",
+ "sync_wrapper",
+ "system-configuration",
"tokio",
"tokio-native-tls",
"tower-service",
@@ -1909,40 +2135,39 @@ dependencies = [
[[package]]
name = "ring"
-version = "0.16.20"
+version = "0.17.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
dependencies = [
"cc",
+ "cfg-if",
+ "getrandom",
"libc",
- "once_cell",
- "spin 0.5.2",
+ "spin",
"untrusted",
- "web-sys",
- "winapi",
+ "windows-sys 0.52.0",
]
[[package]]
name = "rocket"
-version = "0.5.0-rc.3"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58734f7401ae5cfd129685b48f61182331745b357b96f2367f01aebaf1cc9cc9"
+checksum = "a516907296a31df7dc04310e7043b61d71954d703b603cc6867a026d7e72d73f"
dependencies = [
"async-stream",
"async-trait",
- "atomic",
+ "atomic 0.5.3",
"binascii",
"bytes",
"either",
"figment",
"futures",
"indexmap",
- "is-terminal",
"log",
"memchr",
"multer",
"num_cpus",
- "parking_lot 0.12.1",
+ "parking_lot",
"pin-project-lite",
"rand",
"ref-cast",
@@ -1952,7 +2177,7 @@ dependencies = [
"serde_json",
"state",
"tempfile",
- "time 0.3.20",
+ "time",
"tokio",
"tokio-stream",
"tokio-util",
@@ -1963,9 +2188,9 @@ dependencies = [
[[package]]
name = "rocket_codegen"
-version = "0.5.0-rc.3"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7093353f14228c744982e409259fb54878ba9563d08214f2d880d59ff2fc508b"
+checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46"
dependencies = [
"devise",
"glob",
@@ -1973,21 +2198,22 @@ dependencies = [
"proc-macro2",
"quote",
"rocket_http",
- "syn 2.0.15",
+ "syn 2.0.58",
"unicode-xid",
+ "version_check",
]
[[package]]
name = "rocket_http"
-version = "0.5.0-rc.3"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "936012c99162a03a67f37f9836d5f938f662e26f2717809761a9ac46432090f4"
+checksum = "e274915a20ee3065f611c044bd63c40757396b6dbc057d6046aec27f14f882b9"
dependencies = [
"cookie",
"either",
"futures",
- "http",
- "hyper",
+ "http 0.2.12",
+ "hyper 0.14.29",
"indexmap",
"log",
"memchr",
@@ -1999,13 +2225,39 @@ dependencies = [
"smallvec",
"stable-pattern",
"state",
- "time 0.3.20",
+ "time",
"tokio",
"uncased",
]
[[package]]
-name = "rustc_version"
+name = "rsa"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc"
+dependencies = [
+ "const-oid",
+ "digest",
+ "num-bigint-dig",
+ "num-integer",
+ "num-traits",
+ "pkcs1",
+ "pkcs8",
+ "rand_core",
+ "signature",
+ "spki",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
+
+[[package]]
+name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
@@ -2015,37 +2267,76 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.37.18"
+version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8bbfc1d1c7c40c01715f47d71444744a81669ca84e8b63e25a55e169b1f86433"
+checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.4.1",
"errno",
- "io-lifetimes",
"libc",
"linux-raw-sys",
- "windows-sys 0.48.0",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "rustls"
+version = "0.23.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402"
+dependencies = [
+ "once_cell",
+ "rustls-pki-types",
+ "rustls-webpki",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "2.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
+dependencies = [
+ "base64 0.22.1",
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "rustls-pki-types"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
+
+[[package]]
+name = "rustls-webpki"
+version = "0.102.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
+dependencies = [
+ "ring",
+ "rustls-pki-types",
+ "untrusted",
]
[[package]]
name = "rustversion"
-version = "1.0.12"
+version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
+checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
[[package]]
name = "ryu"
-version = "1.0.13"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
+checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "schannel"
-version = "0.1.21"
+version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
+checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
dependencies = [
- "windows-sys 0.42.0",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -2056,21 +2347,15 @@ checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-
-[[package]]
-name = "scratch"
-version = "1.0.5"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "security-framework"
-version = "2.8.2"
+version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
+checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
@@ -2081,9 +2366,9 @@ dependencies = [
[[package]]
name = "security-framework-sys"
-version = "2.8.0"
+version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
+checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7"
dependencies = [
"core-foundation-sys",
"libc",
@@ -2091,41 +2376,50 @@ dependencies = [
[[package]]
name = "semver"
-version = "1.0.17"
+version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
+checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]]
name = "serde"
-version = "1.0.160"
+version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c"
+checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.160"
+version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df"
+checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.58",
]
[[package]]
name = "serde_json"
-version = "1.0.96"
+version = "1.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
+checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4"
dependencies = [
- "itoa 1.0.6",
+ "itoa",
"ryu",
"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"
@@ -2133,28 +2427,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
- "itoa 1.0.6",
+ "itoa",
"ryu",
"serde",
]
[[package]]
name = "serde_yaml"
-version = "0.8.26"
+version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
+checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap",
+ "itoa",
"ryu",
"serde",
- "yaml-rust",
+ "unsafe-libyaml",
]
[[package]]
name = "sha1"
-version = "0.10.5"
+version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
@@ -2163,9 +2458,9 @@ dependencies = [
[[package]]
name = "sha2"
-version = "0.10.6"
+version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
+checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
@@ -2174,147 +2469,179 @@ dependencies = [
[[package]]
name = "sharded-slab"
-version = "0.1.4"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
+checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[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",
]
+[[package]]
+name = "signature"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
+dependencies = [
+ "digest",
+ "rand_core",
+]
+
[[package]]
name = "simple_asn1"
-version = "0.4.1"
+version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b"
+checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085"
dependencies = [
- "chrono",
"num-bigint",
"num-traits",
+ "thiserror",
+ "time",
]
[[package]]
name = "slab"
-version = "0.4.8"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
dependencies = [
"autocfg",
]
[[package]]
name = "smallvec"
-version = "1.10.0"
+version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
+checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socket2"
-version = "0.4.9"
+version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
+checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
dependencies = [
"libc",
- "winapi",
+ "windows-sys 0.52.0",
]
[[package]]
name = "spin"
-version = "0.5.2"
+version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+dependencies = [
+ "lock_api",
+]
[[package]]
-name = "spin"
-version = "0.9.8"
+name = "spinning_top"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
+name = "spki"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
+dependencies = [
+ "base64ct",
+ "der",
+]
[[package]]
name = "sqlformat"
-version = "0.2.1"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e"
+checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f"
dependencies = [
- "itertools",
"nom",
"unicode_categories",
]
[[package]]
name = "sqlx"
-version = "0.6.3"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188"
+checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa"
dependencies = [
"sqlx-core",
"sqlx-macros",
+ "sqlx-mysql",
+ "sqlx-postgres",
+ "sqlx-sqlite",
]
[[package]]
name = "sqlx-core"
-version = "0.6.3"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029"
+checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6"
dependencies = [
"ahash",
"atoi",
- "base64 0.13.1",
- "bitflags 1.3.2",
"byteorder",
"bytes",
"chrono",
"crc",
"crossbeam-queue",
- "dirs",
- "dotenvy",
"either",
"event-listener",
"futures-channel",
"futures-core",
"futures-intrusive",
+ "futures-io",
"futures-util",
"hashlink",
"hex",
- "hkdf",
- "hmac",
"indexmap",
- "itoa 1.0.6",
- "libc",
"log",
- "md-5",
"memchr",
+ "native-tls",
"once_cell",
"paste",
"percent-encoding",
- "rand",
"serde",
"serde_json",
- "sha1",
"sha2",
"smallvec",
"sqlformat",
- "sqlx-rt",
- "stringprep",
"thiserror",
+ "tokio",
"tokio-stream",
+ "tracing",
"url",
- "whoami",
]
[[package]]
name = "sqlx-macros"
-version = "0.6.3"
+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 = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9"
+checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8"
dependencies = [
"dotenvy",
"either",
@@ -2327,21 +2654,119 @@ dependencies = [
"serde_json",
"sha2",
"sqlx-core",
- "sqlx-rt",
+ "sqlx-mysql",
+ "sqlx-postgres",
+ "sqlx-sqlite",
"syn 1.0.109",
+ "tempfile",
+ "tokio",
"url",
]
[[package]]
-name = "sqlx-rt"
-version = "0.6.3"
+name = "sqlx-mysql"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024"
+checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418"
dependencies = [
- "native-tls",
+ "atoi",
+ "base64 0.21.7",
+ "bitflags 2.4.1",
+ "byteorder",
+ "bytes",
+ "chrono",
+ "crc",
+ "digest",
+ "dotenvy",
+ "either",
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-util",
+ "generic-array",
+ "hex",
+ "hkdf",
+ "hmac",
+ "itoa",
+ "log",
+ "md-5",
+ "memchr",
"once_cell",
- "tokio",
- "tokio-native-tls",
+ "percent-encoding",
+ "rand",
+ "rsa",
+ "serde",
+ "sha1",
+ "sha2",
+ "smallvec",
+ "sqlx-core",
+ "stringprep",
+ "thiserror",
+ "tracing",
+ "whoami",
+]
+
+[[package]]
+name = "sqlx-postgres"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e"
+dependencies = [
+ "atoi",
+ "base64 0.21.7",
+ "bitflags 2.4.1",
+ "byteorder",
+ "chrono",
+ "crc",
+ "dotenvy",
+ "etcetera",
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-util",
+ "hex",
+ "hkdf",
+ "hmac",
+ "home",
+ "itoa",
+ "log",
+ "md-5",
+ "memchr",
+ "once_cell",
+ "rand",
+ "serde",
+ "serde_json",
+ "sha2",
+ "smallvec",
+ "sqlx-core",
+ "stringprep",
+ "thiserror",
+ "tracing",
+ "whoami",
+]
+
+[[package]]
+name = "sqlx-sqlite"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa"
+dependencies = [
+ "atoi",
+ "chrono",
+ "flume",
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-intrusive",
+ "futures-util",
+ "libsqlite3-sys",
+ "log",
+ "percent-encoding",
+ "serde",
+ "sqlx-core",
+ "tracing",
+ "url",
+ "urlencoding",
]
[[package]]
@@ -2355,28 +2780,29 @@ dependencies = [
[[package]]
name = "state"
-version = "0.5.3"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b"
+checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8"
dependencies = [
"loom",
]
[[package]]
name = "stringprep"
-version = "0.1.2"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1"
+checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1"
dependencies = [
"unicode-bidi",
"unicode-normalization",
+ "unicode-properties",
]
[[package]]
name = "subtle"
-version = "2.4.1"
+version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
@@ -2391,9 +2817,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.15"
+version = "2.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
+checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
dependencies = [
"proc-macro2",
"quote",
@@ -2401,52 +2827,69 @@ dependencies = [
]
[[package]]
-name = "tempfile"
-version = "3.5.0"
+name = "sync_wrapper"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
+checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
+
+[[package]]
+name = "system-configuration"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
- "cfg-if",
- "fastrand",
- "redox_syscall 0.3.5",
- "rustix",
- "windows-sys 0.45.0",
+ "bitflags 1.3.2",
+ "core-foundation",
+ "system-configuration-sys",
]
[[package]]
-name = "termcolor"
-version = "1.2.0"
+name = "system-configuration-sys"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
+checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [
- "winapi-util",
+ "cfg-if",
+ "fastrand",
+ "rustix",
+ "windows-sys 0.52.0",
]
[[package]]
name = "thiserror"
-version = "1.0.40"
+version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
+checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.40"
+version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
+checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.58",
]
[[package]]
name = "thread_local"
-version = "1.1.7"
+version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
+checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
@@ -2454,21 +2897,14 @@ dependencies = [
[[package]]
name = "time"
-version = "0.1.43"
+version = "0.3.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
+checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "time"
-version = "0.3.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890"
-dependencies = [
- "itoa 1.0.6",
+ "deranged",
+ "itoa",
+ "num-conv",
+ "powerfmt",
"serde",
"time-core",
"time-macros",
@@ -2476,24 +2912,25 @@ dependencies = [
[[package]]
name = "time-core"
-version = "0.1.0"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
-version = "0.2.8"
+version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36"
+checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
dependencies = [
+ "num-conv",
"time-core",
]
[[package]]
name = "tinyvec"
-version = "1.6.0"
+version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82"
dependencies = [
"tinyvec_macros",
]
@@ -2506,11 +2943,11 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.28.0"
+version = "1.38.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f"
+checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
dependencies = [
- "autocfg",
+ "backtrace",
"bytes",
"libc",
"mio",
@@ -2524,13 +2961,13 @@ dependencies = [
[[package]]
name = "tokio-macros"
-version = "2.1.0"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
+checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.58",
]
[[package]]
@@ -2543,11 +2980,22 @@ dependencies = [
"tokio",
]
+[[package]]
+name = "tokio-rustls"
+version = "0.26.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
+dependencies = [
+ "rustls",
+ "rustls-pki-types",
+ "tokio",
+]
+
[[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",
@@ -2556,27 +3004,72 @@ dependencies = [
[[package]]
name = "tokio-util"
-version = "0.7.8"
+version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
+checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio",
- "tracing",
]
[[package]]
name = "toml"
-version = "0.5.11"
+version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
+checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
dependencies = [
"serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
]
+[[package]]
+name = "toml_datetime"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.22.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38"
+dependencies = [
+ "indexmap",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "winnow",
+]
+
+[[package]]
+name = "tower"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "pin-project",
+ "pin-project-lite",
+ "tokio",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
+
[[package]]
name = "tower-service"
version = "0.3.2"
@@ -2585,11 +3078,11 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "tracing"
-version = "0.1.37"
+version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
+checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
- "cfg-if",
+ "log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
@@ -2597,20 +3090,20 @@ dependencies = [
[[package]]
name = "tracing-attributes"
-version = "0.1.24"
+version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74"
+checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.58",
]
[[package]]
name = "tracing-core"
-version = "0.1.30"
+version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
+checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
"valuable",
@@ -2618,20 +3111,20 @@ dependencies = [
[[package]]
name = "tracing-log"
-version = "0.1.3"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
+checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
- "lazy_static",
"log",
+ "once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
-version = "0.3.17"
+version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
+checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"matchers",
"nu-ansi-term",
@@ -2647,30 +3140,30 @@ dependencies = [
[[package]]
name = "try-lock"
-version = "0.2.4"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
+checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "typenum"
-version = "1.16.0"
+version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "ubyte"
-version = "0.10.3"
+version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c81f0dae7d286ad0d9366d7679a77934cfc3cf3a8d67e82669794412b2368fe6"
+checksum = "f720def6ce1ee2fc44d40ac9ed6d3a59c361c80a75a7aa8e75bb9baed31cf2ea"
dependencies = [
"serde",
]
[[package]]
name = "uncased"
-version = "0.9.7"
+version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622"
+checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697"
dependencies = [
"serde",
"version_check",
@@ -2678,36 +3171,36 @@ dependencies = [
[[package]]
name = "unicode-bidi"
-version = "0.3.13"
+version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
+checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
[[package]]
name = "unicode-ident"
-version = "1.0.8"
+version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-normalization"
-version = "0.1.22"
+version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
dependencies = [
"tinyvec",
]
[[package]]
-name = "unicode-segmentation"
-version = "1.10.1"
+name = "unicode-properties"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
+checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291"
[[package]]
-name = "unicode-width"
-version = "0.1.10"
+name = "unicode-segmentation"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]]
name = "unicode-xid"
@@ -2721,29 +3214,51 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
+[[package]]
+name = "unsafe-libyaml"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
+
[[package]]
name = "untrusted"
-version = "0.7.1"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
-version = "2.3.1"
+version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
+checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
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 = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+[[package]]
+name = "variant_partial_eq"
+version = "0.0.0"
+source = "git+https://github.com/stadust/variant-partial-eq#bdccf434b502b36b77f23cc6d6411f580828c08a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.58",
+]
+
[[package]]
name = "vcpkg"
version = "0.2.15"
@@ -2758,31 +3273,30 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "want"
-version = "0.3.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
dependencies = [
- "log",
"try-lock",
]
[[package]]
name = "wasi"
-version = "0.10.2+wasi-snapshot-preview1"
+version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
-name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
+name = "wasite"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
[[package]]
name = "wasm-bindgen"
-version = "0.2.84"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
+checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@@ -2790,24 +3304,24 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.84"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
+checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
- "syn 1.0.109",
+ "syn 2.0.58",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.34"
+version = "0.4.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
+checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0"
dependencies = [
"cfg-if",
"js-sys",
@@ -2817,9 +3331,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.84"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
+checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -2827,28 +3341,28 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.84"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
+checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
- "syn 1.0.109",
+ "syn 2.0.58",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.84"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
+checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "web-sys"
-version = "0.3.61"
+version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
+checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -2856,12 +3370,12 @@ dependencies = [
[[package]]
name = "whoami"
-version = "1.4.0"
+version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c70234412ca409cc04e864e89523cb0fc37f5e1344ebed5a3ebf4192b6b9f68"
+checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9"
dependencies = [
- "wasm-bindgen",
- "web-sys",
+ "redox_syscall 0.4.1",
+ "wasite",
]
[[package]]
@@ -2880,15 +3394,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-[[package]]
-name = "winapi-util"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
-dependencies = [
- "winapi",
-]
-
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
@@ -2901,176 +3406,200 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [
- "windows-targets 0.48.0",
+ "windows-targets 0.48.5",
]
[[package]]
-name = "windows-sys"
-version = "0.42.0"
+name = "windows-core"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
+ "windows-targets 0.52.0",
]
[[package]]
name = "windows-sys"
-version = "0.45.0"
+version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
- "windows-targets 0.42.2",
+ "windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
-version = "0.48.0"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
- "windows-targets 0.48.0",
+ "windows-targets 0.52.0",
]
[[package]]
name = "windows-targets"
-version = "0.42.2"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
+ "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.48.0"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
dependencies = [
- "windows_aarch64_gnullvm 0.48.0",
- "windows_aarch64_msvc 0.48.0",
- "windows_i686_gnu 0.48.0",
- "windows_i686_msvc 0.48.0",
- "windows_x86_64_gnu 0.48.0",
- "windows_x86_64_gnullvm 0.48.0",
- "windows_x86_64_msvc 0.48.0",
+ "windows_aarch64_gnullvm 0.52.0",
+ "windows_aarch64_msvc 0.52.0",
+ "windows_i686_gnu 0.52.0",
+ "windows_i686_msvc 0.52.0",
+ "windows_x86_64_gnu 0.52.0",
+ "windows_x86_64_gnullvm 0.52.0",
+ "windows_x86_64_msvc 0.52.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.42.2"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.48.0"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
+checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]]
name = "windows_aarch64_msvc"
-version = "0.42.2"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
-version = "0.48.0"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
+checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]]
name = "windows_i686_gnu"
-version = "0.42.2"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
-version = "0.48.0"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
+checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]]
name = "windows_i686_msvc"
-version = "0.42.2"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
-version = "0.48.0"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
+checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.42.2"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.48.0"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.42.2"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.48.0"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.42.2"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.48.0"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
-name = "winreg"
-version = "0.10.1"
+name = "winnow"
+version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
+checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1"
dependencies = [
- "winapi",
+ "memchr",
]
[[package]]
-name = "yaml-rust"
-version = "0.4.5"
+name = "winreg"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
+checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
dependencies = [
- "linked-hash-map",
+ "cfg-if",
+ "windows-sys 0.48.0",
]
[[package]]
name = "yansi"
-version = "0.5.1"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
+dependencies = [
+ "is-terminal",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.7.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.7.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.58",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
+checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
diff --git a/Cargo.toml b/Cargo.toml
index 44bdf5586..36cae776e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,6 +11,17 @@ members = [
"pointercrate-user-pages",
"pointercrate-integrate",
- # Create only containing integration tests
- "pointercrate-test"
-]
\ No newline at end of file
+ # Crate only containing integration tests
+ "pointercrate-test",
+
+ # Crate containing an example setup for a custom list
+ "pointercrate-example"
+]
+resolver = "2"
+
+[workspace.package]
+authors = ["stadust"]
+description = "Libraries for creating pointercrate-like demonlist websites"
+homepage = "https://pointercrate.com"
+edition = "2021"
+repository = "https://github.com/stadust/pointercrate"
\ No newline at end of file
diff --git a/README.md b/README.md
index c91aee36c..1e89755d7 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,174 @@
# Pointercrate
-As of March 2nd 2019 this is the official repository for pointercrate. It does not contain all the code required to run a local copy of pointercrate, however, as parts of the code remain private. In particular, this repository does not contain
+As of March 2nd 2019 this is the official repository for pointercrate. It contains the main parts of the backend code of [pointercrate.com](https://pointercrate.com). Specifically, it contains all the code for the demonlist and user area pages seen on pointercrate, but does not contain the code for the home page, API documentation and demonlist guidelines. It instead aims to be a framework that can be used as a stepping stone for creating custom pointercrate-like websites. The reason the home page and similar are not open source is that we have experienced people not customizing these parts when hosting their own lists, resulting in these websites displaying pointercrate branding despite not being associated with pointercrate. As a compromise, this repository instead contains code for an example binary that shows how to use the various library components in this repository to create a demonlist website. See the [getting started section](#getting-started) below for more information.
-- a `main.rs` file stitching together the code in the different libraries
-- various assets such as graphics used by pointercrate
-- code specific to pointercrate that has no place on custom copies of pointercrate (such as the pointercrate homepage)
+Note that exclusion of pointercrate-specific code from this repository is still a work-in-progress. For example, a lot of SEO related metadata included in the pages served for the demonlist still hardcodes the pointercrate.com URL. If you end up using this repository as a base for your own demonlist, we ask you to please update these.
-This has both upsides and downsides. Since you'll have to write those components yourself, it will be very complicated to run custom pointercrate copies (especially since we do not actually support such endeavours). However, there are various advantages:
+## Getting Started (Linux)
-- No code in this repository explicitly references pointercrate. Everything from the logo in the navigation bar to the site metadata in the headers is configurable. This means I wont have to shout at you 7 times for failing to remove references to pointercrate on your website
-- Each component is as independent as possible. For instance, you could run a pointercrate copy that does not use the `pointercrate-demonlist*` libraries and it would work just fine.
+The goal of this section is to compile and successful run the `pointercrate-example` binary target to set up a locally running demonlist-clone.
+
+We assume that you have a rust toolchain set up. If not, install one using [`rustup`](https://rustup.rs).
+
+### Database Setup
+
+Pointercrate uses [`postgresql`](https://www.postgresql.org/) as its database. This guide assumes that you have a local postgres server running, and created both a role (user) and database for use with pointercrate. For simplicity, name both of these `pointercrate` (e.g. `psql -U pointercrate pointercrate` should drop you into a database prompt).
+
+To connect to the postgres database, pointercrate uses [`sqlx`](https://github.com/launchbadge/sqlx). This means that even to just compile pointercrate, a database with pointercrate's database schema needs to be available (as sqlx will validate SQL queries both syntactically and semantically at compile-time by sending them to a database server for validation). For this, the `DATABASE_URL` environment variable needs to be set to a [libpq connection string](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING), e.g.
+
+```bash
+# If you created the pointercrate database and the pointercrate role (without password but with login permissions),
+# the connection string will be
+export DATABASE_URL=postgresql://pointercrate@localhost/pointercrate
+```
+
+To set up a database with all the tables used by pointercrate, this repository contains a set of migrations that can be applied to an empty database (in the [`migrations`](migrations) directory). To apply the migrations, run
+
+```bash
+cargo install sqlx-cli
+cargo sqlx migrate run
+```
+
+### Pointercrate Configuration
+
+Pointercrate is configured via environment variables, which it reads from a `.env` file in the working directory. Additionally, it expects a secret for signing access tokens to be available in a `.secret` file. An example `.env` can be found under `pointercrate-example`. Copy this to the repository root and create the a dummy `.secret` file (for debug purposes only!) via
+
+```bash
+cp pointercrate-example/.env.sample .env
+echo "insecure-do-not-use-in-prod" > .secret
+```
+
+Then, open `.env` and fill out all the fields that do not have default values (e.g. `DATABASE_URL`).
+
+### Running `pointercrate-example`
+
+At this point, you should be able to run `pointercrate-example` via
+
+```bash
+cargo run -p pointercrate-example
+```
+
+If everything is set up correctly, you should see `rocket`'s development server start up with output as follows:
+
+
+
+```
+ Finished dev [unoptimized + debuginfo] target(s) in 0.16s
+ Running `target/debug/pointercrate-example`
+🔧 Configured for debug.
+ >> address: 127.0.0.1
+ >> port: 1971
+ >> workers: 12
+ >> max blocking threads: 512
+ >> ident: Rocket
+ >> IP header: X-Real-IP
+ >> limits: bytes = 8KiB, data-form = 2MiB, file = 1MiB, form = 32KiB, json = 1MiB, msgpack = 1MiB, string = 8KiB
+ >> temp dir: /tmp
+ >> http/2: true
+ >> keep-alive: 5s
+ >> tls: disabled
+ >> shutdown: ctrlc = true, force = true, signals = [SIGTERM], grace = 2s, mercy = 3s
+ >> log level: normal
+ >> cli colors: true
+📬 Routes:
+ >> (home) GET /
+ >> (login_page) GET /login
+ >> (login) POST /login
+ >> (account_page) GET /account
+ >> (register) POST /register
+ >> (overview) GET /demonlist/?&
+ >> (stats_viewer_redirect) GET /demonlist/?statsviewer=true
+ >> (demon_page) GET /demonlist/
+ >> (stats_viewer) GET /demonlist/statsviewer
+ >> (nation_stats_viewer) GET /demonlist/statsviewer/nations
+ >> (demon_permalink) GET /demonlist/permalink/
+ >> (heatmap_css) GET /demonlist/statsviewer/heatmap.css
+ >> (FileServer: pointercrate-core-pages/static) GET /static/core/ [10]
+ >> (FileServer: pointercrate-user-pages/static) GET /static/user/ [10]
+ >> (FileServer: pointercrate-demonlist-pages/static) GET /static/demonlist/ [10]
+ >> (login) POST /api/v1/auth/
+ >> (get_me) GET /api/v1/auth/me
+ >> (patch_me) PATCH /api/v1/auth/me
+ >> (delete_me) DELETE /api/v1/auth/me
+ >> (register) POST /api/v1/auth/register
+ >> (invalidate) POST /api/v1/auth/invalidate
+ >> (verify_email) GET /api/v1/auth/verify_email?
+ >> (paginate) GET /api/v1/users/
+ >> (get_user) GET /api/v1/users/
+ >> (patch_user) PATCH /api/v1/users/
+ >> (delete_user) DELETE /api/v1/users/
+ >> (paginate) GET /api/v2/demons/
+ >> (post) POST /api/v2/demons/
+ >> (paginate_listed) GET /api/v2/demons/listed
+ >> (get) GET /api/v2/demons/
+ >> (patch) PATCH /api/v2/demons/
+ >> (audit) GET /api/v2/demons//audit
+ >> (post_creator) POST /api/v2/demons//creators
+ >> (movement_log) GET /api/v2/demons//audit/movement
+ >> (delete_creator) DELETE /api/v2/demons//creators/
+ >> (paginate) GET /api/v1/records/
+ >> (unauthed_pagination) GET /api/v1/records/
+ >> (submit) POST /api/v1/records/
+ >> (paginate) GET /api/v1/players/
+ >> (paginate_claims) GET /api/v1/players/claims
+ >> (ranking) GET /api/v1/players/ranking
+ >> (delete) DELETE /api/v1/records/
+ >> (get) GET /api/v1/records/
+ >> (patch) PATCH /api/v1/records/
+ >> (get) GET /api/v1/players/
+ >> (patch) PATCH /api/v1/players/
+ >> (get_notes) GET /api/v1/records//notes
+ >> (add_note) POST /api/v1/records//notes
+ >> (audit) GET /api/v1/records//audit
+ >> (put_claim) PUT /api/v1/players//claims
+ >> (geolocate_nationality) POST /api/v1/players//geolocate
+ >> (delete_note) DELETE /api/v1/records//notes/
+ >> (patch_note) PATCH /api/v1/records//notes/
+ >> (patch_claim) PATCH /api/v1/players//claims/
+ >> (delete_claim) DELETE /api/v1/players//claims/
+ >> (paginate) GET /api/v1/submitters/
+ >> (get) GET /api/v1/submitters/
+ >> (patch) PATCH /api/v1/submitters/
+ >> (ranking) GET /api/v1/nationalities/ranking
+ >> (nation) GET /api/v1/nationalities/
+ >> (subdivisions) GET /api/v1/nationalities//subdivisions
+ >> (list_information) GET /api/v1/list_information/
+🥅 Catchers:
+ >> (catch_404) 404
+📡 Fairings:
+ >> Shield (liftoff, response, singleton)
+ >> Maintenance (ignite, request)
+🛡️ Shield:
+ >> X-Content-Type-Options: nosniff
+ >> Permissions-Policy: interest-cohort=()
+ >> X-Frame-Options: SAMEORIGIN
+🚀 Rocket has launched from http://127.0.0.1:1971
+```
+
+
+
+The last line will tell you the URL for accessing your local pointercrate instance (in this case, `127.0.0.1:1971`, since my `ROCKET_PORT` environment variable was set to `1971`)!
+
+### Next Steps
+
+If you want to use pointercrate as a framework for setting up your own demonlist-like website, check out the actual sample code contained in [`pointercrate-example/src/main.rs`](pointercrate-example/src/main.rs). As a first step, you will probably want to replace all the placeholder strings (such as replacing `""` with your domain). You probably also want to the "Hello World" home page with a proper home page of your own, and familiarize yourself with the demonlist administration interface in the "User Area". For the latter, you will need to create an account (via the usual registration routine), and then grant yourself (list) administrator permissions via the postgres shell:
+
+```
+$ psql -U pointercrate pointercrate
+psql (16.1)
+Type "help" for help.
+
+pointercrate=# -- assuming the user you just created was assigned member_id 1:
+pointercrate=# UPDATE members SET permissions = '0100000000001000'::BIT(16) WHERE member_id = 1;
+```
+
+After reloading the user area, you should be able to see all administration tabs (both for website management and demonlist management).
+
+## Running Integration Tests
+
+Pointercrate's test suite can be executed via `cargo test` in the repository root. As running the example binary, it requires access to a database with the pointercrate scheme loaded via the `DATABASE_URL` environment variable. You should use a separate database for tests (say, `pointercrate_test`), as during setup and tear-down of each individual test, this database is dropped and recreated from scratch.
+
+Integration tests are also ran as part of the CI on each pull request.
## Special thanks
diff --git a/migrations/20240328150521_simplify_gd_integration.down.sql b/migrations/20240328150521_simplify_gd_integration.down.sql
new file mode 100644
index 000000000..93479c830
--- /dev/null
+++ b/migrations/20240328150521_simplify_gd_integration.down.sql
@@ -0,0 +1,42 @@
+-- Add down migration script here
+
+CREATE TABLE gj_creator_meta (
+ user_id bigint PRIMARY KEY NOT NULL, -- No REFERENCES creator(user_id) as we also have to keep track of _missing_ entries here!
+ cached_at timestamp without time zone NOT NULL,
+ absent boolean DEFAULT false NOT NULL
+);
+
+CREATE TABLE gj_level_meta (
+ level_id bigint PRIMARY KEY NOT NULL,
+ cached_at timestamp without time zone NOT NULL,
+ absent boolean DEFAULT false NOT NULL
+);
+
+CREATE TABLE gj_level_request_results (
+ level_id bigint NOT NULL,
+ request_hash bigint NOT NULL
+);
+
+CREATE TABLE gj_level_request_meta (
+ request_hash bigint PRIMARY KEY NOT NULL,
+ cached_at timestamp without time zone NOT NULL,
+ absent boolean DEFAULT false NOT NULL
+);
+
+
+CREATE TABLE gj_level_data_meta (
+ level_id bigint PRIMARY KEY NOT NULL,
+ cached_at timestamp without time zone NOT NULL,
+ absent boolean DEFAULT false NOT NULL
+);
+
+CREATE TABLE gj_newgrounds_song_meta (
+ song_id bigint PRIMARY KEY NOT NULL,
+ cached_at timestamp without time zone NOT NULL,
+ absent boolean DEFAULT false NOT NULL
+);
+
+
+CREATE TABLE download_lock(
+ level_id bigint not null
+);
\ No newline at end of file
diff --git a/migrations/20240328150521_simplify_gd_integration.up.sql b/migrations/20240328150521_simplify_gd_integration.up.sql
new file mode 100644
index 000000000..f220f7492
--- /dev/null
+++ b/migrations/20240328150521_simplify_gd_integration.up.sql
@@ -0,0 +1,9 @@
+-- Add up migration script here
+
+DROP TABLE download_lock;
+DROP TABLE gj_newgrounds_song_meta;
+DROP TABLE gj_level_data_meta;
+DROP TABLE gj_level_request_meta;
+DROP TABLE gj_level_request_results;
+DROP TABLE gj_level_meta;
+DROP TABLE gj_creator_meta;
\ No newline at end of file
diff --git a/migrations/20240404084539_nationalityupdate_again.down.sql b/migrations/20240404084539_nationalityupdate_again.down.sql
new file mode 100644
index 000000000..814293862
--- /dev/null
+++ b/migrations/20240404084539_nationalityupdate_again.down.sql
@@ -0,0 +1,81 @@
+-- Add down migration script here
+DELETE FROM subdivisions;
+
+INSERT INTO subdivisions (iso_code, name, nation)
+VALUES
+ ('WA', 'Washington', 'US'),
+ ('MD', 'Maryland', 'US'),
+ ('WV', 'West Virginia', 'US'),
+ ('NY', 'New York', 'US'),
+ ('NJ', 'New Jersey', 'US'),
+ ('PA', 'Pennsylvania', 'US'),
+ ('VA', 'Virginia', 'US'),
+ ('KY', 'Kentucky', 'US'),
+ ('OH', 'Ohio', 'US'),
+ ('IN', 'Indiana', 'US'),
+ ('IL', 'Illinois', 'US'),
+ ('MI', 'Michigan', 'US'),
+ ('WI', 'Wisconsin', 'US'),
+ ('CT', 'Connecticut', 'US'),
+ ('RI', 'Rhode Island', 'US'),
+ ('VT', 'Vermont', 'US'),
+ ('NH', 'New Hampshire', 'US'),
+ ('MA', 'Massachusetts', 'US'),
+ ('ME', 'Maine', 'US'),
+ ('AL', 'Alabama', 'US'),
+ ('GA', 'Georgia', 'US'),
+ ('SC', 'South Carolina', 'US'),
+ ('FL', 'Florida', 'US'),
+ ('MS', 'Mississippi', 'US'),
+ ('TN', 'Tennessee', 'US'),
+ ('NC', 'North Carolina', 'US'),
+ ('TX', 'Texas', 'US'),
+ ('OK', 'Oklahoma', 'US'),
+ ('NM', 'New Mexico', 'US'),
+ ('NE', 'Nebraska', 'US'),
+ ('SD', 'South Dakota', 'US'),
+ ('KS', 'Kansas', 'US'),
+ ('CO', 'Colorado', 'US'),
+ ('ND', 'North Dakota', 'US'),
+ ('AR', 'Arkansas', 'US'),
+ ('MO', 'Missouri', 'US'),
+ ('LA', 'Louisiana', 'US'),
+ ('IA', 'Iowa', 'US'),
+ ('MN', 'Minnesota', 'US'),
+ ('AZ', 'Arizona', 'US'),
+ ('NV', 'Nevada', 'US'),
+ ('CA', 'California', 'US'),
+ ('UT', 'Utah', 'US'),
+ ('OR', 'Oregon', 'US'),
+ ('MT', 'Montana', 'US'),
+ ('ID', 'Idaho', 'US'),
+ ('WY', 'Wyoming', 'US'),
+ ('HI', 'Hawaii', 'US'),
+ ('AK', 'Alaska', 'US'),
+ ('DC', 'Washington, District of Columbia', 'US'),
+ ('DE', 'Delaware', 'US'),
+ ('MB', 'Manitoba', 'CA'),
+ ('NT', 'Northwest Territories', 'CA'),
+ ('NL', 'Newfoundland and Labrador', 'CA'),
+ ('NU', 'Nunavut', 'CA'),
+ ('QC', 'Quebec', 'CA'),
+ ('BC', 'British Columbia', 'CA'),
+ ('SK', 'Saskatchewan', 'CA'),
+ ('AB', 'Alberta', 'CA'),
+ ('ON', 'Ontario', 'CA'),
+ ('NB', 'New Brunswick', 'CA'),
+ ('NS', 'Nova Scotia', 'CA'),
+ ('PE', 'Prince Edward Island', 'CA'),
+ ('YT', 'Yukon', 'CA'),
+ ('SCT', 'Scotland', 'GB'),
+ ('WLS', 'Wales', 'GB'),
+ ('ENG', 'England', 'GB'),
+ ('NIR', 'Northern Ireland', 'GB'),
+ ('ACT', 'Australian Capital Territory', 'AU'),
+ ('TAS', 'Tasmania', 'AU'),
+ ('NT', 'Northern Territory', 'AU'),
+ ('WA', 'Western Australia', 'AU'),
+ ('QLD', 'Queensland', 'AU'),
+ ('NSW', 'New South Wales', 'AU'),
+ ('VIC', 'Victoria', 'AU'),
+ ('SA', 'South Australia', 'AU');
\ No newline at end of file
diff --git a/migrations/20240404084539_nationalityupdate_again.up.sql b/migrations/20240404084539_nationalityupdate_again.up.sql
new file mode 100644
index 000000000..627e29d8a
--- /dev/null
+++ b/migrations/20240404084539_nationalityupdate_again.up.sql
@@ -0,0 +1,428 @@
+-- Add up migration script here
+INSERT INTO subdivisions (iso_code, name, nation)
+VALUES
+ ('V', 'Provincia de Tierra del Fuego', 'AR'),
+ ('N', 'Provincia de Misiones', 'AR'),
+ ('W', 'Provincia de Corrientes', 'AR'),
+ ('E', 'Provincia de Entre Ríos', 'AR'),
+ ('Y', 'Provincia de Jujuy', 'AR'),
+ ('A', 'Provincia de Salta', 'AR'),
+ ('T', 'Provincia de Tucumán', 'AR'),
+ ('G', 'Provincia de Santiago del Estero', 'AR'),
+ ('K', 'Provincia de Catamarca', 'AR'),
+ ('J', 'Provincia de San Juan', 'AR'),
+ ('F', 'Provincia de La Rioja', 'AR'),
+ ('P', 'Provincia de Formosa', 'AR'),
+ ('H', 'Provincia del Chaco', 'AR'),
+ ('S', 'Provincia de Santa Fe', 'AR'),
+ ('X', 'Provincia de Córdoba', 'AR'),
+ ('D', 'Provincia de San Luis', 'AR'),
+ ('M', 'Provincia de Mendoza', 'AR'),
+ ('L', 'Provincia de La Pampa', 'AR'),
+ ('R', 'Provincia de Río Negro', 'AR'),
+ ('Q', 'Provincia de Neuquén', 'AR'),
+ ('B', 'Provincia de Buenos Aires', 'AR'),
+ ('C', 'Ciudad Autónoma de Buenos Aires', 'AR'),
+ ('U', 'Provincia del Chubut', 'AR'),
+ ('Z', 'Provincia de Santa Cruz', 'AR'),
+ ('DF', 'Distrito Federal', 'BR'),
+ ('GO', 'Goiás', 'BR'),
+ ('RR', 'Roraima', 'BR'),
+ ('AM', 'Amazonas', 'BR'),
+ ('RO', 'Rondônia', 'BR'),
+ ('AC', 'Acre', 'BR'),
+ ('TO', 'Tocantins', 'BR'),
+ ('AP', 'Amapá', 'BR'),
+ ('PA', 'Pará', 'BR'),
+ ('MT', 'Mato Grosso', 'BR'),
+ ('MS', 'Mato Grosso do Sul', 'BR'),
+ ('MA', 'Maranhão', 'BR'),
+ ('PI', 'Piauí', 'BR'),
+ ('CE', 'Ceará', 'BR'),
+ ('BA', 'Bahia', 'BR'),
+ ('RN', 'Rio Grande do Norte', 'BR'),
+ ('PB', 'Paraíba', 'BR'),
+ ('PE', 'Pernambuco', 'BR'),
+ ('AL', 'Alagoas', 'BR'),
+ ('SE', 'Sergipe', 'BR'),
+ ('MG', 'Minas Gerais', 'BR'),
+ ('PR', 'Paraná', 'BR'),
+ ('SC', 'Santa Catarina', 'BR'),
+ ('RS', 'Rio Grande do Sul', 'BR'),
+ ('ES', 'Espírito Santo', 'BR'),
+ ('RJ', 'Rio de Janeiro', 'BR'),
+ ('SP', 'São Paulo', 'BR'),
+ ('MA', 'Magallanes', 'CL'),
+ ('LL', 'Los Lagos', 'CL'),
+ ('AI', 'Aysén', 'CL'),
+ ('AR', 'Araucanía', 'CL'),
+ ('NB', 'Ñuble', 'CL'),
+ ('ML', 'Maule', 'CL'),
+ ('VS', 'Valparaíso', 'CL'),
+ ('RM', 'Región Metropolitana de Santiago', 'CL'),
+ ('AT', 'Atacama', 'CL'),
+ ('LR', 'Los Ríos', 'CL'),
+ ('BI', 'Biobío', 'CL'),
+ ('LI', 'O''Higgins', 'CL'),
+ ('CO', 'Coquimbo', 'CL'),
+ ('TA', 'Tarapacá', 'CL'),
+ ('AN', 'Antofagasta', 'CL'),
+ ('AP', 'Arica y Parinacota', 'CL'),
+ ('SAP', 'San Andrés y Providencia', 'CO'),
+ ('LAG', 'Departamento de La Guajira', 'CO'),
+ ('CES', 'Departamento del Cesar', 'CO'),
+ ('NSA', 'Norte de Santander', 'CO'),
+ ('BOY', 'Departamento de Boyacá', 'CO'),
+ ('CUN', 'Departamento de Cundinamarca', 'CO'),
+ ('ATL', 'Departamento del Atlántico', 'CO'),
+ ('MAG', 'Departamento del Magdalena', 'CO'),
+ ('BOL', 'Departamento de Bolívar', 'CO'),
+ ('CHO', 'Departamento del Chocó', 'CO'),
+ ('ANT', 'Departamento de Antioquia', 'CO'),
+ ('CAL', 'Departamento de Caldas', 'CO'),
+ ('RIS', 'Departamento del Risaralda', 'CO'),
+ ('QUI', 'Departamento del Quindío', 'CO'),
+ ('VAC', 'Departamento del Valle del Cauca', 'CO'),
+ ('SUC', 'Departamento de Sucre', 'CO'),
+ ('COR', 'Departamento de Córdoba', 'CO'),
+ ('SAN', 'Departamento de Santander', 'CO'),
+ ('TOL', 'Departamento del Tolima', 'CO'),
+ ('DC', 'Bogotá', 'CO'),
+ ('HUI', 'Departamento del Huila', 'CO'),
+ ('CAU', 'Departamento del Cauca', 'CO'),
+ ('ARA', 'Departamento de Arauca', 'CO'),
+ ('CAS', 'Departamento de Casanare', 'CO'),
+ ('VID', 'Departamento del Vichada', 'CO'),
+ ('MET', 'Departamento del Meta', 'CO'),
+ ('GUV', 'Departamento del Guaviare', 'CO'),
+ ('VAU', 'Departamento del Vaupés', 'CO'),
+ ('GUA', 'Departamento de Guainía', 'CO'),
+ ('CAQ', 'Departamento del Caquetá', 'CO'),
+ ('NAR', 'Departamento de Nariño', 'CO'),
+ ('PUT', 'Departamento del Putumayo', 'CO'),
+ ('AMA', 'Departamento del Amazonas', 'CO'),
+ ('LOR', 'Loreto', 'PE'),
+ ('AMA', 'Amazоnas', 'PE'),
+ ('LAL', 'La Libertad', 'PE'),
+ ('LIM', 'Lima', 'PE'),
+ ('ANC', 'Áncash', 'PE'),
+ ('HUC', 'Huánuco', 'PE'),
+ ('PAS', 'Pasco', 'PE'),
+ ('JUN', 'Junín', 'PE'),
+ ('LAM', 'Lambayeque', 'PE'),
+ ('TUM', 'Tumbes', 'PE'),
+ ('PIU', 'Piura', 'PE'),
+ ('SAM', 'San Martín', 'PE'),
+ ('CAJ', 'Cajamarca', 'PE'),
+ ('CUS', 'Cuzco', 'PE'),
+ ('PUN', 'Puno', 'PE'),
+ ('HUV', 'Huancavelica', 'PE'),
+ ('ICA', 'Ica', 'PE'),
+ ('ARE', 'Arequipa', 'PE'),
+ ('AYA', 'Ayacucho', 'PE'),
+ ('APU', 'Apurímac', 'PE'),
+ ('MOQ', 'Moquegua', 'PE'),
+ ('TAC', 'Tacna', 'PE'),
+ ('UCA', 'Ucayali', 'PE'),
+ ('MDD', 'Madre de Dios', 'PE'),
+ ('NAY', 'Nayarit', 'MX'),
+ ('BCS', 'Baja California Sur', 'MX'),
+ ('SON', 'Sonora', 'MX'),
+ ('BCN', 'Baja California', 'MX'),
+ ('SIN', 'Sinaloa', 'MX'),
+ ('CHH', 'Chihuahua', 'MX'),
+ ('DUR', 'Durango', 'MX'),
+ ('ZAC', 'Zacatecas', 'MX'),
+ ('COL', 'Colima', 'MX'),
+ ('VER', 'Veracruz', 'MX'),
+ ('TAB', 'Tabasco', 'MX'),
+ ('GUA', 'Guanajuato', 'MX'),
+ ('MIC', 'Michoacán', 'MX'),
+ ('QUE', 'Queretaro', 'MX'),
+ ('MEX', 'México', 'MX'),
+ ('HID', 'Hidalgo', 'MX'),
+ ('PUE', 'Puebla', 'MX'),
+ ('MOR', 'Morelos', 'MX'),
+ ('CMX', 'Ciudad de México', 'MX'),
+ ('OAX', 'Oaxaca', 'MX'),
+ ('CHP', 'Chiapas', 'MX'),
+ ('CAM', 'Campeche', 'MX'),
+ ('GRO', 'Guerrero', 'MX'),
+ ('YUC', 'Yucatán', 'MX'),
+ ('ROO', 'Quintana Roo', 'MX'),
+ ('COA', 'Coahuila', 'MX'),
+ ('TAM', 'Tamaulipas', 'MX'),
+ ('NLE', 'Nuevo León', 'MX'),
+ ('SLP', 'San Luis Potosí', 'MX'),
+ ('AGU', 'Aguascalientes', 'MX'),
+ ('JAL', 'Jalisco', 'MX'),
+ ('02', 'Województwo dolnośląskie', 'PL'),
+ ('04', 'Województwo kujawsko-pomorskie', 'PL'),
+ ('06', 'Województwo lubelskie', 'PL'),
+ ('08', 'Województwo lubuskie', 'PL'),
+ ('10', 'Województwo łódzkie', 'PL'),
+ ('12', 'Województwo małopolskie', 'PL'),
+ ('14', 'Województwo mazowieckie', 'PL'),
+ ('16', 'Województwo opolskie', 'PL'),
+ ('18', 'Województwo podkarpackie', 'PL'),
+ ('20', 'Województwo podlaskie', 'PL'),
+ ('22', 'Województwo pomorskie', 'PL'),
+ ('24', 'Województwo śląskie', 'PL'),
+ ('26', 'Województwo świętokrzyskie', 'PL'),
+ ('28', 'Województwo warmińsko-mazurskie', 'PL'),
+ ('30', 'Województwo wielkopolskie', 'PL'),
+ ('32', 'Województwo zachodniopomorskie', 'PL'),
+ ('05', 'Vinnytsia Oblast', 'UA'),
+ ('07', 'Volyn Oblast', 'UA'),
+ ('09', 'Luhansk Oblast', 'UA'),
+ ('12', 'Dnipropetrovsk Oblast', 'UA'),
+ ('14', 'Donetsk Oblast', 'UA'),
+ ('18', 'Zhytomyr Oblast', 'UA'),
+ ('21', 'Zakarpattia Oblast', 'UA'),
+ ('23', 'Zaporizhzhia Oblast', 'UA'),
+ ('26', 'Ivano-Frankivsk Oblast', 'UA'),
+ ('30', 'Kyiv', 'UA'),
+ ('32', 'Kyiv Oblast', 'UA'),
+ ('35', 'Kirovohrad Oblast', 'UA'),
+ ('40', 'Sevastopol', 'UA'),
+ ('43', 'Autonomous Republic of Crimea', 'UA'),
+ ('46', 'Lviv Oblast', 'UA'),
+ ('48', 'Mykolaiv Oblast', 'UA'),
+ ('51', 'Odesa Oblast', 'UA'),
+ ('53', 'Poltava Oblast', 'UA'),
+ ('56', 'Rivne Oblast', 'UA'),
+ ('59', 'Sumy Oblast', 'UA'),
+ ('61', 'Ternopil Oblast', 'UA'),
+ ('63', 'Kharkiv Oblast', 'UA'),
+ ('65', 'Kherson Oblast', 'UA'),
+ ('68', 'Khmelnytskyi Oblast', 'UA'),
+ ('71', 'Cherkasy Oblast', 'UA'),
+ ('74', 'Chernihiv Oblast', 'UA'),
+ ('77', 'Chernivtsi Oblast', 'UA'),
+ ('01', 'Østfold', 'NO'),
+ ('02', 'Akershus', 'NO'),
+ ('03', 'Oslo', 'NO'),
+ ('06', 'Buskerud', 'NO'),
+ ('07', 'Vestfold', 'NO'),
+ ('08', 'Telemark', 'NO'),
+ ('11', 'Rogaland', 'NO'),
+ ('15', 'Møre og Romsdal', 'NO'),
+ ('18', 'Nordland', 'NO'),
+ ('19', 'Troms', 'NO'),
+ ('20', 'Finnmark', 'NO'),
+ ('34', 'Innlandet', 'NO'),
+ ('42', 'Agder', 'NO'),
+ ('46', 'Vestland', 'NO'),
+ ('50', 'Trøndelag', 'NO'),
+ ('SJM', 'Svalbard og Jan Mayen', 'NO'),
+ ('01', 'Ahvenanmaa', 'FI'),
+ ('02', 'Etelä-Karjala', 'FI'),
+ ('03', 'Etelä-Pohjanmaa', 'FI'),
+ ('04', 'Etelä-Savo', 'FI'),
+ ('05', 'Kainuu', 'FI'),
+ ('06', 'Kanta-Häme', 'FI'),
+ ('07', 'Keski-Pohjanmaa', 'FI'),
+ ('08', 'Keski-Suomi', 'FI'),
+ ('09', 'Kymenlaakso', 'FI'),
+ ('10', 'Lappi', 'FI'),
+ ('11', 'Pirkanmaa', 'FI'),
+ ('12', 'Pohjanmaa', 'FI'),
+ ('13', 'Pohjois-Karjala', 'FI'),
+ ('14', 'Pohjois-Pohjanmaa', 'FI'),
+ ('15', 'Pohjois-Savo', 'FI'),
+ ('16', 'Päijät-Häme', 'FI'),
+ ('17', 'Satakunta', 'FI'),
+ ('18', 'Uusimaa', 'FI'),
+ ('19', 'Varsinais-Suomi', 'FI'),
+ ('OV', 'Overijssel', 'NL'),
+ ('GR', 'Groningen', 'NL'),
+ ('FR', 'Friesland', 'NL'),
+ ('FL', 'Flevoland', 'NL'),
+ ('NH', 'Noord-Holland', 'NL'),
+ ('UT', 'Utrecht', 'NL'),
+ ('NB', 'Noord-Brabant', 'NL'),
+ ('ZE', 'Zeeland', 'NL'),
+ ('LI', 'Limburg', 'NL'),
+ ('GE', 'Gelderland', 'NL'),
+ ('DR', 'Drenthe', 'NL'),
+ ('ZH', 'Zuid-Holland', 'NL'),
+ ('BE', 'Berlin', 'DE'),
+ ('HB', 'Bremen', 'DE'),
+ ('SL', 'Saarland', 'DE'),
+ ('NW', 'Nordrhein-Westfalen', 'DE'),
+ ('RP', 'Rheinland-Pfalz', 'DE'),
+ ('BW', 'Baden-Württemberg', 'DE'),
+ ('NI', 'Niedersachsen', 'DE'),
+ ('HE', 'Hessen', 'DE'),
+ ('BY', 'Bayern', 'DE'),
+ ('MV', 'Mecklenburg-Vorpommern', 'DE'),
+ ('HH', 'Hamburg', 'DE'),
+ ('ST', 'Sachsen-Anhalt', 'DE'),
+ ('SH', 'Schleswig-Holstein', 'DE'),
+ ('SN', 'Sachsen', 'DE'),
+ ('TH', 'Thüringen', 'DE'),
+ ('BB', 'Brandenburg', 'DE'),
+ ('GF', 'French Guiana', 'FR'),
+ ('TF', 'French Southern and Antarctic Lands', 'FR'),
+ ('GP', 'Guadeloupe', 'FR'),
+ ('MQ', 'Martinique', 'FR'),
+ ('YT', 'Mayotte', 'FR'),
+ ('RE', 'La Réunion', 'FR'),
+ ('OCC', 'Occitanie', 'FR'),
+ ('PAC', 'Provence-Alpes-Côte d''Azur', 'FR'),
+ ('HDF', 'Hauts-de-France', 'FR'),
+ ('IDF', 'Île-de-France', 'FR'),
+ ('NOR', 'Normandie', 'FR'),
+ ('GES', 'Grand Est', 'FR'),
+ ('PDL', 'Pays de la Loire', 'FR'),
+ ('BRE', 'Bretagne', 'FR'),
+ ('BFC', 'Bourgogne-Franche-Comté', 'FR'),
+ ('CVL', 'Centre-Val de Loire', 'FR'),
+ ('ARA', 'Auvergne-Rhône-Alpes', 'FR'),
+ ('NAQ', 'Nouvelle-Aquitaine', 'FR'),
+ ('20R', 'Corse', 'FR'),
+ ('PM', 'Saint-Pierre-et-Miquelon', 'FR'),
+ ('BL', 'Saint-Barthélemy', 'FR'),
+ ('MF', 'Saint-Martin', 'FR'),
+ ('NC', 'Nouvelle-Calédonie', 'FR'),
+ ('WF', 'Wallis-et-Futuna', 'FR'),
+ ('PF', 'Polynésie Française', 'FR'),
+ ('21', 'Piemonte', 'IT'),
+ ('23', 'Valle d''Aosta', 'IT'),
+ ('25', 'Lombardia', 'IT'),
+ ('32', 'Trentino-Alto Adige', 'IT'),
+ ('34', 'Veneto', 'IT'),
+ ('36', 'Friuli-Venezia Giulia', 'IT'),
+ ('42', 'Liguria', 'IT'),
+ ('45', 'Emilia-Romagna', 'IT'),
+ ('52', 'Toscana', 'IT'),
+ ('55', 'Umbria', 'IT'),
+ ('57', 'Marche', 'IT'),
+ ('62', 'Lazio', 'IT'),
+ ('65', 'Abruzzo', 'IT'),
+ ('67', 'Molise', 'IT'),
+ ('72', 'Campania', 'IT'),
+ ('75', 'Puglia', 'IT'),
+ ('77', 'Basilicata', 'IT'),
+ ('78', 'Calabria', 'IT'),
+ ('82', 'Sicilia', 'IT'),
+ ('88', 'Sardegna', 'IT'),
+ ('ML', 'Melilla', 'ES'),
+ ('CE', 'Ceuta', 'ES'),
+ ('CL', 'Castilla y León', 'ES'),
+ ('PV', 'País Vasco', 'ES'),
+ ('IB', 'Islas Baleares', 'ES'),
+ ('CN', 'Canarias', 'ES'),
+ ('CT', 'Cataluña', 'ES'),
+ ('VC', 'Comunidad Valenciana', 'ES'),
+ ('MC', 'Región de Murcia', 'ES'),
+ ('AN', 'Andalucía', 'ES'),
+ ('CM', 'Castilla–La Mancha', 'ES'),
+ ('EX', 'Extremadura', 'ES'),
+ ('AR', 'Aragón', 'ES'),
+ ('MD', 'Comunidad de Madrid', 'ES'),
+ ('NA', 'Navarra', 'ES'),
+ ('RI', 'La Rioja', 'ES'),
+ ('GA', 'Galicia', 'ES'),
+ ('AS', 'Asturias', 'ES'),
+ ('CB', 'Cantabria', 'ES'),
+ ('MOW', 'Moscow', 'RU'),
+ ('SMO', 'Smolensk Oblast', 'RU'),
+ ('TUL', 'Tula Oblast', 'RU'),
+ ('LIP', 'Lipetsk Oblast', 'RU'),
+ ('KRS', 'Kursk Oblast', 'RU'),
+ ('VOR', 'Voronezh Oblast', 'RU'),
+ ('MUR', 'Murmansk Oblast', 'RU'),
+ ('NEN', 'Nenets Autonomous Okrug', 'RU'),
+ ('ARK', 'Arkhangelsk Oblast', 'RU'),
+ ('YAN', 'Yamalo-Nenets Autonomous Okrug', 'RU'),
+ ('KHM', 'Khanty-Mansi Autonomous Okrug', 'RU'),
+ ('TYU', 'Tyumen Oblast', 'RU'),
+ ('TOM', 'Tomsk Oblast', 'RU'),
+ ('OMS', 'Omsk Oblast', 'RU'),
+ ('NVS', 'Novosibirsk Oblast', 'RU'),
+ ('ALT', 'Altai Krai', 'RU'),
+ ('AL', 'Altai, Republic of', 'RU'),
+ ('KEM', 'Kemerovo Oblast', 'RU'),
+ ('IRK', 'Irkutsk Oblast', 'RU'),
+ ('TY', 'Tuva, Republic of', 'RU'),
+ ('KK', 'Khakassia, Republic of', 'RU'),
+ ('ZAB', 'Zabaykalsky Krai', 'RU'),
+ ('BU', 'Buryatia, Republic of', 'RU'),
+ ('KYA', 'Krasnoyarsk Krai', 'RU'),
+ ('SAK', 'Sakhalin Oblast', 'RU'),
+ ('KAM', 'Kamchatka Krai', 'RU'),
+ ('CHU', 'Chukotka Autonomous Okrug', 'RU'),
+ ('YEV', 'Jewish Autonomous Oblast', 'RU'),
+ ('MAG', 'Magadan Oblast', 'RU'),
+ ('PRI', 'Primorsky Krai', 'RU'),
+ ('AMU', 'Amur Oblast', 'RU'),
+ ('SA', 'Sakha, Republic of', 'RU'),
+ ('KHA', 'Khabarovsk Krai', 'RU'),
+ ('SVE', 'Sverdlovsk Oblast', 'RU'),
+ ('CHE', 'Chelyabinsk Oblast', 'RU'),
+ ('KGN', 'Kurgan Oblast', 'RU'),
+ ('KR', 'Karelia, Republic of', 'RU'),
+ ('LEN', 'Leningrad Oblast', 'RU'),
+ ('NGR', 'Novgorod Oblast', 'RU'),
+ ('YAR', 'Yaroslavl Oblast', 'RU'),
+ ('IVA', 'Ivanovo Oblast', 'RU'),
+ ('KO', 'Komi, Republic of', 'RU'),
+ ('PER', 'Perm Krai', 'RU'),
+ ('BA', 'Bashkortostan, Republic of', 'RU'),
+ ('ORE', 'Orenburg Oblast', 'RU'),
+ ('KIR', 'Kirov Oblast', 'RU'),
+ ('CU', 'Chuvashia, Republic of', 'RU'),
+ ('MO', 'Mordovia, Republic of', 'RU'),
+ ('SAM', 'Samara Oblast', 'RU'),
+ ('SAR', 'Saratov Oblast', 'RU'),
+ ('ROS', 'Rostov Oblast', 'RU'),
+ ('KL', 'Kalmykia, Republic of', 'RU'),
+ ('STA', 'Stavropol Krai', 'RU'),
+ ('KLU', 'Kaluga Oblast', 'RU'),
+ ('BRY', 'Bryansk Oblast', 'RU'),
+ ('ORL', 'Oryol Oblast', 'RU'),
+ ('AD', 'Adygea, Republic of', 'RU'),
+ ('TAM', 'Tambov Oblast', 'RU'),
+ ('BEL', 'Belgorod Oblast', 'RU'),
+ ('VLG', 'Vologda Oblast', 'RU'),
+ ('SPE', 'Saint Petersburg', 'RU'),
+ ('PSK', 'Pskov Oblast', 'RU'),
+ ('TVE', 'Tver Oblast', 'RU'),
+ ('VLA', 'Vladimir Oblast', 'RU'),
+ ('KOS', 'Kostroma Oblast', 'RU'),
+ ('UD', 'Udmurtia, Republic of', 'RU'),
+ ('ME', 'Mari El, Republic of', 'RU'),
+ ('TA', 'Tatarstan, Republic of', 'RU'),
+ ('PNZ', 'Penza Oblast', 'RU'),
+ ('VGG', 'Volgograd Oblast', 'RU'),
+ ('AST', 'Astrakhan Oblast', 'RU'),
+ ('DA', 'Dagestan, Republic of', 'RU'),
+ ('SE', 'North Ossetia-Alania, Republic of', 'RU'),
+ ('KC', 'Karachay-Cherkessia, Republic of', 'RU'),
+ ('KGD', 'Kaliningrad Oblast', 'RU'),
+ ('MOS', 'Moscow Oblast', 'RU'),
+ ('RYA', 'Ryazan Oblast', 'RU'),
+ ('NIZ', 'Nizhny Novgorod Oblast', 'RU'),
+ ('ULY', 'Ulyanovsk Oblast', 'RU'),
+ ('CE', 'Chechnya, Republic of', 'RU'),
+ ('IN', 'Ingushetia, Republic of', 'RU'),
+ ('KB', 'Kabardino-Balkaria, Republic of', 'RU'),
+ ('KDA', 'Krasnodar Krai', 'RU'),
+ ('11', 'Seoul', 'KR'),
+ ('26', 'Busan', 'KR'),
+ ('27', 'Daegu', 'KR'),
+ ('28', 'Incheon', 'KR'),
+ ('29', 'Gwangju', 'KR'),
+ ('30', 'Daejeon', 'KR'),
+ ('31', 'Ulsan', 'KR'),
+ ('41', 'Gyeonggi', 'KR'),
+ ('42', 'Gangwon', 'KR'),
+ ('43', 'Chungcheongbuk-do', 'KR'),
+ ('44', 'Chungcheongnam-do', 'KR'),
+ ('45', 'Jeonbuk', 'KR'),
+ ('46', 'Jeonnam', 'KR'),
+ ('47', 'Gyeongsangbuk-do', 'KR'),
+ ('48', 'Gyeongsangnam-do', 'KR'),
+ ('49', 'Jeju-do', 'KR'),
+ ('50', 'Sejong', 'KR');
diff --git a/migrations/20240504194923_cached_points.down.sql b/migrations/20240504194923_cached_points.down.sql
new file mode 100644
index 000000000..12af63e14
--- /dev/null
+++ b/migrations/20240504194923_cached_points.down.sql
@@ -0,0 +1,183 @@
+-- Add down migration script here
+DROP VIEW ranked_players;
+DROP VIEW ranked_nations;
+
+ALTER TABLE players DROP COLUMN score;
+ALTER TABLE nationalities DROP COLUMN score;
+ALTER TABLE subdivisions DROP COLUMN score;
+
+DROP FUNCTION recompute_player_scores();
+DROP FUNCTION score_of_player(player_id INTEGER);
+DROP FUNCTION recompute_nation_scores();
+DROP FUNCTION score_of_nation(iso_country_code VARCHAR(2));
+DROP FUNCTION recompute_subdivision_scores();
+DROP FUNCTION score_of_subdivision(iso_country_code VARCHAR(2), iso_code VARCHAR(3));
+DROP VIEW score_giving;
+
+ALTER TABLE players DROP CONSTRAINT nation_subdivions_fkey;
+
+-- Copied from 20210419002933.up
+CREATE VIEW players_with_score AS
+SELECT players.id,
+ players.name,
+ RANK() OVER(ORDER BY scores.total_score DESC) AS rank,
+ CASE WHEN scores.total_score IS NULL THEN 0.0::FLOAT ELSE scores.total_score END AS score,
+ ROW_NUMBER() OVER(ORDER BY scores.total_score DESC) AS index,
+ nationalities.iso_country_code,
+ nationalities.nation,
+ players.subdivision,
+ nationalities.continent
+FROM
+ (
+ SELECT pseudo_records.player,
+ SUM(record_score(pseudo_records.progress::FLOAT, pseudo_records.position::FLOAT, 100::FLOAT, pseudo_records.requirement)) as total_score
+ FROM (
+ SELECT player,
+ progress,
+ position,
+ CASE WHEN demons.position > 75 THEN 100 ELSE requirement END AS requirement
+ FROM records
+ INNER JOIN demons
+ ON demons.id = demon
+ WHERE demons.position <= 150 AND status_ = 'APPROVED' AND (demons.position <= 75 OR progress = 100)
+
+ UNION
+
+ SELECT verifier as player,
+ CASE WHEN demons.position > 150 THEN 0.0::FLOAT ELSE 100.0::FLOAT END as progress,
+ position,
+ 100.0::FLOAT
+ FROM demons
+
+ UNION
+
+ SELECT publisher as player,
+ 0.0::FLOAT as progress,
+ position,
+ 100.0::FLOAT
+ FROM demons
+
+ UNION
+
+ SELECT creator as player,
+ 0.0::FLOAT as progress,
+ 1.0::FLOAT as position, -- doesn't matter
+ 100.0::FLOAT
+ FROM creators
+ ) AS pseudo_records
+ GROUP BY player
+ ) scores
+ INNER JOIN players
+ ON scores.player = players.id
+ LEFT OUTER JOIN nationalities
+ ON players.nationality = nationalities.iso_country_code
+WHERE NOT players.banned AND players.id != 1534;
+
+-- Copied from 20210726174613
+CREATE VIEW nations_with_score AS
+ SELECT RANK() OVER(ORDER BY scores.total_score DESC) AS rank,
+ scores.total_score AS score,
+ nationalities.iso_country_code,
+ nationalities.nation,
+ nationalities.continent
+ FROM (
+ SELECT nationality,
+ SUM(record_score(pseudo_records.progress::FLOAT, pseudo_records.position::FLOAT,
+ 100::FLOAT, pseudo_records.requirement)) as total_score
+ FROM (
+ select distinct on (nationality, demon)
+ nationality,
+ progress,
+ position,
+ CASE WHEN demons.position > 75 THEN 100 ELSE requirement END AS requirement
+ from (
+ select demon, player, progress
+ from records
+ where status_='APPROVED'
+
+ union
+
+ select id, verifier, 100
+ from demons
+ ) records
+ inner join demons
+ on demons.id = records.demon
+ inner join players
+ on players.id=records.player
+ inner join nationalities
+ on iso_country_code=players.nationality
+ where position <= 150 and not players.banned
+ order by nationality, demon, progress desc
+ ) AS pseudo_records
+ GROUP BY nationality
+ ) scores
+INNER JOIN nationalities
+ ON nationalities.iso_country_code = scores.nationality;
+
+-- Copied from 20210903174349
+CREATE OR REPLACE FUNCTION best_records_local(country VARCHAR(2), the_subdivision VARCHAR(3))
+ RETURNS TABLE (LIKE records)
+AS
+$body$
+WITH grp AS (
+ SELECT records.*,
+ RANK() OVER (PARTITION BY demon ORDER BY demon, progress DESC) AS rk
+ FROM records
+ INNER JOIN players
+ ON players.id = player
+ WHERE status_='APPROVED' AND players.nationality = country AND players.subdivision = the_subdivision
+)
+SELECT id, progress, video, status_, player, submitter, demon
+FROM grp
+WHERE rk = 1;
+$body$
+ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION subdivision_ranking_of(country VARCHAR(2))
+ RETURNS TABLE (
+ rank BIGINT,
+ score FLOAT,
+ subdivision_code VARCHAR(3),
+ name TEXT
+ )
+AS
+ $body$
+ SELECT RANK() OVER(ORDER BY scores.total_score DESC) AS rank,
+ scores.total_score AS score,
+ iso_code,
+ name
+ FROM (
+ SELECT iso_code, name,
+ SUM(record_score(pseudo_records.progress::FLOAT, pseudo_records.position::FLOAT,
+ 100::FLOAT, pseudo_records.requirement)) as total_score
+ FROM (
+ select distinct on (iso_code, demon)
+ iso_code,
+ subdivisions.name,
+ progress,
+ position,
+ CASE WHEN demons.position > 75 THEN 100 ELSE requirement END AS requirement
+ from (
+ select demon, player, progress
+ from records
+ where status_='APPROVED'
+
+ union
+
+ select id, verifier, 100
+ from demons
+ ) records
+ inner join demons
+ on demons.id = records.demon
+ inner join players
+ on players.id=records.player
+ inner join subdivisions
+ on (iso_code=players.subdivision and players.nationality = nation)
+ where position <= 150 and not players.banned and nation = country
+ order by iso_code, demon, progress desc
+ ) AS pseudo_records
+ GROUP BY iso_code, name
+ ) scores;
+ $body$
+LANGUAGE SQL;
+
diff --git a/migrations/20240504194923_cached_points.up.sql b/migrations/20240504194923_cached_points.up.sql
new file mode 100644
index 000000000..306aa9af5
--- /dev/null
+++ b/migrations/20240504194923_cached_points.up.sql
@@ -0,0 +1,145 @@
+-- Add up migration script here
+
+ALTER TABLE players ADD COLUMN score DOUBLE PRECISION DEFAULT 0 NOT NULL;
+
+CREATE VIEW score_giving AS
+ SELECT records.progress, demons.position, demons.requirement, records.player
+ FROM records
+ INNER JOIN demons
+ ON demons.id = records.demon
+ WHERE records.status_ = 'APPROVED'
+
+ UNION
+
+ SELECT 100, demons.position, demons.requirement, demons.verifier
+ FROM demons;
+
+CREATE FUNCTION score_of_player(player_id INTEGER) RETURNS DOUBLE PRECISION AS $$
+ SELECT SUM(record_score(progress, position, 150, requirement))
+ FROM score_giving
+ WHERE player = player_id
+$$ LANGUAGE SQL;
+
+-- This is slower than the old "select * from players_with_scores", but only needs to be called
+-- when demons are being moved around, so overall cheaper. Should this ever become a bottleneck for
+-- some obscure reason, we can separate the "score" column into a separate table, in which case the
+-- below function becomes a "TRUNCATE + INSERT q" on that new table (but then we'd pay the cost of
+-- combining these via a JOIN when requesting the stats viewer).
+CREATE FUNCTION recompute_player_scores() RETURNS void AS $$
+ -- The nested query is faster than the more obvious "UPDATE players SET score = score_of_player(id)",
+ -- as the latter would essentially have runtime O(|records| * |players|), which this solution as
+ -- runtime O(|records| + |players|^2) [approximately, technically its |players| * |players where score > 0|
+ -- and I'm sure the query planner is clever enough to not make it quadratic].
+ -- Since |records| >> |players|, this is faster.
+ UPDATE players
+ SET score = coalesce(q.score, 0)
+ FROM (
+ SELECT player, SUM(record_score(progress, position, 150, requirement)) as score
+ FROM score_giving
+ GROUP BY player
+ ) q
+ WHERE q.player = id;
+$$ LANGUAGE SQL;
+
+SELECT recompute_player_scores();
+
+DROP VIEW players_with_score;
+CREATE VIEW ranked_players AS
+ SELECT
+ ROW_NUMBER() OVER(ORDER BY players.score DESC, id) AS index,
+ RANK() OVER(ORDER BY score DESC) AS rank,
+ id, name, players.score, subdivision,
+ nationalities.iso_country_code,
+ nationalities.nation,
+ nationalities.continent
+ FROM players
+ LEFT OUTER JOIN nationalities
+ ON players.nationality = nationalities.iso_country_code
+ WHERE NOT players.banned AND players.score > 0.0;
+
+
+ALTER TABLE nationalities ADD COLUMN score DOUBLE PRECISION NOT NULL DEFAULT 0.0;
+
+CREATE FUNCTION score_of_nation(iso_country_code VARCHAR(2)) RETURNS DOUBLE PRECISION AS $$
+ SELECT SUM(record_score(q.progress, q.position, 150, q.requirement))
+ FROM (
+ SELECT DISTINCT ON (position) * from score_giving
+ INNER JOIN players
+ ON players.id=player
+ WHERE players.nationality = iso_country_code
+ ORDER BY position, progress DESC
+ ) q
+$$ LANGUAGE SQL;
+
+CREATE FUNCTION recompute_nation_scores() RETURNS void AS $$
+ UPDATE nationalities
+ SET score = COALESCE(p.sum, 0)
+ FROM (
+ SELECT nationality, SUM(record_score(q.progress, q.position, 150, q.requirement))
+ FROM (
+ SELECT DISTINCT ON (position, nationality) * from score_giving
+ INNER JOIN players
+ ON players.id=player
+ WHERE players.nationality IS NOT NULL
+ ORDER BY players.nationality, position, progress DESC
+ ) q
+ GROUP BY nationality
+ ) p
+ WHERE p.nationality = iso_country_code
+$$ LANGUAGE SQL;
+
+SELECT recompute_nation_scores();
+
+ALTER TABLE subdivisions ADD COLUMN score DOUBLE PRECISION NOT NULL DEFAULT 0.0;
+
+CREATE FUNCTION score_of_subdivision(iso_country_code VARCHAR(2), iso_code VARCHAR(3)) RETURNS DOUBLE PRECISION AS $$
+ SELECT SUM(record_score(q.progress, q.position, 150, q.requirement))
+ FROM (
+ SELECT DISTINCT ON (position) * from score_giving
+ INNER JOIN players
+ ON players.id=player
+ WHERE players.nationality = iso_country_code
+ AND players.subdivision = iso_code
+ ORDER BY position, progress DESC
+ ) q
+$$ LANGUAGE SQL;
+
+CREATE FUNCTION recompute_subdivision_scores() RETURNS void AS $$
+ UPDATE subdivisions
+ SET score = COALESCE(p.sum, 0)
+ FROM (
+ SELECT nationality, subdivision, SUM(record_score(q.progress, q.position, 150, q.requirement))
+ FROM (
+ SELECT DISTINCT ON (position, nationality, subdivision) * from score_giving
+ INNER JOIN players
+ ON players.id=player
+ WHERE players.nationality IS NOT NULL
+ AND players.subdivision IS NOT NULL
+ ORDER BY players.nationality, players.subdivision, position, progress DESC
+ ) q
+ GROUP BY nationality, subdivision
+ ) p
+ WHERE p.nationality = nation
+ AND p.subdivision = iso_code
+$$ LANGUAGE SQL;
+
+SELECT recompute_subdivision_scores();
+
+DROP VIEW nations_with_score;
+CREATE VIEW ranked_nations AS
+ SELECT
+ ROW_NUMBER() OVER(ORDER BY score DESC, iso_country_code) AS index,
+ RANK() OVER(ORDER BY score DESC) AS rank,
+ score,
+ iso_country_code,
+ nation,
+ continent
+ FROM nationalities
+ WHERE score > 0.0;
+
+-- Now-unused functions
+DROP FUNCTION subdivision_ranking_of(country varchar(2));
+DROP FUNCTION best_records_local(country VARCHAR(2), the_subdivision VARCHAR(3));
+
+-- Hardening against invalid database state
+ALTER TABLE players ADD CONSTRAINT nation_subdivions_fkey FOREIGN KEY (nationality, subdivision) REFERENCES subdivisions (nation, iso_code);
\ No newline at end of file
diff --git a/migrations/20240518154803_no_extended_progress_points.down.sql b/migrations/20240518154803_no_extended_progress_points.down.sql
new file mode 100644
index 000000000..8f33ab529
--- /dev/null
+++ b/migrations/20240518154803_no_extended_progress_points.down.sql
@@ -0,0 +1,17 @@
+-- Add down migration script here
+
+CREATE OR REPLACE VIEW score_giving AS
+ SELECT records.progress, demons.position, demons.requirement, records.player
+ FROM records
+ INNER JOIN demons
+ ON demons.id = records.demon
+ WHERE records.status_ = 'APPROVED'
+
+ UNION
+
+ SELECT 100, demons.position, demons.requirement, demons.verifier
+ FROM demons;
+
+SELECT recompute_player_scores();
+SELECT recompute_nation_scores();
+SELECT recompute_subdivision_scores();
\ No newline at end of file
diff --git a/migrations/20240518154803_no_extended_progress_points.up.sql b/migrations/20240518154803_no_extended_progress_points.up.sql
new file mode 100644
index 000000000..8efed0766
--- /dev/null
+++ b/migrations/20240518154803_no_extended_progress_points.up.sql
@@ -0,0 +1,17 @@
+-- Add up migration script here
+CREATE OR REPLACE VIEW score_giving AS
+ SELECT records.progress, demons.position, demons.requirement, records.player
+ FROM records
+ INNER JOIN demons
+ ON demons.id = records.demon
+ WHERE records.status_ = 'APPROVED' AND (demons.position <= 75 OR records.progress = 100)
+
+ UNION
+
+ SELECT 100, demons.position, demons.requirement, demons.verifier
+ FROM demons;
+
+
+SELECT recompute_player_scores();
+SELECT recompute_nation_scores();
+SELECT recompute_subdivision_scores();
\ No newline at end of file
diff --git a/migrations/20240518161548_properly_zero_scores.down.sql b/migrations/20240518161548_properly_zero_scores.down.sql
new file mode 100644
index 000000000..f689e4bf7
--- /dev/null
+++ b/migrations/20240518161548_properly_zero_scores.down.sql
@@ -0,0 +1,53 @@
+-- Add down migration script here
+
+CREATE OR REPLACE FUNCTION recompute_player_scores() RETURNS void AS $$
+ UPDATE players
+ SET score = coalesce(q.score, 0)
+ FROM (
+ SELECT player, SUM(record_score(progress, position, 150, requirement)) as score
+ FROM score_giving
+ GROUP BY player
+ ) q
+ WHERE q.player = id;
+$$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION recompute_nation_scores() RETURNS void AS $$
+ UPDATE nationalities
+ SET score = COALESCE(p.sum, 0)
+ FROM (
+ SELECT nationality, SUM(record_score(q.progress, q.position, 150, q.requirement))
+ FROM (
+ SELECT DISTINCT ON (position, nationality) * from score_giving
+ INNER JOIN players
+ ON players.id=player
+ WHERE players.nationality IS NOT NULL
+ ORDER BY players.nationality, position, progress DESC
+ ) q
+ GROUP BY nationality
+ ) p
+ WHERE p.nationality = iso_country_code
+$$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION recompute_subdivision_scores() RETURNS void AS $$
+ UPDATE subdivisions
+ SET score = COALESCE(p.sum, 0)
+ FROM (
+ SELECT nationality, subdivision, SUM(record_score(q.progress, q.position, 150, q.requirement))
+ FROM (
+ SELECT DISTINCT ON (position, nationality, subdivision) * from score_giving
+ INNER JOIN players
+ ON players.id=player
+ WHERE players.nationality IS NOT NULL
+ AND players.subdivision IS NOT NULL
+ ORDER BY players.nationality, players.subdivision, position, progress DESC
+ ) q
+ GROUP BY nationality, subdivision
+ ) p
+ WHERE p.nationality = nation
+ AND p.subdivision = iso_code
+$$ LANGUAGE SQL;
+
+
+SELECT recompute_player_scores();
+SELECT recompute_nation_scores();
+SELECT recompute_subdivision_scores();
\ No newline at end of file
diff --git a/migrations/20240518161548_properly_zero_scores.up.sql b/migrations/20240518161548_properly_zero_scores.up.sql
new file mode 100644
index 000000000..dedf68fbf
--- /dev/null
+++ b/migrations/20240518161548_properly_zero_scores.up.sql
@@ -0,0 +1,62 @@
+-- Add up migration script here
+
+-- We need LEFT OUTER JOINs below so that those players which DO NOT show up in the
+-- SELECT player, SUM(...) query (because they no longer have any records that give scores) have their scores correctly
+-- reset to 0!
+
+CREATE OR REPLACE FUNCTION recompute_player_scores() RETURNS void AS $$
+ UPDATE players
+ SET score = coalesce(q.score, 0)
+ FROM players p
+ LEFT OUTER JOIN (
+ SELECT player, SUM(record_score(progress, position, 150, requirement)) as score
+ FROM score_giving
+ GROUP BY player
+ ) q
+ ON q.player = p.id
+ WHERE players.id = p.id;
+$$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION recompute_nation_scores() RETURNS void AS $$
+ UPDATE nationalities
+ SET score = COALESCE(p.sum, 0)
+ FROM nationalities n
+ LEFT OUTER JOIN (
+ SELECT nationality, SUM(record_score(q.progress, q.position, 150, q.requirement))
+ FROM (
+ SELECT DISTINCT ON (position, nationality) * from score_giving
+ INNER JOIN players
+ ON players.id=player
+ WHERE players.nationality IS NOT NULL
+ ORDER BY players.nationality, position, progress DESC
+ ) q
+ GROUP BY nationality
+ ) p
+ ON p.nationality = n.iso_country_code
+ WHERE n.iso_country_code = nationalities.iso_country_code
+$$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION recompute_subdivision_scores() RETURNS void AS $$
+ UPDATE subdivisions
+ SET score = COALESCE(p.sum, 0)
+ FROM subdivisions s
+ LEFT OUTER JOIN (
+ SELECT nationality, subdivision, SUM(record_score(q.progress, q.position, 150, q.requirement))
+ FROM (
+ SELECT DISTINCT ON (position, nationality, subdivision) * from score_giving
+ INNER JOIN players
+ ON players.id=player
+ WHERE players.nationality IS NOT NULL
+ AND players.subdivision IS NOT NULL
+ ORDER BY players.nationality, players.subdivision, position, progress DESC
+ ) q
+ GROUP BY nationality, subdivision
+ ) p
+ ON s.nation = p.nationality AND s.iso_code = p.subdivision
+ WHERE s.nation = subdivisions.nation
+ AND s.iso_code = subdivisions.iso_code
+$$ LANGUAGE SQL;
+
+SELECT recompute_player_scores();
+SELECT recompute_nation_scores();
+SELECT recompute_subdivision_scores();
\ No newline at end of file
diff --git a/pointercrate-core-api/Cargo.toml b/pointercrate-core-api/Cargo.toml
index 13dde7881..aef057866 100644
--- a/pointercrate-core-api/Cargo.toml
+++ b/pointercrate-core-api/Cargo.toml
@@ -1,17 +1,18 @@
[package]
name = "pointercrate-core-api"
version = "0.1.0"
-edition = "2021"
+authors.workspace = true
+edition.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-serde = "1.0.118"
-rocket = {version = "0.5.0-rc.3", features = ["json"]}
+serde = "1.0.203"
+rocket = {version = "0.5.1", features = ["json"]}
pointercrate-core = {path = "../pointercrate-core"}
pointercrate-core-pages = {path = "../pointercrate-core-pages"}
-serde_json = "1.0.60"
-sqlx = { version = "0.6", default-features = false, features = [ "runtime-tokio-native-tls", "macros", "postgres", "chrono", "offline" ] }
-log = "0.4.11"
+serde_json = "1.0.118"
+sqlx = { version = "0.7", default-features = false, features = [ "runtime-tokio-native-tls", "macros", "postgres", "chrono" ] }
+log = "0.4.22"
serde_urlencoded = "0.7.0"
-maud = "0.25"
+maud = "0.26.0"
diff --git a/pointercrate-core-api/src/error.rs b/pointercrate-core-api/src/error.rs
index 7940b0119..910719de4 100644
--- a/pointercrate-core-api/src/error.rs
+++ b/pointercrate-core-api/src/error.rs
@@ -1,5 +1,5 @@
use crate::response::Page;
-use log::{error, info};
+use log::info;
use pointercrate_core::error::PointercrateError;
use pointercrate_core_pages::error::ErrorFragment;
use rocket::{
@@ -34,10 +34,6 @@ impl<'r> Responder<'r, 'static> for ErrorResponder {
let status = Status::from_code(self.error_code / 100).unwrap_or(Status::InternalServerError);
- if status.code >= 500 {
- error!("Encountered an internal server error: {:?}", self);
- }
-
if accept == MediaType::HTML {
Response::build_from(
Page::new(ErrorFragment {
diff --git a/pointercrate-core-api/src/etag.rs b/pointercrate-core-api/src/etag.rs
index 4ab057c2a..72c6bd2ec 100644
--- a/pointercrate-core-api/src/etag.rs
+++ b/pointercrate-core-api/src/etag.rs
@@ -37,7 +37,7 @@ impl<'r> FromRequest<'r> for Precondition {
async fn from_request(request: &'r Request<'_>) -> Outcome {
match request.headers().get_one("if-match") {
Some(if_match) => Outcome::Success(Precondition(if_match.split(',').map(ToString::to_string).collect())),
- None => Outcome::Failure((Status::PreconditionRequired, CoreError::PreconditionRequired)),
+ None => Outcome::Error((Status::PreconditionRequired, CoreError::PreconditionRequired)),
}
}
}
@@ -47,18 +47,20 @@ impl<'r, T: Taggable> Responder<'r, 'static> for Tagged {
let response_etag = self.0.etag_string();
match request.method() {
- Method::Get =>
+ Method::Get => {
if let Some(if_none_match) = request.headers().get_one("if-none-match") {
if if_none_match.contains(&response_etag) {
- return Response::build().status(Status::NotModified).ok()
+ return Response::build().status(Status::NotModified).ok();
}
- },
- Method::Patch | Method::Delete =>
+ }
+ },
+ Method::Patch | Method::Delete => {
if let Some(if_none_match) = request.headers().get_one("if-match") {
if if_none_match.contains(&response_etag) {
- return Response::build().status(Status::NotModified).ok()
+ return Response::build().status(Status::NotModified).ok();
}
- },
+ }
+ },
_ => (),
}
diff --git a/pointercrate-core-api/src/lib.rs b/pointercrate-core-api/src/lib.rs
index 26b958086..ffe9d847e 100644
--- a/pointercrate-core-api/src/lib.rs
+++ b/pointercrate-core-api/src/lib.rs
@@ -1,5 +1,6 @@
pub mod error;
pub mod etag;
+pub mod maintenance;
+pub mod pagination;
pub mod query;
-#[macro_use]
pub mod response;
diff --git a/pointercrate-core-api/src/maintenance.rs b/pointercrate-core-api/src/maintenance.rs
new file mode 100644
index 000000000..53ef16959
--- /dev/null
+++ b/pointercrate-core-api/src/maintenance.rs
@@ -0,0 +1,55 @@
+//! Module providing a "maintenance mode" fairing (middleware)
+
+use crate::error::Result;
+use pointercrate_core::error::CoreError;
+use rocket::{
+ fairing::{Fairing, Info, Kind},
+ http::Method,
+ routes, uri, Build, Data, Request, Rocket,
+};
+
+/// Rocket fairing that causes all mutating requests (aka non-GET requests) to return 503 SERVICE UNAVAILABLE if `.0` is `true`.
+///
+/// Works in a very hacky way, as rocket does not allow fairing to terminate requests. Thus we instead rewrite the
+/// request on the fly to be a GET /maintenance, which is an endpoint that unconditionally returns a 503 response.
+/// This endpoint only exists when maintainence mode is active (it is dynamically mounted in `on_ignite`).
+///
+/// Idea taken from https://stackoverflow.com/questions/70011965/global-authentication-authorization-in-rocket-based-on-a-header
+#[derive(Default)]
+pub struct MaintenanceFairing(bool);
+
+impl MaintenanceFairing {
+ pub fn new(read_only: bool) -> Self {
+ MaintenanceFairing(read_only)
+ }
+}
+
+#[rocket::async_trait]
+impl Fairing for MaintenanceFairing {
+ fn info(&self) -> Info {
+ Info {
+ name: "Maintenance",
+ kind: Kind::Ignite | Kind::Request,
+ }
+ }
+
+ async fn on_ignite(&self, mut rocket: Rocket) -> rocket::fairing::Result {
+ if self.0 {
+ log::warn!("Maintenance mode activated! All non-GET requests will receive a 503 response!");
+ rocket = rocket.mount("/", routes![maintenance]);
+ }
+ Ok(rocket)
+ }
+
+ async fn on_request(&self, request: &mut Request<'_>, _: &mut Data<'_>) {
+ if self.0 && request.method() != Method::Get {
+ request.set_uri(uri!("/maintenance"));
+ request.set_method(Method::Get);
+ }
+ }
+}
+
+#[rocket::get("/maintenance")]
+async fn maintenance() -> Result<()> {
+ Err(CoreError::ReadOnlyMaintenance.into())
+}
diff --git a/pointercrate-core-api/src/pagination.rs b/pointercrate-core-api/src/pagination.rs
new file mode 100644
index 000000000..17df9b75a
--- /dev/null
+++ b/pointercrate-core-api/src/pagination.rs
@@ -0,0 +1,193 @@
+use std::collections::BTreeMap;
+
+use pointercrate_core::{
+ error::CoreError,
+ pagination::{Paginatable, PaginationParameters, PaginationQuery},
+};
+use rocket::serde::json::Json;
+use sqlx::PgConnection;
+
+use crate::response::Response2;
+
+#[derive(Debug)]
+pub struct LinksBuilder {
+ endpoint: &'static str,
+ rels: BTreeMap<&'static str, PaginationParameters>,
+}
+
+impl LinksBuilder {
+ pub fn new(endpoint: &'static str) -> Self {
+ LinksBuilder {
+ endpoint,
+ rels: BTreeMap::new(),
+ }
+ }
+
+ pub fn with_first(mut self, id_before_first: i32) -> Self {
+ self.rels.insert(
+ "first",
+ PaginationParameters {
+ after: Some(id_before_first),
+ before: None,
+ ..Default::default()
+ },
+ );
+ self
+ }
+
+ pub fn with_last(mut self, id_after_last: i32) -> Self {
+ self.rels.insert(
+ "last",
+ PaginationParameters {
+ after: None,
+ before: Some(id_after_last),
+ ..Default::default()
+ },
+ );
+ self
+ }
+
+ pub fn with_next(mut self, after: i32) -> Self {
+ self.rels.insert(
+ "next",
+ PaginationParameters {
+ after: Some(after),
+ before: None,
+ ..Default::default()
+ },
+ );
+ self
+ }
+
+ pub fn with_previous(mut self, before: i32) -> Self {
+ self.rels.insert(
+ "prev",
+ PaginationParameters {
+ after: None,
+ before: Some(before),
+ ..Default::default()
+ },
+ );
+ self
+ }
+
+ pub fn generate(&self, base: &P) -> Result {
+ let mut buf = String::new();
+ let mut is_first = true;
+ // The build functions set a default value for "limit" - copy the actual value from the given base here
+ let limit = base.parameters().limit;
+
+ for (rel, param) in &self.rels {
+ if !is_first {
+ buf.push_str(",");
+ }
+ is_first = false;
+
+ let query_string =
+ serde_urlencoded::to_string(base.with_parameters(PaginationParameters { limit, ..*param })).map_err(|err| {
+ CoreError::internal_server_error(format!(
+ "Failed to serialize pagination query string: {:?}. Base: {:?}, Builder: {:?}, Current Rel: {}",
+ err, base, self, rel
+ ))
+ })?;
+
+ buf += &format!("<{}?{}>; rel={}", self.endpoint, query_string, rel);
+ }
+
+ Ok(buf)
+ }
+}
+
+pub async fn pagination_response>(
+ endpoint: &'static str, query: Q, connection: &mut PgConnection,
+) -> Result>>, CoreError> {
+ let parameters = query.parameters();
+
+ parameters.validate()?;
+
+ let (objects, context) = P::page(&query, &mut *connection).await?;
+
+ let mut links = LinksBuilder::new(endpoint);
+
+ if let Some((min_id, max_id)) = P::first_and_last(connection).await? {
+ links = links.with_first(min_id - 1).with_last(max_id + 1);
+ }
+
+ if context.has_next() {
+ let after = match objects.last() {
+ Some(obj) => obj.pagination_id(),
+ None => {
+ // If there exists a next page, but this page is empty, then
+ // we must have had a `before` value set (e.g. this is a page before the first object matching the pagination conditions).
+ parameters.before.ok_or_else(|| {
+ CoreError::internal_server_error(format!(
+ "Empty page claims next page exists, yet `before` not set on current request. Caused by {:?}",
+ query
+ ))
+ })? - 1
+ },
+ };
+
+ // TODO: Figure out the case where both `before` and `after` are set
+ // If `before` is set on this request, then we _could_ support one-way pagination up to `before` by preserving the "before" value here.
+ // Currently, this scenario cannot happen, as the documentation of `Pagination::page` we treat these pages as "standalone".
+ links = links.with_next(after);
+ }
+
+ if context.has_previous() {
+ let before = match objects.first() {
+ Some(obj) => obj.pagination_id(),
+ None => {
+ parameters.after.ok_or_else(|| {
+ CoreError::internal_server_error(format!(
+ "Empty page claims previous page exists, yet `after` not set on current request. Caused by {:?}",
+ query
+ ))
+ })? + 1
+ },
+ };
+
+ // Either this request had the `after` parameter set, in which case we definitely do not want to preserve it as our "before" variable above is either
+ // the ID of the smallest object greater than `after`, or it is literally `after + 1`.
+ links = links.with_previous(before);
+ };
+
+ Ok(Response2::json(objects).with_header("Links", links.generate(&query)?))
+}
+
+#[cfg(test)]
+mod tests {
+ use pointercrate_core::pagination::{PaginationParameters, PaginationQuery};
+ use serde::Serialize;
+
+ use super::LinksBuilder;
+
+ #[derive(Debug, Default, Serialize)]
+ struct DummyQuery(PaginationParameters);
+
+ impl PaginationQuery for DummyQuery {
+ fn parameters(&self) -> PaginationParameters {
+ self.0
+ }
+
+ fn with_parameters(&self, parameters: PaginationParameters) -> Self {
+ DummyQuery(parameters)
+ }
+ }
+
+ #[test]
+ fn test_links_builder() {
+ let links_header = LinksBuilder::new("/dummies")
+ .with_first(0)
+ .with_last(1971)
+ .with_next(2)
+ .with_previous(100)
+ .generate(&DummyQuery::default())
+ .unwrap();
+
+ assert_eq!(
+ links_header,
+ "; rel=first,; rel=last,; rel=next,; rel=prev"
+ );
+ }
+}
diff --git a/pointercrate-core-api/src/query.rs b/pointercrate-core-api/src/query.rs
index 4c2286e13..f2af799d3 100644
--- a/pointercrate-core-api/src/query.rs
+++ b/pointercrate-core-api/src/query.rs
@@ -14,11 +14,10 @@ impl<'r, T: DeserializeOwned> FromRequest<'r> for Query {
async fn from_request(request: &'r Request<'_>) -> Outcome {
match request.uri().query() {
None => Outcome::Success(Query(serde_urlencoded::from_str("").unwrap())),
- Some(query) =>
- match serde_urlencoded::from_str(query.as_str()) {
- Ok(t) => Outcome::Success(Query(t)),
- Err(err) => Outcome::Failure((Status::BadRequest, err)),
- },
+ Some(query) => match serde_urlencoded::from_str(query.as_str()) {
+ Ok(t) => Outcome::Success(Query(t)),
+ Err(err) => Outcome::Error((Status::BadRequest, err)),
+ },
}
}
}
diff --git a/pointercrate-core-api/src/response.rs b/pointercrate-core-api/src/response.rs
index b341ea50e..2f56d063c 100644
--- a/pointercrate-core-api/src/response.rs
+++ b/pointercrate-core-api/src/response.rs
@@ -114,109 +114,3 @@ impl<'r, 'o: 'r, T: Responder<'r, 'o>> Responder<'r, 'o> for Response2 {
response_builder.ok()
}
}
-
-#[macro_export]
-macro_rules! pagination_response {
- ($endpoint: expr, $objects:expr, $pagination:expr, $min_id:expr, $max_id:expr, $before_field:ident, $after_field:ident, $($id_field:tt)*) => {{
- use pointercrate_core_api::response::Response2;
-
- log::debug!("Received pagination request {:?}", $pagination);
-
- let mut rel = String::new();
-
- let limit = $pagination.limit.unwrap_or(50) as usize;
- let next_page_exists = $objects.len() > limit;
-
- if !$objects.is_empty() {
- if next_page_exists {
- log::debug!("A new page exists!");
-
- $objects.pop(); // remove the things from then next page
- }
-
- let last = $objects.last().unwrap().$($id_field)*;
- let first = $objects.first().unwrap().$($id_field)*;
-
- match ($pagination.$before_field, $pagination.$after_field) {
- (None, after) => {
- log::debug!("No before value set, assuming result is correctly ordered!");
-
- // no 'before' value set.
- // if 'after' is none, we're on the first page, otherwise we have ot generate a 'prev' link
-
- if next_page_exists {
-
- $pagination.$after_field = Some(last);
- $pagination.$before_field = None;
-
- rel.push_str(&format!(
- ",<{}?{}>; rel=next",
- $endpoint, serde_urlencoded::to_string(&$pagination).unwrap()
- ));
- }
-
- if after.is_some() {
- $pagination.$after_field = None;
- $pagination.$before_field = Some(first);
-
- rel.push_str(&format!(
- ",<{}?{}>; rel=prev",
- $endpoint, serde_urlencoded::to_string(&$pagination).unwrap()
- ));
- }
- }
- (Some(_), None) => {
- log::debug!("Before value set, assuming result is reverse ordered!");
-
- // A previous page exists. This means "first" and "last" are actually to opposite of what the variables are named.
- $pagination.$before_field = Some(last);
- $pagination.$after_field = None;
-
- // In this case, the page was retrieved using 'ORDER BY ... DESC' so we need to reverse list order!
- $objects.reverse();
-
- if next_page_exists {
- rel.push_str(&format!(
- ",<{}?{}>; rel=prev",
- $endpoint, serde_urlencoded::to_string(&$pagination).unwrap()
- ));
- }
- $pagination.$after_field = Some(first);
- $pagination.$before_field = None;
-
- rel.push_str(&format!(
- ",<{}?{}>; rel=next",
- $endpoint, serde_urlencoded::to_string(&$pagination).unwrap()
- ));
- }
- (Some(_before), Some(_after)) => {
- // We interpret this as that all objects _up to 'before'_ are supposed to be paginated.
- // This means we keep the 'before' value and handle the 'after' value just as above.
- // tODO: implement
- }
- }
- }
-
- $pagination.$after_field = Some($min_id - 1);
- $pagination.$before_field = None;
-
- let mut links = format!(
- "<{}?{}>; rel=first",
- $endpoint, serde_urlencoded::to_string(&$pagination).unwrap()
- );
-
- $pagination.$after_field = None;
- $pagination.$before_field = Some($max_id + 1);
-
- links.push_str(&format!(
- ",<{}?{}>; rel=last",
- $endpoint, serde_urlencoded::to_string(&$pagination).unwrap()
- ));
-
- links.push_str(&rel);
-
- log::debug!("Links headers has value '{}'", links);
-
- Ok(Response2::json($objects).with_header("Links", links))
- }};
-}
diff --git a/pointercrate-core-pages/Cargo.toml b/pointercrate-core-pages/Cargo.toml
index c7b7cae52..5ac01a6cf 100644
--- a/pointercrate-core-pages/Cargo.toml
+++ b/pointercrate-core-pages/Cargo.toml
@@ -1,10 +1,11 @@
[package]
name = "pointercrate-core-pages"
version = "0.1.0"
-edition = "2021"
+authors.workspace = true
+edition.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-maud = "0.25"
+maud = "0.26.0"
pointercrate-core = {path = "../pointercrate-core"}
diff --git a/pointercrate-core-pages/src/config.rs b/pointercrate-core-pages/src/config.rs
index c9df8439d..9a6bf684e 100644
--- a/pointercrate-core-pages/src/config.rs
+++ b/pointercrate-core-pages/src/config.rs
@@ -1,7 +1,3 @@
-pub fn adsense_publisher_id() -> Option {
- std::env::var("ADSENSE_PUBLISHER_ID").ok()
-}
-
pub fn google_analytics_tag() -> Option {
std::env::var("ANALYTICS_TAG").ok()
}
diff --git a/pointercrate-core-pages/src/footer.rs b/pointercrate-core-pages/src/footer.rs
index de2c967ba..a43272df8 100644
--- a/pointercrate-core-pages/src/footer.rs
+++ b/pointercrate-core-pages/src/footer.rs
@@ -60,23 +60,21 @@ impl Render for &Link {
impl Render for &FooterColumn {
fn render(&self) -> Markup {
match self {
- FooterColumn::LinkList { heading, links } =>
- html! {
- nav {
- h2 {(heading)}
- @for link in links {
- (link)
- br;
- }
+ FooterColumn::LinkList { heading, links } => html! {
+ nav {
+ h2 {(heading)}
+ @for link in links {
+ (link)
+ br;
}
- },
- FooterColumn::Arbitrary { heading, content } =>
- html! {
- div {
- h2 {(heading)}
- (*content)
- }
- },
+ }
+ },
+ FooterColumn::Arbitrary { heading, content } => html! {
+ div {
+ h2 {(heading)}
+ (*content)
+ }
+ },
}
}
}
diff --git a/pointercrate-core-pages/src/head.rs b/pointercrate-core-pages/src/head.rs
index cc7dafaed..f3f737675 100644
--- a/pointercrate-core-pages/src/head.rs
+++ b/pointercrate-core-pages/src/head.rs
@@ -136,7 +136,7 @@ impl Script {
}
}
-impl Render for &Script {
+impl Render for Script {
fn render(&self) -> Markup {
html! {
@if self.module {
@@ -172,15 +172,6 @@ impl Render for &Meta {
}
}
-// this should be handled automatically on newer versions of maud
-/*
-impl Render for Script {
- fn render(&self) -> Markup {
- (&self).render()
- }
-}
-*/
-
/// Adds a version query string to a url based on the package version.
///
/// A macro is used to make the version crate-independent.
diff --git a/pointercrate-core-pages/src/lib.rs b/pointercrate-core-pages/src/lib.rs
index 227f87d5c..b6a081926 100644
--- a/pointercrate-core-pages/src/lib.rs
+++ b/pointercrate-core-pages/src/lib.rs
@@ -27,20 +27,16 @@ impl HeadLike for PageConfiguration {
impl PageConfiguration {
pub fn new(site_name: impl Into, nav_bar: NavigationBar, footer: Footer) -> Self {
let default_head_html = html! {
- @if let Some(publisher_id) = config::adsense_publisher_id() {
- (PreEscaped(format!(r#""#, publisher_id)))
- }
-
@if let Some(analytics_tag) = config::google_analytics_tag() {
(PreEscaped(format!(r#"
"#, analytics_tag)));
}
@@ -57,7 +53,19 @@ impl PageConfiguration {
.meta("og:site_name", site_name)
.meta("og:type", "website")
.meta("referrer", "no-referrer")
- .meta("viewport", "initial-scale=1, maximum-scale=1"),
+ .meta("viewport", "initial-scale=1, maximum-scale=1")
+ .script("https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js")
+ .script("https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js")
+ .script("/static/core/js/ui.js")
+ .script("/static/core/js/nav.js")
+ .script("/static/core/js/misc.js")
+ .stylesheet("/static/core/css/icon.css")
+ .stylesheet("/static/core/css/nav.css")
+ .stylesheet("/static/core/css/main.css")
+ .stylesheet("/static/core/css/ui.css")
+ .stylesheet("/static/core/css/core.css")
+ .stylesheet("/static/core/css/fa.all.min.css")
+ .stylesheet("https://fonts.googleapis.com/css?family=Montserrat|Montserrat:light,bold"),
}
}
diff --git a/pointercrate-core-pages/src/navigation.rs b/pointercrate-core-pages/src/navigation.rs
index c51a2c912..a12223fe9 100644
--- a/pointercrate-core-pages/src/navigation.rs
+++ b/pointercrate-core-pages/src/navigation.rs
@@ -70,7 +70,7 @@ impl Render for NavigationBar {
header {
nav.center.collapse.underlined {
div.nav-icon style = "margin-right: auto" {
- a href = "/" {
+ a href = "/" aria-label = "Go to homepage" {
img src = (self.logo_path) style="height:50px" alt="1.9 Demonlist";
}
}
diff --git a/pointercrate-core-pages/static/css/core.css b/pointercrate-core-pages/static/css/core.css
index 74589638d..ed0f34972 100644
--- a/pointercrate-core-pages/static/css/core.css
+++ b/pointercrate-core-pages/static/css/core.css
@@ -32,15 +32,15 @@
/* center using margin */
.m-center {
max-width: 1072px;
- margin-left: calc(45% - 1072px / 2) !important;
- margin-right: calc(55% - 1072px / 2) !important;
+ margin-left: calc(50% - 1072px / 2) !important;
+ margin-right: calc(50% - 1072px / 2) !important;
}
/* center using padding */
.center {
max-width: 1072px;
- padding-left: calc(45% - 1072px / 2);
- padding-right: calc(55% - 1072px / 2);
+ padding-left: calc(50% - 1072px / 2);
+ padding-right: calc(50% - 1072px / 2);
}
}
diff --git a/pointercrate-core-pages/static/css/nav.css b/pointercrate-core-pages/static/css/nav.css
index 680930919..c44f9abf5 100644
--- a/pointercrate-core-pages/static/css/nav.css
+++ b/pointercrate-core-pages/static/css/nav.css
@@ -216,7 +216,7 @@ footer .flex {
footer .flex > * {
margin: 1% 1%;
min-width: 150px;
- max-width: 15%;
+ max-width: 30%;
}
footer a.link {
@@ -241,7 +241,8 @@ footer * {
}
footer .flex {
- justify-content: center;
+ flex-direction: column;
+ align-items: center;
}
footer .flex {
diff --git a/pointercrate-core-pages/static/css/ui.css b/pointercrate-core-pages/static/css/ui.css
index 01ca631bd..8c4951f12 100644
--- a/pointercrate-core-pages/static/css/ui.css
+++ b/pointercrate-core-pages/static/css/ui.css
@@ -262,6 +262,7 @@ input[type="text"],
input[type="number"],
input[type="url"],
input[type="password"],
+input[type="datetime-local"],
textarea {
border: 1px solid #444;
min-width: 0; /* Firefox and Egde need this */
@@ -279,16 +280,29 @@ textarea {
input[type="text"],
input[type="number"],
input[type="url"],
-input[type="password"] {
+input[type="password"],
+input[type="datetime-local"]{
min-height: 1em;
padding: 0.65rem;
}
+/*
+form input[type="text"]:valid,
+form input[type="number"]:valid,
+form input[type="url"]:valid,
+form input[type="password"]:valid,
+form input[type="datetime-local"]:valid,
+textarea:valid {
+ border-bottom: 1px solid lime;
+}
+*/
+
form input[type="text"]:focus:invalid,
form input[type="number"]:focus:invalid,
form input[type="url"]:focus:invalid,
form input[type="password"]:focus:invalid,
-textarea:invalid {
+form input[type="datetime-local"]:focus:invalid,
+textarea:focus:invalid {
border-color: rgb(255, 0, 0);
}
@@ -486,7 +500,7 @@ textarea:invalid {
top: 2em; /* place it below the box! */
width: calc(100% - 2px);
- max-height: 400px;
+ max-height: 290px;
overflow-y: scroll;
background: #1f1f1f;
@@ -695,6 +709,19 @@ h2 .dropdown-menu ul {
border-left-color: yellow;
}
+.info-blue {
+ background: #181818;
+ padding: 10px 15px;
+ color: white;
+ margin: 25px 0px;
+
+ border-radius: 4px;
+
+ border-left-width: 4px;
+ border-left-style: solid;
+ border-left-color: #6e7dff;
+}
+
.info-red {
background: #181818;
padding: 10px 15px;
diff --git a/pointercrate-core-pages/static/js/modules/form.js b/pointercrate-core-pages/static/js/modules/form.js
index ba679e603..c63a394e8 100644
--- a/pointercrate-core-pages/static/js/modules/form.js
+++ b/pointercrate-core-pages/static/js/modules/form.js
@@ -1186,6 +1186,11 @@ const UNEXPECTED_REDIRECT = {
code: 50000,
data: null,
};
+const RATELIMITED = {
+ message: "You have hit a Cloudflare ratelimit. Please wait a short time and try again.",
+ code: 42900,
+ data: null
+}
function mkReq(method, endpoint, headers = {}, data = null) {
headers["Content-Type"] = "application/json";
@@ -1221,7 +1226,7 @@ function mkReq(method, endpoint, headers = {}, data = null) {
var jsonError = JSON.parse(xhr.responseText);
} catch (e) {
return reject({
- data: SEVERE_ERROR,
+ data: xhr.status == 429 ? RATELIMITED : SEVERE_ERROR,
headers: parseHeaders(xhr),
status: xhr.status,
});
diff --git a/pointercrate-core/Cargo.toml b/pointercrate-core/Cargo.toml
index b09259a9e..71f337f86 100644
--- a/pointercrate-core/Cargo.toml
+++ b/pointercrate-core/Cargo.toml
@@ -1,13 +1,14 @@
[package]
name = "pointercrate-core"
version = "0.1.0"
-edition = "2021"
+authors.workspace = true
+edition.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-serde = "1.0.118"
-derive_more = "0.99.11"
-sqlx = { version = "0.6", default-features = false, features = [ "runtime-tokio-native-tls", "macros", "postgres", "chrono", "migrate", "offline"] }
-log = "0.4.8"
-chrono = {version = "0.4.19", features = ["serde"]}
+serde = "1.0.203"
+derive_more = "0.99.18"
+sqlx = { version = "0.7", default-features = false, features = [ "runtime-tokio-native-tls", "macros", "postgres", "chrono", "migrate"] }
+log = "0.4.22"
+chrono = {version = "0.4.38", features = ["serde"]}
diff --git a/pointercrate-core/build.rs b/pointercrate-core/build.rs
index 3a8149ef0..ce57e1a18 100644
--- a/pointercrate-core/build.rs
+++ b/pointercrate-core/build.rs
@@ -1,3 +1,5 @@
+// generated by `sqlx migrate build-script`
fn main() {
- println!("cargo:rerun-if-changed=migrations");
+ // trigger recompilation when a new migration is added
+ println!("cargo:rerun-if-changed=../migrations");
}
diff --git a/pointercrate-core/src/error.rs b/pointercrate-core/src/error.rs
index 9fddd08c1..718d870f1 100644
--- a/pointercrate-core/src/error.rs
+++ b/pointercrate-core/src/error.rs
@@ -2,7 +2,6 @@ use crate::permission::Permission;
use derive_more::Display;
use log::error;
use serde::Serialize;
-use sqlx::postgres::PgDatabaseError;
use std::{error::Error, time::Duration};
pub type Result = std::result::Result;
@@ -194,10 +193,7 @@ pub enum CoreError {
fmt = "The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there \
is an error in the application. Please notify a server administrator and have them look at the server logs!"
)]
- InternalServerError {
- #[serde(skip)]
- message: String,
- },
+ InternalServerError,
/// `500 INTERNAL SERVER ERROR`
///
@@ -208,12 +204,34 @@ pub enum CoreError {
)]
DatabaseError,
+ /// `500 INTERNAL SERVER ERROR` reported when postgres terminates a query due to hitting `statement_timeout`
+ ///
+ /// Error Code `50004`
+ #[display(
+ fmt = "Internally, a database query timed out. This could be due to high server load, or because of a logic error resulting in a deadlock. If this issue persists after retrying, please notify a server administrator!"
+ )]
+ QueryTimeout,
+
/// `500 INTERNAL SERVER ERROR` variant returned if the server fails to acquire a database
/// connection
///
/// Error Code `50005`
#[display(fmt = "Failed to retrieve connection to the database. The server might be temporarily overloaded.")]
DatabaseConnectionError,
+
+ /// `503 SERVICE UNAVAILABLE` variant returned by all non-GET (e.g. all possible mutating) requests if the server is in maintenance mode.
+ ///
+ /// Error Core `50301`
+ #[display(fmt = "The website is currently in read-only maintenance mode.")]
+ ReadOnlyMaintenance,
+}
+
+impl CoreError {
+ pub fn internal_server_error(message: impl AsRef) -> CoreError {
+ error!("INTERNAL SERVER ERROR: {}", message.as_ref());
+
+ CoreError::InternalServerError
+ }
}
impl Error for CoreError {}
@@ -244,41 +262,21 @@ impl PointercrateError for CoreError {
CoreError::Ratelimited { .. } => 42900,
CoreError::InternalServerError { .. } => 50000,
CoreError::DatabaseError => 50003,
+ CoreError::QueryTimeout => 50004,
CoreError::DatabaseConnectionError => 50005,
+ CoreError::ReadOnlyMaintenance => 50301,
}
}
}
impl From for CoreError {
fn from(error: sqlx::Error) -> Self {
- match error {
- sqlx::Error::Database(database_error) => {
- let database_error = database_error.downcast::();
-
- error!("Database error: {:?}. ", database_error);
+ error!("Database error: {:?}. Backtrace:\n {}", error, std::backtrace::Backtrace::capture());
- CoreError::DatabaseError
- },
- sqlx::Error::PoolClosed | sqlx::Error::PoolTimedOut => {
- error!("Failed to acquire database connection");
-
- CoreError::DatabaseConnectionError
- },
- sqlx::Error::ColumnNotFound(column) => {
- format!("Invalid access to column {}, which does not exist", column);
-
- CoreError::DatabaseError
- },
- sqlx::Error::RowNotFound => {
- error!("Unhandled 'NotFound', this is a logic or data consistency error");
-
- CoreError::DatabaseError
- },
- _ => {
- error!("Database error: {:?}", error);
-
- CoreError::DatabaseError
- },
+ match error {
+ sqlx::Error::Database(err) if err.code().as_deref() == Some("57014") => CoreError::QueryTimeout,
+ sqlx::Error::PoolClosed | sqlx::Error::PoolTimedOut => CoreError::DatabaseConnectionError,
+ _ => CoreError::DatabaseError,
}
}
}
diff --git a/pointercrate-core/src/lib.rs b/pointercrate-core/src/lib.rs
index fdda6c278..caa449d46 100644
--- a/pointercrate-core/src/lib.rs
+++ b/pointercrate-core/src/lib.rs
@@ -2,6 +2,7 @@ pub mod audit;
pub mod config;
pub mod error;
pub mod etag;
+pub mod pagination;
pub mod permission;
pub mod pool;
pub mod util;
diff --git a/pointercrate-core/src/pagination.rs b/pointercrate-core/src/pagination.rs
new file mode 100644
index 000000000..a4e2a1787
--- /dev/null
+++ b/pointercrate-core/src/pagination.rs
@@ -0,0 +1,248 @@
+use std::fmt::{Debug, Display};
+
+use crate::{error::CoreError, util::non_nullable};
+use serde::{de::Error, Deserialize, Serialize};
+use sqlx::PgConnection;
+
+/// The maximal number of entries that can be requested per page via the `limit` parameter.
+pub const ENTRIES_PER_PAGE: i32 = 100;
+
+/// The default number of entries returned per page if the `limit` parameter was omited.
+///
+/// Try not to directly rely on this constant, and instead use `PaginationParameters::default()`
+pub const DEFAULT_ENTRIES_PER_PAGE: i32 = 50;
+
+#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, Copy)]
+pub struct PaginationParameters {
+ #[serde(default, deserialize_with = "from_str_non_nullable")]
+ pub before: Option,
+
+ #[serde(default, deserialize_with = "from_str_non_nullable")]
+ pub after: Option,
+
+ #[serde(
+ default = "default_limit",
+ deserialize_with = "from_str",
+ skip_serializing_if = "is_default_entries_per_page"
+ )]
+ pub limit: i32,
+}
+
+impl Default for PaginationParameters {
+ fn default() -> Self {
+ Self {
+ before: None,
+ after: None,
+ limit: DEFAULT_ENTRIES_PER_PAGE,
+ }
+ }
+}
+
+impl PaginationParameters {
+ pub fn validate(&self) -> Result<(), CoreError> {
+ if !(1..=ENTRIES_PER_PAGE).contains(&self.limit) {
+ return Err(CoreError::InvalidPaginationLimit);
+ }
+
+ if let (Some(after), Some(before)) = (self.before, self.after) {
+ if after < before {
+ return Err(CoreError::AfterSmallerBefore);
+ }
+ }
+
+ Ok(())
+ }
+
+ pub fn order(&self) -> &'static str {
+ if self.after.is_none() && self.before.is_some() {
+ "DESC"
+ } else {
+ "ASC"
+ }
+ }
+}
+
+/// Enum describing what is going on "around" a page returned by [`Pagination::page`].
+///
+/// Describes whether [`Pagination::Item`] matching all properties of a given [`Pagination`] exist
+/// with an id lower/larger than the smallest/largest on a given page
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+pub enum PageContext {
+ /// The page contains all possible items matching the given [`Pagination`] query.
+ /// No further pages exist.
+ ///
+ /// For example, given a list of ids such as `[1, 3, 5]`, a request such as `?after=0&before=6`
+ /// would return the page`[1, 3, 5]`, meaning this page is `Standalone`.
+ Standalone,
+
+ /// There exist more items matching the given [`Pagination`] query whose ids are less than
+ /// the smallest of this page.
+ ///
+ /// For example, given a list of ids such as `[1, 3, 5]`, a request such as `?after=1&before=6`
+ /// would return the page`[3, 5]`, meaning there exists a previous page containing just the item `1`.
+ HasPrevious,
+
+ /// There exist more items matching the given [`Pagination`] query whose ids are greater than
+ /// the largest of this page.
+ ///
+ /// For example, given a list of ids such as `[1, 3, 5]`, a request such as `?after=0&before=5`
+ /// would return the page`[1, 3]`, meaning there exists a next page containing just the item `5`.
+ HasNext,
+
+ /// There exist more items matching the given [`Pagination`] query, some whose ids are less than
+ /// the smallest of this page, and some whose ids are greater than the greatest of this page.
+ ///
+ /// For example, given a list of ids such as `[1, 3, 5]`, a request such as `?after=1&before=5`
+ /// would return the page`[3]`, meaning there exists a previous page containing just the item `1`,
+ /// and a next page containing just the item `5`.
+ HasPreviousAndNext,
+}
+
+impl PageContext {
+ pub fn has_next(&self) -> bool {
+ matches!(self, PageContext::HasNext | PageContext::HasPreviousAndNext)
+ }
+
+ pub fn has_previous(&self) -> bool {
+ matches!(self, PageContext::HasPrevious | PageContext::HasPreviousAndNext)
+ }
+}
+
+pub trait PaginationQuery: Serialize + Debug {
+ fn parameters(&self) -> PaginationParameters;
+ fn with_parameters(&self, parameters: PaginationParameters) -> Self;
+}
+
+#[allow(async_fn_in_trait)]
+pub trait Paginatable: Serialize + Sized {
+ /// Returns a page of objects matching the query described by tthe given [`PaginationQuery`].
+ ///
+ /// The returned list of objects must have the following properties:
+ /// - They are sorted in ascending order according to the value of [`pagination_id`].
+ /// - Their ids are consecutive, meaning if the object at index `i` in the list has ID `a`, and
+ /// the object at index `i + 1` has id `b`, then there exists no object also matching all conditions
+ /// of this `Pagination` in the _database_ with an ID `c` such that `a < c < b`.
+ /// - If the `after` parameter of the query's associated [`PaginationParameters`] is set, then the first
+ /// object in the returned list must have the smallest ID out of all objects matching the given
+ /// query greater than `after`.
+ /// - If the `after` parameter is not set, but `before` is, then the last object in the returned
+ /// list must have the greatest ID out of all objects matching the given query smaller than
+ /// `before`.
+ ///
+ /// The returned [`PageContext`] should describe whether more pages surrounding this page exist which
+ /// match all conditions of this [`Pagination`] object, with the exception of the `before` and `after` fields!
+ /// HOWEVER, if both `before` and `after` are set, then it should be [`PageContext::Standalone`].
+ ///
+ /// The number of items in the returned `Vec` must not exceed [`PaginationParameters::limit`].
+ async fn page(query: &Q, connection: &mut PgConnection) -> Result<(Vec, PageContext), sqlx::Error>;
+
+ async fn first_and_last(connection: &mut PgConnection) -> Result