From 5a6a22711913a08ddbfc9a7660f593ae6a2c4e71 Mon Sep 17 00:00:00 2001 From: asd-a Date: Fri, 9 May 2025 16:56:45 +0800 Subject: [PATCH 1/9] feat(algorithm): init --- src/app/algorithm/mod.rs | 16 ++++++++++++++++ src/app/mod.rs | 1 + 2 files changed, 17 insertions(+) create mode 100644 src/app/algorithm/mod.rs diff --git a/src/app/algorithm/mod.rs b/src/app/algorithm/mod.rs new file mode 100644 index 0000000..b73b40e --- /dev/null +++ b/src/app/algorithm/mod.rs @@ -0,0 +1,16 @@ + +struct User{ + id: u64, + availables: Vec, +} + +struct Spare{ + stamp: u64, + day: u64, +} + +// users: questionaire, spares +// return each user with the spares they can take with algorithm result +fn something(users: Vec, spares: Vec) -> Vec { + todo!() +} \ No newline at end of file diff --git a/src/app/mod.rs b/src/app/mod.rs index 1e5a7ae..aa5eca2 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -5,6 +5,7 @@ mod hash; mod sign; mod spare; mod user; +mod algorithm; use admin::AdminAPI; use api::{APICollection, API}; From c0c6cd566d4787181d3146a179b9f0deb6c136ee Mon Sep 17 00:00:00 2001 From: xiaohongrsx Date: Mon, 12 May 2025 19:08:41 +0800 Subject: [PATCH 2/9] feat(algorithm):use MCMF to distribute spare --- .vscode/settings.json | 98 +++++++++++++++++++++++++ 1.txt | 18 +++++ Cargo.lock | 149 +++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 ++ build.rs | 16 ++++- src/app/algorithm.rs | 57 +++++++++++++++ src/app/algorithm/mod.rs | 16 ----- src/app/hash.rs | 1 - src/cpp/distribute.h | 91 ++++++++++++++++++++++++ src/cpp/mcmf.h | 136 +++++++++++++++++++++++++++++++++++ src/main.rs | 1 - 11 files changed, 568 insertions(+), 19 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 1.txt create mode 100644 src/app/algorithm.rs delete mode 100644 src/app/algorithm/mod.rs create mode 100644 src/cpp/distribute.h create mode 100644 src/cpp/mcmf.h diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c43c36a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,98 @@ +{ + "files.associations": { + "vector": "cpp", + "iostream": "cpp", + "any": "cpp", + "array": "cpp", + "atomic": "cpp", + "barrier": "cpp", + "bit": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "cfenv": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "cinttypes": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "coroutine": "cpp", + "csetjmp": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cuchar": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "exception": "cpp", + "expected": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "source_location": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "format": "cpp", + "fstream": "cpp", + "future": "cpp", + "generator": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "latch": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "print": "cpp", + "ranges": "cpp", + "scoped_allocator": "cpp", + "semaphore": "cpp", + "shared_mutex": "cpp", + "span": "cpp", + "spanstream": "cpp", + "sstream": "cpp", + "stacktrace": "cpp", + "stdexcept": "cpp", + "stdfloat": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "syncstream": "cpp", + "text_encoding": "cpp", + "thread": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "valarray": "cpp", + "variant": "cpp", + "queue": "cpp" + } +} \ No newline at end of file diff --git a/1.txt b/1.txt new file mode 100644 index 0000000..31acdfb --- /dev/null +++ b/1.txt @@ -0,0 +1,18 @@ + Compiling api v0.1.0 (/home/renshixin/back-end/api) + Compiling backend v0.1.1 (/home/renshixin/back-end) +error: failed to run custom build command for `backend v0.1.1 (/home/renshixin/back-end)` + +Caused by: + process didn't exit successfully: `/home/renshixin/back-end/target/debug/build/backend-b7c7a75890c4f3da/build-script-build` (exit status: 1) + --- stdout + cargo:rerun-if-changed=migrations + + --- stderr + + error[cxxbridge]: using C++ vector by value is not supported + ┌─ src/app/algorithm.rs:12:9 + │ + 12 │ stamps: CxxVector, + │ ^^^^^^^^^^^^^^^^^^^^^^ using C++ vector by value is not supported + +warning: build failed, waiting for other jobs to finish... diff --git a/Cargo.lock b/Cargo.lock index da44afb..1e5b210 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + [[package]] name = "api" version = "0.1.0" @@ -154,6 +160,8 @@ dependencies = [ "argon2", "axum", "chrono", + "cxx", + "cxx-build", "hex", "hmac", "http-body-util", @@ -271,6 +279,43 @@ dependencies = [ "windows-link", ] +[[package]] +name = "clap" +version = "4.5.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120" +dependencies = [ + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "codespan-reporting" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" +dependencies = [ + "serde", + "termcolor", + "unicode-width", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -341,6 +386,65 @@ dependencies = [ "typenum", ] +[[package]] +name = "cxx" +version = "1.0.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a71ea7f29c73f7ffa64c50b83c9fe4d3a6d4be89a86b009eb80d5a6d3429d741" +dependencies = [ + "cc", + "cxxbridge-cmd", + "cxxbridge-flags", + "cxxbridge-macro", + "foldhash", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36a8232661d66dcf713394726157d3cfe0a89bfc85f52d6e9f9bbc2306797fe7" +dependencies = [ + "cc", + "codespan-reporting", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-cmd" +version = "1.0.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f44296c8693e9ea226a48f6a122727f77aa9e9e338380cb021accaeeb7ee279" +dependencies = [ + "clap", + "codespan-reporting", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42f69c181c176981ae44ba9876e2ea41ce8e574c296b38d06925ce9214fb8e4" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8faff5d4467e0709448187df29ccbf3b0982cc426ee444a193f87b11afb565a8" +dependencies = [ + "proc-macro2", + "quote", + "rustversion", + "syn", +] + [[package]] name = "der" version = "0.7.10" @@ -994,6 +1098,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "link-cplusplus" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6f6da007f968f9def0d65a05b187e2960183de70c160204ecfccf0ee330212" +dependencies = [ + "cc", +] + [[package]] name = "linux-raw-sys" version = "0.9.4" @@ -1380,6 +1493,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scratch" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f6280af86e5f559536da57a45ebc84948833b3bee313a7dd25232e09c878a52" + [[package]] name = "serde" version = "1.0.219" @@ -1743,6 +1862,12 @@ dependencies = [ "unicode-properties", ] +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "subtle" version = "2.6.1" @@ -1790,6 +1915,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "2.0.12" @@ -2043,6 +2177,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "url" version = "2.5.4" @@ -2198,6 +2338,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 3c1d79f..e3ff430 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,4 +23,8 @@ hmac = "0.12.1" hex = "0.4.3" sha2 = "0.10.8" chrono = "0.4.33" +cxx = "1.0" + +[build-dependencies] +cxx-build = "1.0" iso8601 = { version = "0.6.2", features = ["chrono", "serde"] } diff --git a/build.rs b/build.rs index 327a3b4..7f2f30e 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,18 @@ fn main() { // trigger recompilation when a new migration is added - println!("cargo::rerun-if-changed=migrations"); + println!("cargo:rerun-if-changed=migrations"); + + // cxx build for C++ interop + + cxx_build::bridge("src/app/algorithm.rs") + .file("src/cpp/distribute.h") + .file("src/cpp/mcmf.h") + .include("src/cpp") + .flag_if_supported("-std=c++17") + .compile("cxx-demo"); + + // trigger rebuild when Rust bridge or C++ headers change + println!("cargo:rerun-if-changed=src/app/algorithm/algo.rs"); + println!("cargo:rerun-if-changed=src/cpp/distribute.h"); + println!("cargo:rerun-if-changed=src/cpp/mcmf.h"); } diff --git a/src/app/algorithm.rs b/src/app/algorithm.rs new file mode 100644 index 0000000..f1fe303 --- /dev/null +++ b/src/app/algorithm.rs @@ -0,0 +1,57 @@ +use cxx::{CxxVector, UniquePtr}; + +#[cxx::bridge] +mod ffi { + #[derive(Clone)] + struct User { + id: u64, + stamps: CxxVector, + } + + #[derive(Clone)] + struct Spare { + stamp: u64, + day: u64, + } + + unsafe extern "C++" { + include!("distribute.h"); + + fn distribute( + users: &CxxVector, + spares: &CxxVector, + ) -> UniquePtr>; + } +} + +pub fn distribute( + users: Vec, + spares: Vec, +) -> Vec { + let mut cv_users = CxxVector::::new(); + for u in users { + let mut cv_stamps = CxxVector::::new(); + for s in u.stamps { + cv_stamps.push(s); + } + cv_users.push( ffi::User { id: u.id, stamps: cv_stamps } ); + } + + let mut cv_spares = CxxVector::::new(); + for s in spares { + cv_spares.push( ffi::Spare { stamp: s.stamp, day: s.day } ); + } + + let uptr: UniquePtr> = ffi::distribute(&cv_users, &cv_spares); + let cv_res = uptr.as_ref().expect("ffi::distribute returned null"); + + let mut out = Vec::with_capacity(cv_res.len()); + for ru in cv_res.iter() { + let mut stamps = Vec::with_capacity(ru.stamps.len()); + for &st in ru.stamps.iter() { + stamps.push(st); + } + out.push(User { id: ru.id, stamps }); + } + out +} diff --git a/src/app/algorithm/mod.rs b/src/app/algorithm/mod.rs deleted file mode 100644 index b73b40e..0000000 --- a/src/app/algorithm/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ - -struct User{ - id: u64, - availables: Vec, -} - -struct Spare{ - stamp: u64, - day: u64, -} - -// users: questionaire, spares -// return each user with the spares they can take with algorithm result -fn something(users: Vec, spares: Vec) -> Vec { - todo!() -} \ No newline at end of file diff --git a/src/app/hash.rs b/src/app/hash.rs index 3faed1e..82e2373 100644 --- a/src/app/hash.rs +++ b/src/app/hash.rs @@ -1,5 +1,4 @@ use argon2::{password_hash::SaltString, Argon2, PasswordHash, PasswordHasher, PasswordVerifier}; - #[derive(Debug, Clone)] pub struct Hasher { salt: SaltString, diff --git a/src/cpp/distribute.h b/src/cpp/distribute.h new file mode 100644 index 0000000..c8cedd6 --- /dev/null +++ b/src/cpp/distribute.h @@ -0,0 +1,91 @@ +#include +#include +#include "mcmf.h" +#include +#include +using std::vector; +using std::byte; +using std::runtime_error; + + +struct User { + uint64_t id; + vector stamps; +}; +struct Spare { + uint64_t stamp, day; +}; + +struct distribution { + vector user; + vector spare; + void init(const vector &users, const vector &spares, int64_t spare_size) { + if (spare_size != (int64_t) spares.size()) { + throw runtime_error("spare_size != spares.size()"); + } + user.clear(); + spare.clear(); + user.shrink_to_fit(); + spare.shrink_to_fit(); + user.resize(users.size()); + spare.resize(spare_size); + for (size_t i = 0; i < (size_t) spare_size; i++) { + spare[i] = spares[i]; + } + for (size_t i = 0; i < users.size(); i++) { + user[i] = users[i]; + } + } + vector solve() { + mcmf::init(); + int32_t s = 1; + int32_t n = user.size() * 8 + spare.size() + 2; + int32_t t = n; + mcmf::s = s; + mcmf::t = t; + mcmf::n = n; + mcmf::set_n(n); + for (size_t i = 0; i < user.size(); i++) { + mcmf::addEdge(s, i + 2, 0, 1, 20); + mcmf::addEdge(s, i + 2, 0, 1, 50); + mcmf::addEdge(s, i + 2, 0, 1, 100); + } + for (size_t i = 1; i <= 7; ++i) { + for (size_t j = 0; j < user.size(); j++) { + mcmf::addEdge(j + 2, j + 2 + i * user.size(), 0, 1, 0); + } + } + for (size_t i = 0; i < user.size(); ++i) { + for (size_t j = 0; j < user[i].stamps.size(); ++j) { + mcmf::addEdge(i + 2 + (spare[user[i].stamps[j]].day + 1) * user.size(), n - spare.size() + spare[user[i].stamps[j]].stamp, 0, 1, 0); + } + } + for (size_t i = 0; i < spare.size(); ++i) { + mcmf::addEdge(n - spare.size() + i, t, 0, 1, 0); + } + mcmf::solve(); + int64_t a0 = 1 + user.size(); + int64_t a1 = 1 + user.size() * 8; + int64_t a2 = n - 1; + vector res(user.size()); + for (size_t i = 2; i < mcmf::e.size(); ++i) { + if (mcmf::e[i].u <= a1 && mcmf::e[i].u > a0 && mcmf::e[i].v <= a2 && mcmf::e[i].v > a1) { + res[mcmf::e[i].u - a0 - 1].stamps.push_back(mcmf::e[i].v - a2 - 1); + } + } + for (size_t i = 0; i < user.size(); ++i) { + res[i].id = user[i].id; + std::sort(res[i].stamps.begin(), res[i].stamps.end()); + } + return res; + } +}; + + +std::unique_ptr> distribute(const vector &users, const vector &spares) { + distribution sol; + sol.init(users, spares, spares.size()); + vector method = sol.solve(); + return std::make_unique>(std::move(method)); + +} diff --git a/src/cpp/mcmf.h b/src/cpp/mcmf.h new file mode 100644 index 0000000..2d9cd0e --- /dev/null +++ b/src/cpp/mcmf.h @@ -0,0 +1,136 @@ +#pragma once + +#include +#include +#include +#include +#include + + +using std::min; +using std::vector; +using std::queue; + +namespace mcmf { + const int INF = 0x3f3f3f3f; + int n, m, s, t, maxflow, cost; + int in, S, T; + int a0, a1; + struct E { + int u, next, v, w, c; + }; + vector d, incf, pre, head, a, vis; + vector e; + queue q; + void inline add(int u, int v, int w, int c) { + e.push_back({ u, head[u], v, w, c }); + head[u] = e.size() - 1; + } + void inline addE(int u, int v, int w, int c) { + add(u, v, w, c); + add(v, u, 0, -c); + } + bool spfa() { + std::fill(vis.begin(), vis.end(), 0); + std::fill(d.begin(), d.end(), INF); + q.push(S); + d[S] = 0; incf[S] = 2e9; + while (q.size()) { + int u = q.front(); q.pop(); vis[u] = 0; + for (int i = head[u]; i; i = e[i].next) { + int v = e[i].v; + if (e[i].w && d[u] + e[i].c < d[v]) { + d[v] = d[u] + e[i].c; + pre[v] = i; + incf[v] = min(incf[u], e[i].w); + if (!vis[v]) { + q.push(v); + vis[v] = 1; + } + } + } + } + return d[T] != INF; + } + void update() { + int x = T; + while (x != S) { + int i = pre[x]; + e[i].w -= incf[T], e[i ^ 1].w += incf[T]; + x = e[i ^ 1].v; + } + maxflow += incf[T]; + cost += d[T] * incf[T]; + } + + void inline addEdge(int u, int v, int l, int d, int c) { + a[v] += l, a[u] -= l; + addE(u, v, d - l, c); + } + + void inline work() { + while (spfa()) update(); + } + + void inline ADD(int u, int v, int w, int c) { + if (c >= 0) addEdge(u, v, 0, w, c); + else a[v] += w, a[u] -= w, addEdge(v, u, 0, w, -c), a1 += c * w; + } + + void inline solve() { + S = n + 1; + T = n + 2; + for (int i = 1; i <= n; i++) { + if (!a[i]) continue; + if (a[i] > 0) addEdge(S, i, 0, a[i], 0); + else addEdge(i, T, 0, -a[i], 0); + } + addEdge(T, S, 0, INF, 0); + work(); + S = s, T = t; + a1 += cost; + maxflow = cost = 0; + e[e.size() - 1].w = 0; + e[e.size() - 2].w = 0; + work(); + a0 += maxflow, a1 += cost; + } + void init() { + n = 0; + m = 0; + s = 0; + t = 0; + maxflow = 0; + cost = 0; + in = 0; + S = 0; + T = 0; + a0 = 0; + a1 = 0; + d.clear(); + d.shrink_to_fit(); + incf.clear(); + incf.shrink_to_fit(); + pre.clear(); + pre.shrink_to_fit(); + head.clear(); + head.shrink_to_fit(); + a.clear(); + a.shrink_to_fit(); + vis.clear(); + vis.shrink_to_fit(); + e.clear(); + e.shrink_to_fit(); + while (q.size()) q.pop(); + e.push_back({0, 0, 0, 0, 0}); + e.push_back({0, 0, 0, 0, 0}); + } + void set_n(int32_t n) { + d.resize(n + 3, 0); + incf.resize(n + 3, 0); + pre.resize(n + 3, 0); + head.resize(n + 3, 0); + a.resize(n + 3, 0); + vis.resize(n + 3, 0); + } +} diff --git a/src/main.rs b/src/main.rs index 0b18311..0b52b6a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ use app::{app, connect_pool}; - mod app; const DATABASE_URL: &str = "sqlite://db/sqlite.db"; From 88822da798a1deefd095835554c178721524c9d4 Mon Sep 17 00:00:00 2001 From: xiaohongrsx Date: Tue, 13 May 2025 10:51:18 +0800 Subject: [PATCH 3/9] feat(algorithm):use rust rewrite mcmf and distribute --- .vscode/settings.json | 98 ----------- 1.txt | 18 -- Cargo.lock | 8 +- Cargo.toml | 2 +- build.rs | 13 -- src/app/algorithm.rs | 384 +++++++++++++++++++++++++++++++++++++----- src/cpp/distribute.h | 91 ---------- src/cpp/mcmf.h | 136 --------------- 8 files changed, 350 insertions(+), 400 deletions(-) delete mode 100644 .vscode/settings.json delete mode 100644 1.txt delete mode 100644 src/cpp/distribute.h delete mode 100644 src/cpp/mcmf.h diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index c43c36a..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "files.associations": { - "vector": "cpp", - "iostream": "cpp", - "any": "cpp", - "array": "cpp", - "atomic": "cpp", - "barrier": "cpp", - "bit": "cpp", - "bitset": "cpp", - "cctype": "cpp", - "cfenv": "cpp", - "charconv": "cpp", - "chrono": "cpp", - "cinttypes": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "codecvt": "cpp", - "compare": "cpp", - "complex": "cpp", - "concepts": "cpp", - "condition_variable": "cpp", - "coroutine": "cpp", - "csetjmp": "cpp", - "csignal": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cuchar": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "forward_list": "cpp", - "list": "cpp", - "map": "cpp", - "set": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "unordered_set": "cpp", - "exception": "cpp", - "expected": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "optional": "cpp", - "random": "cpp", - "ratio": "cpp", - "regex": "cpp", - "source_location": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "format": "cpp", - "fstream": "cpp", - "future": "cpp", - "generator": "cpp", - "initializer_list": "cpp", - "iomanip": "cpp", - "iosfwd": "cpp", - "istream": "cpp", - "latch": "cpp", - "limits": "cpp", - "mutex": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "print": "cpp", - "ranges": "cpp", - "scoped_allocator": "cpp", - "semaphore": "cpp", - "shared_mutex": "cpp", - "span": "cpp", - "spanstream": "cpp", - "sstream": "cpp", - "stacktrace": "cpp", - "stdexcept": "cpp", - "stdfloat": "cpp", - "stop_token": "cpp", - "streambuf": "cpp", - "syncstream": "cpp", - "text_encoding": "cpp", - "thread": "cpp", - "typeindex": "cpp", - "typeinfo": "cpp", - "valarray": "cpp", - "variant": "cpp", - "queue": "cpp" - } -} \ No newline at end of file diff --git a/1.txt b/1.txt deleted file mode 100644 index 31acdfb..0000000 --- a/1.txt +++ /dev/null @@ -1,18 +0,0 @@ - Compiling api v0.1.0 (/home/renshixin/back-end/api) - Compiling backend v0.1.1 (/home/renshixin/back-end) -error: failed to run custom build command for `backend v0.1.1 (/home/renshixin/back-end)` - -Caused by: - process didn't exit successfully: `/home/renshixin/back-end/target/debug/build/backend-b7c7a75890c4f3da/build-script-build` (exit status: 1) - --- stdout - cargo:rerun-if-changed=migrations - - --- stderr - - error[cxxbridge]: using C++ vector by value is not supported - ┌─ src/app/algorithm.rs:12:9 - │ - 12 │ stamps: CxxVector, - │ ^^^^^^^^^^^^^^^^^^^^^^ using C++ vector by value is not supported - -warning: build failed, waiting for other jobs to finish... diff --git a/Cargo.lock b/Cargo.lock index 1e5b210..7ec3cbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,9 +252,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.19" +version = "1.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" +checksum = "32db95edf998450acc7881c932f94cd9b05c87b4b2599e8bab064753da4acfd1" dependencies = [ "shlex", ] @@ -1566,9 +1566,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", diff --git a/Cargo.toml b/Cargo.toml index e3ff430..461074c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ hyper-util = { version = "0.1.10", features = ["full"] } argon2 = "0.5.3" hmac = "0.12.1" hex = "0.4.3" -sha2 = "0.10.8" +sha2 = "0.10.9" chrono = "0.4.33" cxx = "1.0" diff --git a/build.rs b/build.rs index 7f2f30e..e140e3d 100644 --- a/build.rs +++ b/build.rs @@ -2,17 +2,4 @@ fn main() { // trigger recompilation when a new migration is added println!("cargo:rerun-if-changed=migrations"); - // cxx build for C++ interop - - cxx_build::bridge("src/app/algorithm.rs") - .file("src/cpp/distribute.h") - .file("src/cpp/mcmf.h") - .include("src/cpp") - .flag_if_supported("-std=c++17") - .compile("cxx-demo"); - - // trigger rebuild when Rust bridge or C++ headers change - println!("cargo:rerun-if-changed=src/app/algorithm/algo.rs"); - println!("cargo:rerun-if-changed=src/cpp/distribute.h"); - println!("cargo:rerun-if-changed=src/cpp/mcmf.h"); } diff --git a/src/app/algorithm.rs b/src/app/algorithm.rs index f1fe303..9f28fe0 100644 --- a/src/app/algorithm.rs +++ b/src/app/algorithm.rs @@ -1,57 +1,363 @@ -use cxx::{CxxVector, UniquePtr}; +use std::collections::VecDeque; +use std::cmp::min; -#[cxx::bridge] -mod ffi { - #[derive(Clone)] - struct User { - id: u64, - stamps: CxxVector, +#[derive(Clone, Debug)] +pub struct Edge { + pub u: i32, + pub next: usize, + pub v: i32, + pub w: i32, + pub c: i32, +} + +pub struct Mcmf { + pub n: i32, + pub m: i32, + pub s: i32, + pub t: i32, + pub maxflow: i32, + pub cost: i32, + pub in_field: i32, + pub S: i32, + pub T: i32, + pub a0: i32, + pub a1: i32, + pub d: Vec, + pub incf: Vec, + pub pre: Vec, + pub head: Vec, + pub a: Vec, + pub vis: Vec, + pub e: Vec, + pub q: VecDeque, +} + +impl Mcmf { + pub const INF: i32 = 0x3f3f3f3f; + + pub fn new() -> Self { + let mut m = Mcmf { + n: 0, + m: 0, + s: 0, + t: 0, + maxflow: 0, + cost: 0, + in_field: 0, + S: 0, + T: 0, + a0: 0, + a1: 0, + d: Vec::new(), + incf: Vec::new(), + pre: Vec::new(), + head: Vec::new(), + a: Vec::new(), + vis: Vec::new(), + e: Vec::new(), + q: VecDeque::new(), + }; + m.e.push(Edge { u: 0, next: 0, v: 0, w: 0, c: 0 }); + m.e.push(Edge { u: 0, next: 0, v: 0, w: 0, c: 0 }); + m + } + + pub fn init(&mut self) { + self.n = 0; + self.m = 0; + self.s = 0; + self.t = 0; + self.maxflow = 0; + self.cost = 0; + self.in_field = 0; + self.S = 0; + self.T = 0; + self.a0 = 0; + self.a1 = 0; + self.d.clear(); + self.incf.clear(); + self.pre.clear(); + self.head.clear(); + self.a.clear(); + self.vis.clear(); + self.e.truncate(2); + self.q.clear(); } - #[derive(Clone)] - struct Spare { - stamp: u64, - day: u64, + pub fn set_n(&mut self, n: i32) { + let sz = (n + 3) as usize; + self.d.resize(sz, 0); + self.incf.resize(sz, 0); + self.pre.resize(sz, 0); + self.head.resize(sz, 0); + self.a.resize(sz, 0); + self.vis.resize(sz, false); } - unsafe extern "C++" { - include!("distribute.h"); + fn add(&mut self, u: i32, v: i32, w: i32, c: i32) { + let idx = self.e.len(); + self.e.push(Edge { u, next: self.head[u as usize], v, w, c }); + self.head[u as usize] = idx; + } + + fn add_e(&mut self, u: i32, v: i32, w: i32, c: i32) { + self.add(u, v, w, c); + self.add(v, u, 0, -c); + } - fn distribute( - users: &CxxVector, - spares: &CxxVector, - ) -> UniquePtr>; + pub fn add_edge(&mut self, u: i32, v: i32, l: i32, d: i32, c: i32) { + self.a[v as usize] += l; + self.a[u as usize] -= l; + self.add_e(u, v, d - l, c); + } + + pub fn add_signed(&mut self, u: i32, v: i32, w: i32, c: i32) { + if c >= 0 { + self.add_edge(u, v, 0, w, c); + } else { + self.a[v as usize] += w; + self.a[u as usize] -= w; + self.add_edge(v, u, 0, w, -c); + self.a1 += c * w; + } + } + + fn spfa(&mut self) -> bool { + self.q.clear(); + self.vis.fill(false); + self.d.fill(Self::INF); + self.q.push_back(self.S); + self.d[self.S as usize] = 0; + self.incf[self.S as usize] = std::i32::MAX; + while let Some(u) = self.q.pop_front() { + self.vis[u as usize] = false; + let mut i = self.head[u as usize]; + while i != 0 { + let e = &self.e[i]; + if e.w > 0 && self.d[u as usize] + e.c < self.d[e.v as usize] { + self.d[e.v as usize] = self.d[u as usize] + e.c; + self.pre[e.v as usize] = i; + self.incf[e.v as usize] = min(self.incf[u as usize], e.w); + if !self.vis[e.v as usize] { + self.vis[e.v as usize] = true; + self.q.push_back(e.v); + } + } + i = e.next; + } + } + self.d[self.T as usize] != Self::INF + } + + /// 沿增广路更新流与费用 + fn update(&mut self) { + let mut x = self.T; + let flow = self.incf[self.T as usize]; + while x != self.S { + let i = self.pre[x as usize]; + self.e[i].w -= flow; + let ri = i ^ 1; + self.e[ri].w += flow; + x = self.e[ri].v; + } + self.maxflow += flow; + self.cost += self.d[self.T as usize] * flow; + } + + /// 主循环:不断 SPFA + 更新 + pub fn work(&mut self) { + while self.spfa() { + self.update(); + } + } + + /// 求解 + pub fn solve(&mut self) { + // 构造超级源汇 + self.S = self.n + 1; + self.T = self.n + 2; + for i in 1..=self.n { + let ai = self.a[i as usize]; + if ai > 0 { + self.add_edge(self.S, i, 0, ai, 0); + } else if ai < 0 { + self.add_edge(i, self.T, 0, -ai, 0); + } + } + // 保证原图中循环流可行 + self.add_edge(self.T, self.S, 0, Self::INF, 0); + self.work(); + + // 切换为真正的源汇 + self.S = self.s; + self.T = self.t; + self.a1 += self.cost; + self.maxflow = 0; + self.cost = 0; + // 将最后两条边容量置零 + let len = self.e.len(); + self.e[len - 1].w = 0; + self.e[len - 2].w = 0; + self.work(); + self.a0 += self.maxflow; + self.a1 += self.cost; } } -pub fn distribute( - users: Vec, - spares: Vec, -) -> Vec { - let mut cv_users = CxxVector::::new(); - for u in users { - let mut cv_stamps = CxxVector::::new(); - for s in u.stamps { - cv_stamps.push(s); + +use std::error::Error; + +#[derive(Clone, Debug)] +pub struct User { + pub id: u64, + pub stamps: Vec, +} + +#[derive(Clone, Debug)] +pub struct Spare { + pub stamp: u64, + pub day: u64, +} + +pub struct Distribution { + user: Vec, + spare: Vec, + mf: Mcmf, +} + +impl Distribution { + pub fn new() -> Self { + Distribution { + user: Vec::new(), + spare: Vec::new(), + mf: Mcmf::new(), } - cv_users.push( ffi::User { id: u.id, stamps: cv_stamps } ); } - let mut cv_spares = CxxVector::::new(); - for s in spares { - cv_spares.push( ffi::Spare { stamp: s.stamp, day: s.day } ); + pub fn init( + &mut self, + users: &[User], + spares: &[Spare], + spare_size: usize, + ) -> Result<(), Box> { + if spare_size != spares.len() { + return Err("spare_size != spares.len()".into()); + } + self.user.clear(); + self.spare.clear(); + self.user.reserve(users.len()); + self.spare.reserve(spare_size); + self.user.extend_from_slice(users); + self.spare.extend_from_slice(spares); + Ok(()) } - let uptr: UniquePtr> = ffi::distribute(&cv_users, &cv_spares); - let cv_res = uptr.as_ref().expect("ffi::distribute returned null"); + pub fn solve(&mut self) -> Vec { + self.mf.init(); + let s = 1; + let n_nodes = (self.user.len() * 8) as i32 + self.spare.len() as i32 + 2; + let t = n_nodes; + self.mf.n = n_nodes; + self.mf.s = s; + self.mf.t = t; + self.mf.set_n(n_nodes); - let mut out = Vec::with_capacity(cv_res.len()); - for ru in cv_res.iter() { - let mut stamps = Vec::with_capacity(ru.stamps.len()); - for &st in ru.stamps.iter() { - stamps.push(st); + for i in 0..self.user.len() { + let u = (i + 2) as i32; + self.mf.add_edge(s, u, 0, 1, 20); + self.mf.add_edge(s, u, 0, 1, 50); + self.mf.add_edge(s, u, 0, 1, 100); + } + for day in 1..=7 { + for j in 0..self.user.len() { + let from = (j + 2) as i32; + let to = (j + 2 + day * self.user.len()) as i32; + self.mf.add_edge(from, to, 0, 1, 0); + } + } + for (i, user) in self.user.iter().enumerate() { + for &stamp in &user.stamps { + let from = (i as u64 + 2 + (self.spare[stamp as usize].day + 1) * self.user.len() as u64) as i32; + let to = n_nodes - self.spare.len() as i32 + self.spare[stamp as usize].stamp as i32; + self.mf.add_edge(from, to, 0, 1, 0); + } + } + for i in 0..self.spare.len() { + let from = n_nodes - self.spare.len() as i32 + i as i32; + self.mf.add_edge(from, t, 0, 1, 0); + } + self.mf.solve(); + let a0 = 1 + self.user.len() as i64; + let a1 = 1 + (self.user.len() * 8) as i64; + let a2 = (self.mf.n - 1) as i64; + let mut res = vec![User { id: 0, stamps: Vec::new() }; self.user.len()]; + for e in &self.mf.e { + let u = e.u as i64; + let v = e.v as i64; + if u > a0 && u <= a1 && v > a1 && v <= a2 { + let idx = (u - a0 - 1) as usize; + let stamp = (v - a2 - 1) as u64; + res[idx].stamps.push(stamp); + } + } + for (i, user) in self.user.iter().enumerate() { + res[i].id = user.id; + res[i].stamps.sort_unstable(); } - out.push(User { id: ru.id, stamps }); + res } - out } + +pub fn distribute(users: Vec, spares: Vec) -> Vec { + let mut sol = Distribution::new(); + sol.init(&users, &spares, spares.len()) + .expect("spare_size must equal spares.len()"); + sol.solve() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_mcmf_sample1() { + let mut mf = Mcmf::new(); + mf.n = 4; + mf.s = 4; + mf.t = 3; + mf.set_n(4); + + mf.add_signed(4, 2, 30, 2); + mf.add_signed(4, 3, 20, 3); + mf.add_signed(2, 3, 20, 1); + mf.add_signed(2, 1, 30, 9); + mf.add_signed(1, 3, 40, 5); + + mf.solve(); + + assert_eq!(mf.a0, 50, "期望最大流 a0 = 50,但实际是 {}", mf.a0); + assert_eq!(mf.a1, 280, "期望最小费用 a1 = 280,但实际是 {}", mf.a1); + } + #[test] + fn test_mcmf_sample2() { + let mut mf = Mcmf::new(); + mf.n = 5; + mf.s = 1; + mf.t = 5; + mf.set_n(5); + + mf.add_signed(1, 3, 2, 4); + mf.add_signed(1, 2, 2, 3); + mf.add_signed(3, 5, 2, 2); + mf.add_signed(3, 2, 1, -1); + mf.add_signed(2, 4, 2, -2); + mf.add_signed(4, 3, 1, -1); + mf.add_signed(4, 5, 1, 3); + + mf.solve(); + + assert_eq!(mf.a0, 3, "期望最大流 a0 = 3,但实际是 {}", mf.a0); + assert_eq!(mf.a1, 12, "期望最小费用 a1 = 12,但实际是 {}", mf.a1); + } + +} \ No newline at end of file diff --git a/src/cpp/distribute.h b/src/cpp/distribute.h deleted file mode 100644 index c8cedd6..0000000 --- a/src/cpp/distribute.h +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include -#include "mcmf.h" -#include -#include -using std::vector; -using std::byte; -using std::runtime_error; - - -struct User { - uint64_t id; - vector stamps; -}; -struct Spare { - uint64_t stamp, day; -}; - -struct distribution { - vector user; - vector spare; - void init(const vector &users, const vector &spares, int64_t spare_size) { - if (spare_size != (int64_t) spares.size()) { - throw runtime_error("spare_size != spares.size()"); - } - user.clear(); - spare.clear(); - user.shrink_to_fit(); - spare.shrink_to_fit(); - user.resize(users.size()); - spare.resize(spare_size); - for (size_t i = 0; i < (size_t) spare_size; i++) { - spare[i] = spares[i]; - } - for (size_t i = 0; i < users.size(); i++) { - user[i] = users[i]; - } - } - vector solve() { - mcmf::init(); - int32_t s = 1; - int32_t n = user.size() * 8 + spare.size() + 2; - int32_t t = n; - mcmf::s = s; - mcmf::t = t; - mcmf::n = n; - mcmf::set_n(n); - for (size_t i = 0; i < user.size(); i++) { - mcmf::addEdge(s, i + 2, 0, 1, 20); - mcmf::addEdge(s, i + 2, 0, 1, 50); - mcmf::addEdge(s, i + 2, 0, 1, 100); - } - for (size_t i = 1; i <= 7; ++i) { - for (size_t j = 0; j < user.size(); j++) { - mcmf::addEdge(j + 2, j + 2 + i * user.size(), 0, 1, 0); - } - } - for (size_t i = 0; i < user.size(); ++i) { - for (size_t j = 0; j < user[i].stamps.size(); ++j) { - mcmf::addEdge(i + 2 + (spare[user[i].stamps[j]].day + 1) * user.size(), n - spare.size() + spare[user[i].stamps[j]].stamp, 0, 1, 0); - } - } - for (size_t i = 0; i < spare.size(); ++i) { - mcmf::addEdge(n - spare.size() + i, t, 0, 1, 0); - } - mcmf::solve(); - int64_t a0 = 1 + user.size(); - int64_t a1 = 1 + user.size() * 8; - int64_t a2 = n - 1; - vector res(user.size()); - for (size_t i = 2; i < mcmf::e.size(); ++i) { - if (mcmf::e[i].u <= a1 && mcmf::e[i].u > a0 && mcmf::e[i].v <= a2 && mcmf::e[i].v > a1) { - res[mcmf::e[i].u - a0 - 1].stamps.push_back(mcmf::e[i].v - a2 - 1); - } - } - for (size_t i = 0; i < user.size(); ++i) { - res[i].id = user[i].id; - std::sort(res[i].stamps.begin(), res[i].stamps.end()); - } - return res; - } -}; - - -std::unique_ptr> distribute(const vector &users, const vector &spares) { - distribution sol; - sol.init(users, spares, spares.size()); - vector method = sol.solve(); - return std::make_unique>(std::move(method)); - -} diff --git a/src/cpp/mcmf.h b/src/cpp/mcmf.h deleted file mode 100644 index 2d9cd0e..0000000 --- a/src/cpp/mcmf.h +++ /dev/null @@ -1,136 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - - -using std::min; -using std::vector; -using std::queue; - -namespace mcmf { - const int INF = 0x3f3f3f3f; - int n, m, s, t, maxflow, cost; - int in, S, T; - int a0, a1; - struct E { - int u, next, v, w, c; - }; - vector d, incf, pre, head, a, vis; - vector e; - queue q; - void inline add(int u, int v, int w, int c) { - e.push_back({ u, head[u], v, w, c }); - head[u] = e.size() - 1; - } - void inline addE(int u, int v, int w, int c) { - add(u, v, w, c); - add(v, u, 0, -c); - } - bool spfa() { - std::fill(vis.begin(), vis.end(), 0); - std::fill(d.begin(), d.end(), INF); - q.push(S); - d[S] = 0; incf[S] = 2e9; - while (q.size()) { - int u = q.front(); q.pop(); vis[u] = 0; - for (int i = head[u]; i; i = e[i].next) { - int v = e[i].v; - if (e[i].w && d[u] + e[i].c < d[v]) { - d[v] = d[u] + e[i].c; - pre[v] = i; - incf[v] = min(incf[u], e[i].w); - if (!vis[v]) { - q.push(v); - vis[v] = 1; - } - } - } - } - return d[T] != INF; - } - void update() { - int x = T; - while (x != S) { - int i = pre[x]; - e[i].w -= incf[T], e[i ^ 1].w += incf[T]; - x = e[i ^ 1].v; - } - maxflow += incf[T]; - cost += d[T] * incf[T]; - } - - void inline addEdge(int u, int v, int l, int d, int c) { - a[v] += l, a[u] -= l; - addE(u, v, d - l, c); - } - - void inline work() { - while (spfa()) update(); - } - - void inline ADD(int u, int v, int w, int c) { - if (c >= 0) addEdge(u, v, 0, w, c); - else a[v] += w, a[u] -= w, addEdge(v, u, 0, w, -c), a1 += c * w; - } - - void inline solve() { - S = n + 1; - T = n + 2; - for (int i = 1; i <= n; i++) { - if (!a[i]) continue; - if (a[i] > 0) addEdge(S, i, 0, a[i], 0); - else addEdge(i, T, 0, -a[i], 0); - } - addEdge(T, S, 0, INF, 0); - work(); - S = s, T = t; - a1 += cost; - maxflow = cost = 0; - e[e.size() - 1].w = 0; - e[e.size() - 2].w = 0; - work(); - a0 += maxflow, a1 += cost; - } - void init() { - n = 0; - m = 0; - s = 0; - t = 0; - maxflow = 0; - cost = 0; - in = 0; - S = 0; - T = 0; - a0 = 0; - a1 = 0; - d.clear(); - d.shrink_to_fit(); - incf.clear(); - incf.shrink_to_fit(); - pre.clear(); - pre.shrink_to_fit(); - head.clear(); - head.shrink_to_fit(); - a.clear(); - a.shrink_to_fit(); - vis.clear(); - vis.shrink_to_fit(); - e.clear(); - e.shrink_to_fit(); - while (q.size()) q.pop(); - e.push_back({0, 0, 0, 0, 0}); - e.push_back({0, 0, 0, 0, 0}); - } - void set_n(int32_t n) { - d.resize(n + 3, 0); - incf.resize(n + 3, 0); - pre.resize(n + 3, 0); - head.resize(n + 3, 0); - a.resize(n + 3, 0); - vis.resize(n + 3, 0); - } -} From 3e868559730eb4b3ff5d920061e1ed135b5529c2 Mon Sep 17 00:00:00 2001 From: xiaohongrsx Date: Mon, 19 May 2025 02:06:05 +0800 Subject: [PATCH 4/9] fix(algorithm): resolve index-out-of-bounds in solve and add unit test --- Cargo.lock | 4 + Cargo.toml | 2 + src/app/algorithm.rs | 179 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 149 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ec3cbf..5e0a3eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,7 +166,11 @@ dependencies = [ "hmac", "http-body-util", "hyper-util", +<<<<<<< HEAD "iso8601", +======= + "rand", +>>>>>>> 4c6697d (fix(algorithm): resolve index-out-of-bounds in solve and add unit test) "serde", "serde_json", "sha2", diff --git a/Cargo.toml b/Cargo.toml index 461074c..50f8cb8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,3 +28,5 @@ cxx = "1.0" [build-dependencies] cxx-build = "1.0" iso8601 = { version = "0.6.2", features = ["chrono", "serde"] } + +rand = "0.8.5" \ No newline at end of file diff --git a/src/app/algorithm.rs b/src/app/algorithm.rs index 9f28fe0..ad2e77d 100644 --- a/src/app/algorithm.rs +++ b/src/app/algorithm.rs @@ -1,5 +1,5 @@ -use std::collections::VecDeque; use std::cmp::min; +use std::collections::VecDeque; #[derive(Clone, Debug)] pub struct Edge { @@ -18,8 +18,8 @@ pub struct Mcmf { pub maxflow: i32, pub cost: i32, pub in_field: i32, - pub S: i32, - pub T: i32, + pub ss: i32, + pub tt: i32, pub a0: i32, pub a1: i32, pub d: Vec, @@ -44,8 +44,8 @@ impl Mcmf { maxflow: 0, cost: 0, in_field: 0, - S: 0, - T: 0, + ss: 0, + tt: 0, a0: 0, a1: 0, d: Vec::new(), @@ -57,8 +57,20 @@ impl Mcmf { e: Vec::new(), q: VecDeque::new(), }; - m.e.push(Edge { u: 0, next: 0, v: 0, w: 0, c: 0 }); - m.e.push(Edge { u: 0, next: 0, v: 0, w: 0, c: 0 }); + m.e.push(Edge { + u: 0, + next: 0, + v: 0, + w: 0, + c: 0, + }); + m.e.push(Edge { + u: 0, + next: 0, + v: 0, + w: 0, + c: 0, + }); m } @@ -70,8 +82,8 @@ impl Mcmf { self.maxflow = 0; self.cost = 0; self.in_field = 0; - self.S = 0; - self.T = 0; + self.ss = 0; + self.tt = 0; self.a0 = 0; self.a1 = 0; self.d.clear(); @@ -96,7 +108,13 @@ impl Mcmf { fn add(&mut self, u: i32, v: i32, w: i32, c: i32) { let idx = self.e.len(); - self.e.push(Edge { u, next: self.head[u as usize], v, w, c }); + self.e.push(Edge { + u, + next: self.head[u as usize], + v, + w, + c, + }); self.head[u as usize] = idx; } @@ -126,9 +144,9 @@ impl Mcmf { self.q.clear(); self.vis.fill(false); self.d.fill(Self::INF); - self.q.push_back(self.S); - self.d[self.S as usize] = 0; - self.incf[self.S as usize] = std::i32::MAX; + self.q.push_back(self.ss); + self.d[self.ss as usize] = 0; + self.incf[self.ss as usize] = std::i32::MAX; while let Some(u) = self.q.pop_front() { self.vis[u as usize] = false; let mut i = self.head[u as usize]; @@ -146,14 +164,14 @@ impl Mcmf { i = e.next; } } - self.d[self.T as usize] != Self::INF + self.d[self.tt as usize] != Self::INF } /// 沿增广路更新流与费用 fn update(&mut self) { - let mut x = self.T; - let flow = self.incf[self.T as usize]; - while x != self.S { + let mut x = self.tt; + let flow = self.incf[self.tt as usize]; + while x != self.ss { let i = self.pre[x as usize]; self.e[i].w -= flow; let ri = i ^ 1; @@ -161,7 +179,7 @@ impl Mcmf { x = self.e[ri].v; } self.maxflow += flow; - self.cost += self.d[self.T as usize] * flow; + self.cost += self.d[self.tt as usize] * flow; } /// 主循环:不断 SPFA + 更新 @@ -174,23 +192,23 @@ impl Mcmf { /// 求解 pub fn solve(&mut self) { // 构造超级源汇 - self.S = self.n + 1; - self.T = self.n + 2; + self.ss = self.n + 1; + self.tt = self.n + 2; for i in 1..=self.n { let ai = self.a[i as usize]; if ai > 0 { - self.add_edge(self.S, i, 0, ai, 0); + self.add_edge(self.ss, i, 0, ai, 0); } else if ai < 0 { - self.add_edge(i, self.T, 0, -ai, 0); + self.add_edge(i, self.tt, 0, -ai, 0); } } // 保证原图中循环流可行 - self.add_edge(self.T, self.S, 0, Self::INF, 0); + self.add_edge(self.tt, self.ss, 0, Self::INF, 0); self.work(); // 切换为真正的源汇 - self.S = self.s; - self.T = self.t; + self.ss = self.s; + self.tt = self.t; self.a1 += self.cost; self.maxflow = 0; self.cost = 0; @@ -204,7 +222,6 @@ impl Mcmf { } } - use std::error::Error; #[derive(Clone, Debug)] @@ -277,8 +294,11 @@ impl Distribution { } for (i, user) in self.user.iter().enumerate() { for &stamp in &user.stamps { - let from = (i as u64 + 2 + (self.spare[stamp as usize].day + 1) * self.user.len() as u64) as i32; - let to = n_nodes - self.spare.len() as i32 + self.spare[stamp as usize].stamp as i32; + let from = + (i as u64 + 2 + (self.spare[stamp as usize].day + 1) * self.user.len() as u64) + as i32; + let to = + n_nodes - self.spare.len() as i32 + self.spare[stamp as usize].stamp as i32; self.mf.add_edge(from, to, 0, 1, 0); } } @@ -290,13 +310,19 @@ impl Distribution { let a0 = 1 + self.user.len() as i64; let a1 = 1 + (self.user.len() * 8) as i64; let a2 = (self.mf.n - 1) as i64; - let mut res = vec![User { id: 0, stamps: Vec::new() }; self.user.len()]; + let mut res = vec![ + User { + id: 0, + stamps: Vec::new() + }; + self.user.len() + ]; for e in &self.mf.e { let u = e.u as i64; let v = e.v as i64; - if u > a0 && u <= a1 && v > a1 && v <= a2 { - let idx = (u - a0 - 1) as usize; - let stamp = (v - a2 - 1) as u64; + if u > a0 && u <= a1 && v > a1 && v <= a2 && e.w == 0 { + let idx = ((u - a0 - 1) % self.user.len() as i64) as usize; + let stamp = (v - a1 - 1) as u64; res[idx].stamps.push(stamp); } } @@ -317,8 +343,11 @@ pub fn distribute(users: Vec, spares: Vec) -> Vec { #[cfg(test)] mod tests { + use crate::app::user; + use super::*; + use rand::{thread_rng, seq::SliceRandom}; #[test] fn test_mcmf_sample1() { let mut mf = Mcmf::new(); @@ -335,10 +364,10 @@ mod tests { mf.solve(); - assert_eq!(mf.a0, 50, "期望最大流 a0 = 50,但实际是 {}", mf.a0); + assert_eq!(mf.a0, 50, "期望最大流 a0 = 50,但实际是 {}", mf.a0); assert_eq!(mf.a1, 280, "期望最小费用 a1 = 280,但实际是 {}", mf.a1); } - #[test] + #[test] fn test_mcmf_sample2() { let mut mf = Mcmf::new(); mf.n = 5; @@ -356,8 +385,86 @@ mod tests { mf.solve(); - assert_eq!(mf.a0, 3, "期望最大流 a0 = 3,但实际是 {}", mf.a0); + assert_eq!(mf.a0, 3, "期望最大流 a0 = 3,但实际是 {}", mf.a0); assert_eq!(mf.a1, 12, "期望最小费用 a1 = 12,但实际是 {}", mf.a1); } + // empty_test + #[test] + fn test_distribution_sample1() { + let users = vec![User { + id: 0, + stamps: vec![], + }]; + let spares = vec![Spare { day: 0, stamp: 0 }]; + let res = distribute(users, spares); + println!("res: {:?}", res); + assert_eq!(res.len(), 1, "期望结果长度为 1,但实际是 {}", res.len()); + } + #[test] + fn test_distribution_sample2() { + let users = vec![User { + id: 0, + stamps: vec![0], + }]; + let spares = vec![Spare { day: 0, stamp: 0 }]; + let res = distribute(users, spares); + // println!("res: {:?}", res); + assert_eq!(res.len(), 1, "期望结果长度为 1,但实际是 {}", res.len()); + } + + #[test] + fn test_distribution_sample3() { + let users = vec![User { + id: 0, + stamps: vec![0, 1], + }]; + let spares = vec![Spare { day: 0, stamp: 0 }, Spare { day: 0, stamp: 1 }]; + let res = distribute(users, spares); + // println!("res: {:?}", res); + assert_eq!(res.len(), 1, "期望结果长度为 1,但实际是 {}", res.len()); + } + + #[test] + fn test_distribution_sample4() { + let mut spares = Vec::new(); + for day in 0..7 { + for slot in 0..2 { + spares.push(Spare { + stamp: (day * 2 + slot) as u64, + day: day as u64, + }); + } + } + + let mut rng = thread_rng(); + let all_slots: Vec = (0..14).collect(); + let users: Vec = (0..10) + .map(|i| { + let mut picks = all_slots.clone(); + picks.shuffle(&mut rng); + picks.truncate(5); + User { id: i as u64, stamps: picks } + }) + .collect(); + + println!("初始"); + for user in &users { + println!(" 用户 {}: 时隙 {:?}", user.id, user.stamps); + } + let result = distribute(users.clone(), spares.clone()); + + println!("分配结果:"); + for user in &result { + println!(" 用户 {}: 时隙 {:?}", user.id, user.stamps); + } + + assert_eq!(result.len(), users.len(), "结果用户数量应与输入一致"); + for user in result { + assert!(user.stamps.len() <= 5, "用户分配时隙不能超过 5"); + for &stamp in &user.stamps { + assert!(stamp < 14, "时隙索引应在 0..14 范围内"); + } + } + } -} \ No newline at end of file +} From 8f29987d8d7ee5134800e5d1d7b805223fa48a50 Mon Sep 17 00:00:00 2001 From: xiaohongrsx Date: Tue, 20 May 2025 10:04:37 +0800 Subject: [PATCH 5/9] chore(algorithm): rebase feat/algorithm onto main --- Cargo.lock | 501 +++++++++++-------------------------------- Cargo.toml | 5 - src/app/algorithm.rs | 2 - 3 files changed, 120 insertions(+), 388 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e0a3eb..6fc9a56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,12 +38,6 @@ dependencies = [ "libc", ] -[[package]] -name = "anstyle" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" - [[package]] name = "api" version = "0.1.0" @@ -88,9 +82,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de45108900e1f9b9242f7f2e254aa3e2c029c921c258fe9e6b4217eeebd54288" +checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" dependencies = [ "axum-core", "axum-macros", @@ -160,17 +154,12 @@ dependencies = [ "argon2", "axum", "chrono", - "cxx", - "cxx-build", "hex", "hmac", "http-body-util", "hyper-util", -<<<<<<< HEAD "iso8601", -======= "rand", ->>>>>>> 4c6697d (fix(algorithm): resolve index-out-of-bounds in solve and add unit test) "serde", "serde_json", "sha2", @@ -184,9 +173,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", "cfg-if", @@ -211,9 +200,9 @@ checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" dependencies = [ "serde", ] @@ -256,9 +245,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.22" +version = "1.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32db95edf998450acc7881c932f94cd9b05c87b4b2599e8bab064753da4acfd1" +checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" dependencies = [ "shlex", ] @@ -271,9 +260,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", @@ -283,43 +272,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "clap" -version = "4.5.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000" -dependencies = [ - "clap_builder", -] - -[[package]] -name = "clap_builder" -version = "4.5.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120" -dependencies = [ - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_lex" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" - -[[package]] -name = "codespan-reporting" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" -dependencies = [ - "serde", - "termcolor", - "unicode-width", -] - [[package]] name = "concurrent-queue" version = "2.5.0" @@ -352,9 +304,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.2.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" dependencies = [ "crc-catalog", ] @@ -390,65 +342,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "cxx" -version = "1.0.158" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a71ea7f29c73f7ffa64c50b83c9fe4d3a6d4be89a86b009eb80d5a6d3429d741" -dependencies = [ - "cc", - "cxxbridge-cmd", - "cxxbridge-flags", - "cxxbridge-macro", - "foldhash", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.158" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a8232661d66dcf713394726157d3cfe0a89bfc85f52d6e9f9bbc2306797fe7" -dependencies = [ - "cc", - "codespan-reporting", - "proc-macro2", - "quote", - "scratch", - "syn", -] - -[[package]] -name = "cxxbridge-cmd" -version = "1.0.158" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f44296c8693e9ea226a48f6a122727f77aa9e9e338380cb021accaeeb7ee279" -dependencies = [ - "clap", - "codespan-reporting", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.158" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f69c181c176981ae44ba9876e2ea41ce8e574c296b38d06925ce9214fb8e4" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.158" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8faff5d4467e0709448187df29ccbf3b0982cc426ee444a193f87b11afb565a8" -dependencies = [ - "proc-macro2", - "quote", - "rustversion", - "syn", -] - [[package]] name = "der" version = "0.7.10" @@ -513,16 +406,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" -[[package]] -name = "errno" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - [[package]] name = "etcetera" version = "0.8.0" @@ -545,12 +428,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - [[package]] name = "flume" version = "0.11.1" @@ -667,25 +544,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.3.2" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi", ] [[package]] @@ -696,9 +561,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "h2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" +checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" dependencies = [ "atomic-waker", "bytes", @@ -715,9 +580,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" dependencies = [ "allocator-api2", "equivalent", @@ -851,9 +716,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" +checksum = "cf9f1e950e0d9d1d3c47184416723cf29c0d1f93bd8cccf37e4beb6b44f31710" dependencies = [ "bytes", "futures-channel", @@ -895,21 +760,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -918,31 +784,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -950,67 +796,54 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "idna" version = "1.0.3" @@ -1024,9 +857,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -1044,9 +877,9 @@ dependencies = [ [[package]] name = "iso8601" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5c177cff824ab21a6f41079a4c401241c4e8be14f316c4c6b07d5fca351c98d" +checksum = "e1082f0c48f143442a1ac6122f67e360ceee130b967af4d50996e5154a45df46" dependencies = [ "chrono", "nom", @@ -1087,9 +920,9 @@ checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libm" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libsqlite3-sys" @@ -1102,26 +935,11 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "link-cplusplus" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6f6da007f968f9def0d65a05b187e2960183de70c160204ecfccf0ee330212" -dependencies = [ - "cc", -] - -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lock_api" @@ -1183,7 +1001,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.52.0", ] @@ -1368,6 +1186,15 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -1395,12 +1222,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "r-efi" -version = "5.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" - [[package]] name = "rand" version = "0.8.5" @@ -1428,14 +1249,14 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom", ] [[package]] name = "redox_syscall" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" dependencies = [ "bitflags", ] @@ -1466,19 +1287,6 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" -[[package]] -name = "rustix" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.59.0", -] - [[package]] name = "rustversion" version = "1.0.20" @@ -1497,12 +1305,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "scratch" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f6280af86e5f559536da57a45ebc84948833b3bee313a7dd25232e09c878a52" - [[package]] name = "serde" version = "1.0.219" @@ -1662,9 +1464,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c3a85280daca669cfd3bcb68a337882a8bc57ec882f72c5d13a430613a738e" +checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" dependencies = [ "sqlx-core", "sqlx-macros", @@ -1675,9 +1477,9 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f743f2a3cea30a58cd479013f75550e879009e3a02f616f18ca699335aa248c3" +checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" dependencies = [ "base64", "bytes", @@ -1709,9 +1511,9 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4200e0fde19834956d4252347c12a083bdcb237d7a1a1446bffd8768417dce" +checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" dependencies = [ "proc-macro2", "quote", @@ -1722,9 +1524,9 @@ dependencies = [ [[package]] name = "sqlx-macros-core" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882ceaa29cade31beca7129b6beeb05737f44f82dbe2a9806ecea5a7093d00b7" +checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" dependencies = [ "dotenvy", "either", @@ -1741,16 +1543,15 @@ dependencies = [ "sqlx-postgres", "sqlx-sqlite", "syn", - "tempfile", "tokio", "url", ] [[package]] name = "sqlx-mysql" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0afdd3aa7a629683c2d750c2df343025545087081ab5942593a5288855b1b7a7" +checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", "base64", @@ -1790,9 +1591,9 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0bedbe1bbb5e2615ef347a5e9d8cd7680fb63e77d9dafc0f29be15e53f1ebe6" +checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", "base64", @@ -1827,9 +1628,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c26083e9a520e8eb87a06b12347679b142dc2ea29e6e409f805644a7a979a5bc" +checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" dependencies = [ "atoi", "flume", @@ -1866,12 +1667,6 @@ dependencies = [ "unicode-properties", ] -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - [[package]] name = "subtle" version = "2.6.1" @@ -1880,9 +1675,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.100" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -1897,37 +1692,15 @@ checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", "syn", ] -[[package]] -name = "tempfile" -version = "3.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" -dependencies = [ - "fastrand", - "getrandom 0.3.2", - "once_cell", - "rustix", - "windows-sys 0.59.0", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" version = "2.0.12" @@ -1960,9 +1733,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -1985,9 +1758,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.2" +version = "1.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" +checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165" dependencies = [ "backtrace", "bytes", @@ -2025,9 +1798,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" dependencies = [ "bytes", "futures-core", @@ -2058,9 +1831,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" +checksum = "0fdb0c213ca27a9f57ab69ddb290fd80d970922355b83ae380b395d3986b8a2e" dependencies = [ "bitflags", "bytes", @@ -2181,12 +1954,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" -[[package]] -name = "unicode-width" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" - [[package]] name = "url" version = "2.5.4" @@ -2198,12 +1965,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -2243,15 +2004,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" -dependencies = [ - "wit-bindgen-rt", -] - [[package]] name = "wasite" version = "0.1.0" @@ -2342,15 +2094,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2359,9 +2102,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.61.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", @@ -2400,18 +2143,18 @@ checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] name = "windows-result" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ "windows-link", ] @@ -2564,32 +2307,17 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "wit-bindgen-rt" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] - -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", @@ -2599,9 +2327,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", @@ -2611,18 +2339,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", @@ -2656,11 +2384,22 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" dependencies = [ "yoke", "zerofrom", @@ -2669,9 +2408,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 50f8cb8..f0e6d9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,10 +23,5 @@ hmac = "0.12.1" hex = "0.4.3" sha2 = "0.10.9" chrono = "0.4.33" -cxx = "1.0" - -[build-dependencies] -cxx-build = "1.0" iso8601 = { version = "0.6.2", features = ["chrono", "serde"] } - rand = "0.8.5" \ No newline at end of file diff --git a/src/app/algorithm.rs b/src/app/algorithm.rs index ad2e77d..f66bb60 100644 --- a/src/app/algorithm.rs +++ b/src/app/algorithm.rs @@ -343,8 +343,6 @@ pub fn distribute(users: Vec, spares: Vec) -> Vec { #[cfg(test)] mod tests { - use crate::app::user; - use super::*; use rand::{thread_rng, seq::SliceRandom}; From f05320e0ba018805fc955b16160a861062b55172 Mon Sep 17 00:00:00 2001 From: xiaohongrsx Date: Tue, 20 May 2025 10:32:35 +0800 Subject: [PATCH 6/9] fix(algorithm): correct typos and minor mistakes --- Cargo.toml | 2 +- build.rs | 2 +- src/app/hash.rs | 1 + src/main.rs | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f0e6d9c..a0cdc86 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ hyper-util = { version = "0.1.10", features = ["full"] } argon2 = "0.5.3" hmac = "0.12.1" hex = "0.4.3" -sha2 = "0.10.9" +sha2 = "0.10.8" chrono = "0.4.33" iso8601 = { version = "0.6.2", features = ["chrono", "serde"] } rand = "0.8.5" \ No newline at end of file diff --git a/build.rs b/build.rs index e140e3d..1ed525c 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,5 @@ fn main() { // trigger recompilation when a new migration is added - println!("cargo:rerun-if-changed=migrations"); + println!("cargo::rerun-if-changed=migrations"); } diff --git a/src/app/hash.rs b/src/app/hash.rs index 82e2373..3faed1e 100644 --- a/src/app/hash.rs +++ b/src/app/hash.rs @@ -1,4 +1,5 @@ use argon2::{password_hash::SaltString, Argon2, PasswordHash, PasswordHasher, PasswordVerifier}; + #[derive(Debug, Clone)] pub struct Hasher { salt: SaltString, diff --git a/src/main.rs b/src/main.rs index 0b52b6a..0b18311 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use app::{app, connect_pool}; + mod app; const DATABASE_URL: &str = "sqlite://db/sqlite.db"; From a33e4e53fdc5627fca5478c03c6a17969e44daad Mon Sep 17 00:00:00 2001 From: xiaohongrsx <168885171+xiaohongrsx@users.noreply.github.com> Date: Tue, 20 May 2025 10:43:41 +0800 Subject: [PATCH 7/9] Update Cargo.lock fix malformed Cargo.lock checksum string --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 0aefb0d..076c819 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -247,7 +247,7 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" name = "cc" version = "1.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766 +checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" dependencies = [ "shlex", ] From 4592c42843d2ab8729702e6104e669951dfbda31 Mon Sep 17 00:00:00 2001 From: xiaohongrsx <168885171+xiaohongrsx@users.noreply.github.com> Date: Tue, 20 May 2025 10:47:30 +0800 Subject: [PATCH 8/9] Update Cargo.lock add missing double-quote to checksum in Cargo.lock --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 076c819..fbb9de7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -809,7 +809,7 @@ checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" name = "icu_properties" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", From 30878ff421f41aa89ee4d509244b2ae01a52c878 Mon Sep 17 00:00:00 2001 From: xiaohongrsx <168885171+xiaohongrsx@users.noreply.github.com> Date: Tue, 20 May 2025 10:50:09 +0800 Subject: [PATCH 9/9] refactor(mod): remove redundant mod declarations --- src/app/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/mod.rs b/src/app/mod.rs index f66cb57..33edf9c 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -6,7 +6,6 @@ mod hash; mod sign; mod spare; mod user; -mod algorithm; use admin::AdminAPI; use api::{APICollection, API};