Compare commits
16 Commits
e4e274a543
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
906ddec843
|
|||
|
48e92d1736
|
|||
|
733e8f73ea
|
|||
| 2c0d5c8479 | |||
| 9b479d1236 | |||
| 29f97f82c4 | |||
| dd17de79de | |||
| bb96724454 | |||
| 4dae5bac7a | |||
| 37753fe37c | |||
| 7fe6980867 | |||
| 0ce26fc0e5 | |||
| 62399c2046 | |||
| 612a696829 | |||
| 2bf42e47c5 | |||
| 50230c43b8 |
473
Cargo.lock
generated
473
Cargo.lock
generated
@@ -434,24 +434,6 @@ version = "1.8.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
|
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bindgen"
|
|
||||||
version = "0.72.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.10.0",
|
|
||||||
"cexpr",
|
|
||||||
"clang-sys",
|
|
||||||
"itertools 0.13.0",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"regex",
|
|
||||||
"rustc-hash",
|
|
||||||
"shlex",
|
|
||||||
"syn 2.0.111",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@@ -580,19 +562,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.11.0"
|
version = "1.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
|
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bzip2-sys"
|
|
||||||
version = "0.1.13+1.0.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"pkg-config",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cacache"
|
name = "cacache"
|
||||||
@@ -691,21 +663,6 @@ dependencies = [
|
|||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cesu8"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cexpr"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
|
||||||
dependencies = [
|
|
||||||
"nom",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -766,16 +723,6 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clang-sys"
|
|
||||||
version = "1.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
|
||||||
dependencies = [
|
|
||||||
"glob",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.53"
|
version = "4.5.53"
|
||||||
@@ -1648,6 +1595,35 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ext-trait"
|
||||||
|
version = "2.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ccef4f53516d7589a8ed95216b6ebc9d519df033c1303b42125bfe57aa475d23"
|
||||||
|
dependencies = [
|
||||||
|
"ext-trait-proc_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ext-trait-proc_macros"
|
||||||
|
version = "2.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "025e48a9a5db92b84dbd3b6be37853a0e60c1ce9c7c03c08e6ac282766f3e3f0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.111",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "extension-traits"
|
||||||
|
version = "2.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a7dae1256e3fea2900e1e674bae228edc852f5ce9ccb1c916a496a33cb9bc4cb"
|
||||||
|
dependencies = [
|
||||||
|
"ext-trait",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastpool"
|
name = "fastpool"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -1747,12 +1723,15 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"async-compression",
|
"async-compression",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"bytes",
|
||||||
"capnp",
|
"capnp",
|
||||||
"capnpc",
|
"capnpc",
|
||||||
"clap",
|
"clap",
|
||||||
"dashmap 6.1.0",
|
"dashmap 6.1.0",
|
||||||
|
"extension-traits",
|
||||||
"futures",
|
"futures",
|
||||||
"hound",
|
"hound",
|
||||||
|
"moka",
|
||||||
"opendal",
|
"opendal",
|
||||||
"opus2",
|
"opus2",
|
||||||
"patricia_tree 0.10.1",
|
"patricia_tree 0.10.1",
|
||||||
@@ -1765,6 +1744,8 @@ dependencies = [
|
|||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
|
"tokio-websockets 0.11.4",
|
||||||
|
"tokio-websockets 0.13.2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"twilight-gateway",
|
"twilight-gateway",
|
||||||
@@ -1772,6 +1753,7 @@ dependencies = [
|
|||||||
"twilight-model",
|
"twilight-model",
|
||||||
"twilight-util",
|
"twilight-util",
|
||||||
"typed-builder 0.23.2",
|
"typed-builder 0.23.2",
|
||||||
|
"yoke",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2762,15 +2744,6 @@ version = "1.70.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itertools"
|
|
||||||
version = "0.13.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
|
||||||
dependencies = [
|
|
||||||
"either",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
@@ -2829,50 +2802,6 @@ dependencies = [
|
|||||||
"jiff-tzdb",
|
"jiff-tzdb",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "jni"
|
|
||||||
version = "0.21.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
|
|
||||||
dependencies = [
|
|
||||||
"cesu8",
|
|
||||||
"cfg-if",
|
|
||||||
"combine",
|
|
||||||
"jni-sys 0.3.1",
|
|
||||||
"log",
|
|
||||||
"thiserror 1.0.69",
|
|
||||||
"walkdir",
|
|
||||||
"windows-sys 0.45.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "jni-sys"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258"
|
|
||||||
dependencies = [
|
|
||||||
"jni-sys 0.4.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "jni-sys"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2"
|
|
||||||
dependencies = [
|
|
||||||
"jni-sys-macros",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "jni-sys-macros"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
|
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.111",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jobserver"
|
name = "jobserver"
|
||||||
version = "0.1.34"
|
version = "0.1.34"
|
||||||
@@ -3229,19 +3158,6 @@ dependencies = [
|
|||||||
"redox_syscall 0.7.1",
|
"redox_syscall 0.7.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "librocksdb-sys"
|
|
||||||
version = "0.17.3+10.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cef2a00ee60fe526157c9023edab23943fae1ce2ab6f4abb2a807c1746835de9"
|
|
||||||
dependencies = [
|
|
||||||
"bindgen",
|
|
||||||
"bzip2-sys",
|
|
||||||
"cc",
|
|
||||||
"libc",
|
|
||||||
"libz-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libsqlite3-sys"
|
name = "libsqlite3-sys"
|
||||||
version = "0.30.1"
|
version = "0.30.1"
|
||||||
@@ -3252,17 +3168,6 @@ dependencies = [
|
|||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libz-sys"
|
|
||||||
version = "1.1.28"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"pkg-config",
|
|
||||||
"vcpkg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
version = "0.5.6"
|
version = "0.5.6"
|
||||||
@@ -3471,12 +3376,6 @@ dependencies = [
|
|||||||
"triomphe",
|
"triomphe",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "minimal-lexical"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.8.9"
|
version = "0.8.9"
|
||||||
@@ -3500,9 +3399,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "moka"
|
name = "moka"
|
||||||
version = "0.12.12"
|
version = "0.12.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a3dec6bd31b08944e08b58fd99373893a6c17054d6f3ea5006cc894f4f4eee2a"
|
checksum = "957228ad12042ee839f93c8f257b62b4c0ab5eaae1d4fa60de53b27c9d7c5046"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-lock",
|
"async-lock",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
@@ -3627,16 +3526,6 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "7.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
"minimal-lexical",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nonmax"
|
name = "nonmax"
|
||||||
version = "0.5.5"
|
version = "0.5.5"
|
||||||
@@ -3769,7 +3658,7 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal"
|
name = "opendal"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ctor",
|
"ctor",
|
||||||
"opendal-core",
|
"opendal-core",
|
||||||
@@ -3807,7 +3696,6 @@ dependencies = [
|
|||||||
"opendal-service-postgresql",
|
"opendal-service-postgresql",
|
||||||
"opendal-service-redb",
|
"opendal-service-redb",
|
||||||
"opendal-service-redis",
|
"opendal-service-redis",
|
||||||
"opendal-service-rocksdb",
|
|
||||||
"opendal-service-s3",
|
"opendal-service-s3",
|
||||||
"opendal-service-sled",
|
"opendal-service-sled",
|
||||||
"opendal-service-webdav",
|
"opendal-service-webdav",
|
||||||
@@ -3816,7 +3704,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-core"
|
name = "opendal-core"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
@@ -3832,7 +3720,7 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"quick-xml 0.38.4",
|
"quick-xml 0.38.4",
|
||||||
"reqsign-core",
|
"reqsign-core",
|
||||||
"reqwest 0.13.2",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -3844,7 +3732,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-layer-concurrent-limit"
|
name = "opendal-layer-concurrent-limit"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"http",
|
"http",
|
||||||
@@ -3855,7 +3743,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-layer-logging"
|
name = "opendal-layer-logging"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"opendal-core",
|
"opendal-core",
|
||||||
@@ -3864,7 +3752,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-layer-retry"
|
name = "opendal-layer-retry"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backon",
|
"backon",
|
||||||
"log",
|
"log",
|
||||||
@@ -3874,7 +3762,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-layer-timeout"
|
name = "opendal-layer-timeout"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"opendal-core",
|
"opendal-core",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -3883,7 +3771,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-aliyun-drive"
|
name = "opendal-service-aliyun-drive"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
@@ -3897,7 +3785,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-alluxio"
|
name = "opendal-service-alluxio"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
@@ -3910,7 +3798,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-azblob"
|
name = "opendal-service-azblob"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -3930,7 +3818,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-azdls"
|
name = "opendal-service-azdls"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
@@ -3948,7 +3836,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-azfile"
|
name = "opendal-service-azfile"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
@@ -3965,7 +3853,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-azure-common"
|
name = "opendal-service-azure-common"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"opendal-core",
|
"opendal-core",
|
||||||
@@ -3974,7 +3862,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-b2"
|
name = "opendal-service-b2"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
@@ -3988,7 +3876,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-cacache"
|
name = "opendal-service-cacache"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"cacache",
|
"cacache",
|
||||||
@@ -3999,7 +3887,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-d1"
|
name = "opendal-service-d1"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
@@ -4011,7 +3899,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-dashmap"
|
name = "opendal-service-dashmap"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dashmap 6.1.0",
|
"dashmap 6.1.0",
|
||||||
"log",
|
"log",
|
||||||
@@ -4022,7 +3910,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-dbfs"
|
name = "opendal-service-dbfs"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -4036,7 +3924,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-dropbox"
|
name = "opendal-service-dropbox"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
@@ -4049,7 +3937,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-etcd"
|
name = "opendal-service-etcd"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"etcd-client",
|
"etcd-client",
|
||||||
"fastpool",
|
"fastpool",
|
||||||
@@ -4061,7 +3949,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-fs"
|
name = "opendal-service-fs"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"log",
|
"log",
|
||||||
@@ -4074,7 +3962,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-ftp"
|
name = "opendal-service-ftp"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"fastpool",
|
"fastpool",
|
||||||
@@ -4092,7 +3980,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-gcs"
|
name = "opendal-service-gcs"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -4112,7 +4000,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-gdrive"
|
name = "opendal-service-gdrive"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
@@ -4126,7 +4014,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-ghac"
|
name = "opendal-service-ghac"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"ghac",
|
"ghac",
|
||||||
@@ -4145,7 +4033,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-github"
|
name = "opendal-service-github"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -4159,7 +4047,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-gridfs"
|
name = "opendal-service-gridfs"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"mea",
|
"mea",
|
||||||
@@ -4171,7 +4059,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-hdfs-native"
|
name = "opendal-service-hdfs-native"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures",
|
"futures",
|
||||||
@@ -4184,7 +4072,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-ipmfs"
|
name = "opendal-service-ipmfs"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
@@ -4197,7 +4085,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-mini-moka"
|
name = "opendal-service-mini-moka"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"mini-moka",
|
"mini-moka",
|
||||||
@@ -4208,7 +4096,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-moka"
|
name = "opendal-service-moka"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"moka",
|
"moka",
|
||||||
@@ -4219,7 +4107,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-mongodb"
|
name = "opendal-service-mongodb"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"mea",
|
"mea",
|
||||||
"mongodb",
|
"mongodb",
|
||||||
@@ -4230,7 +4118,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-mysql"
|
name = "opendal-service-mysql"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"mea",
|
"mea",
|
||||||
"opendal-core",
|
"opendal-core",
|
||||||
@@ -4241,7 +4129,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-pcloud"
|
name = "opendal-service-pcloud"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
@@ -4254,7 +4142,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-persy"
|
name = "opendal-service-persy"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"opendal-core",
|
"opendal-core",
|
||||||
"persy",
|
"persy",
|
||||||
@@ -4264,7 +4152,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-postgresql"
|
name = "opendal-service-postgresql"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"mea",
|
"mea",
|
||||||
"opendal-core",
|
"opendal-core",
|
||||||
@@ -4275,7 +4163,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-redb"
|
name = "opendal-service-redb"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"opendal-core",
|
"opendal-core",
|
||||||
"redb",
|
"redb",
|
||||||
@@ -4285,7 +4173,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-redis"
|
name = "opendal-service-redis"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"fastpool",
|
"fastpool",
|
||||||
@@ -4296,20 +4184,10 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "opendal-service-rocksdb"
|
|
||||||
version = "0.55.0"
|
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
|
||||||
dependencies = [
|
|
||||||
"opendal-core",
|
|
||||||
"rocksdb",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-s3"
|
name = "opendal-service-s3"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -4329,7 +4207,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-sled"
|
name = "opendal-service-sled"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"opendal-core",
|
"opendal-core",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -4339,7 +4217,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opendal-service-webdav"
|
name = "opendal-service-webdav"
|
||||||
version = "0.55.0"
|
version = "0.55.0"
|
||||||
source = "git+https://github.com/babichjacob/opendal?branch=rocksdb-0.24.0-bindgen-static#979a75c46308dab4db5b172caf4483f6ea37cd72"
|
source = "git+https://github.com/apache/opendal?rev=ecf840b04afd2be109830b9978ba89759adfee79#ecf840b04afd2be109830b9978ba89759adfee79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -4903,7 +4781,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7"
|
checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"itertools 0.14.0",
|
"itertools",
|
||||||
"log",
|
"log",
|
||||||
"multimap",
|
"multimap",
|
||||||
"petgraph",
|
"petgraph",
|
||||||
@@ -4924,7 +4802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
|
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"itertools 0.14.0",
|
"itertools",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.111",
|
"syn 2.0.111",
|
||||||
@@ -4937,7 +4815,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
|
checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"itertools 0.14.0",
|
"itertools",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.111",
|
"syn 2.0.111",
|
||||||
@@ -5029,7 +4907,6 @@ version = "0.11.13"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31"
|
checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aws-lc-rs",
|
|
||||||
"bytes",
|
"bytes",
|
||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
"lru-slab",
|
"lru-slab",
|
||||||
@@ -5061,9 +4938,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.42"
|
version = "1.0.45"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
|
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@@ -5443,49 +5320,11 @@ dependencies = [
|
|||||||
"url",
|
"url",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"wasm-streams 0.4.2",
|
"wasm-streams",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"webpki-roots 1.0.4",
|
"webpki-roots 1.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "reqwest"
|
|
||||||
version = "0.13.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801"
|
|
||||||
dependencies = [
|
|
||||||
"base64 0.22.1",
|
|
||||||
"bytes",
|
|
||||||
"futures-core",
|
|
||||||
"futures-util",
|
|
||||||
"http",
|
|
||||||
"http-body",
|
|
||||||
"http-body-util",
|
|
||||||
"hyper",
|
|
||||||
"hyper-rustls",
|
|
||||||
"hyper-util",
|
|
||||||
"js-sys",
|
|
||||||
"log",
|
|
||||||
"percent-encoding",
|
|
||||||
"pin-project-lite",
|
|
||||||
"quinn",
|
|
||||||
"rustls 0.23.35",
|
|
||||||
"rustls-pki-types",
|
|
||||||
"rustls-platform-verifier",
|
|
||||||
"sync_wrapper",
|
|
||||||
"tokio",
|
|
||||||
"tokio-rustls 0.26.4",
|
|
||||||
"tokio-util",
|
|
||||||
"tower",
|
|
||||||
"tower-http",
|
|
||||||
"tower-service",
|
|
||||||
"url",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"wasm-bindgen-futures",
|
|
||||||
"wasm-streams 0.5.0",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "resolv-conf"
|
name = "resolv-conf"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
@@ -5555,16 +5394,6 @@ dependencies = [
|
|||||||
"portable-atomic-util",
|
"portable-atomic-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rocksdb"
|
|
||||||
version = "0.24.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ddb7af00d2b17dbd07d82c0063e25411959748ff03e8d4f96134c2ff41fce34f"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"librocksdb-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roxmltree"
|
name = "roxmltree"
|
||||||
version = "0.21.1"
|
version = "0.21.1"
|
||||||
@@ -5721,33 +5550,6 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustls-platform-verifier"
|
|
||||||
version = "0.6.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
|
|
||||||
dependencies = [
|
|
||||||
"core-foundation",
|
|
||||||
"core-foundation-sys",
|
|
||||||
"jni",
|
|
||||||
"log",
|
|
||||||
"once_cell",
|
|
||||||
"rustls 0.23.35",
|
|
||||||
"rustls-native-certs",
|
|
||||||
"rustls-platform-verifier-android",
|
|
||||||
"rustls-webpki 0.103.8",
|
|
||||||
"security-framework",
|
|
||||||
"security-framework-sys",
|
|
||||||
"webpki-root-certs",
|
|
||||||
"windows-sys 0.61.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustls-platform-verifier-android"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.102.8"
|
version = "0.102.8"
|
||||||
@@ -6058,7 +5860,7 @@ dependencies = [
|
|||||||
"futures",
|
"futures",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"reqwest 0.12.28",
|
"reqwest",
|
||||||
"secrecy 0.8.0",
|
"secrecy 0.8.0",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_cow",
|
"serde_cow",
|
||||||
@@ -6321,7 +6123,7 @@ dependencies = [
|
|||||||
"parking_lot 0.12.5",
|
"parking_lot 0.12.5",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"rand 0.9.2",
|
"rand 0.9.2",
|
||||||
"reqwest 0.12.28",
|
"reqwest",
|
||||||
"ringbuf",
|
"ringbuf",
|
||||||
"rubato",
|
"rubato",
|
||||||
"rusty_pool",
|
"rusty_pool",
|
||||||
@@ -6606,7 +6408,7 @@ dependencies = [
|
|||||||
"futures-util",
|
"futures-util",
|
||||||
"hls_m3u8",
|
"hls_m3u8",
|
||||||
"patricia_tree 0.8.0",
|
"patricia_tree 0.8.0",
|
||||||
"reqwest 0.12.28",
|
"reqwest",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
@@ -7097,6 +6899,7 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls 0.26.4",
|
"tokio-rustls 0.26.4",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
|
"webpki-roots 0.26.11",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -7810,19 +7613,6 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-streams"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb"
|
|
||||||
dependencies = [
|
|
||||||
"futures-util",
|
|
||||||
"js-sys",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"wasm-bindgen-futures",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmparser"
|
name = "wasmparser"
|
||||||
version = "0.244.0"
|
version = "0.244.0"
|
||||||
@@ -7855,15 +7645,6 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "webpki-root-certs"
|
|
||||||
version = "1.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca"
|
|
||||||
dependencies = [
|
|
||||||
"rustls-pki-types",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "webpki-roots"
|
||||||
version = "0.26.11"
|
version = "0.26.11"
|
||||||
@@ -8040,15 +7821,6 @@ dependencies = [
|
|||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.45.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
|
||||||
dependencies = [
|
|
||||||
"windows-targets 0.42.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
@@ -8085,21 +7857,6 @@ dependencies = [
|
|||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm 0.42.2",
|
|
||||||
"windows_aarch64_msvc 0.42.2",
|
|
||||||
"windows_i686_gnu 0.42.2",
|
|
||||||
"windows_i686_msvc 0.42.2",
|
|
||||||
"windows_x86_64_gnu 0.42.2",
|
|
||||||
"windows_x86_64_gnullvm 0.42.2",
|
|
||||||
"windows_x86_64_msvc 0.42.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-targets"
|
name = "windows-targets"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
@@ -8157,12 +7914,6 @@ dependencies = [
|
|||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
@@ -8181,12 +7932,6 @@ version = "0.53.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
|
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
@@ -8205,12 +7950,6 @@ version = "0.53.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
|
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
@@ -8241,12 +7980,6 @@ version = "0.53.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
|
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
@@ -8265,12 +7998,6 @@ version = "0.53.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
|
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
@@ -8289,12 +8016,6 @@ version = "0.53.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
|
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
@@ -8313,12 +8034,6 @@ version = "0.53.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
|
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
@@ -8486,9 +8201,9 @@ checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954"
|
checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"stable_deref_trait",
|
"stable_deref_trait",
|
||||||
"yoke-derive",
|
"yoke-derive",
|
||||||
@@ -8497,9 +8212,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke-derive"
|
name = "yoke-derive"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
|
checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|||||||
26
Cargo.toml
26
Cargo.toml
@@ -6,12 +6,15 @@ edition = "2024"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
async-compression = { version = "0.4.41", features = ["brotli", "futures-io"] }
|
async-compression = { version = "0.4.41", features = ["brotli", "futures-io"] }
|
||||||
async-trait = "0.1.89"
|
async-trait = "0.1.89"
|
||||||
|
bytes = "1.11.1"
|
||||||
capnp = "0.25.3"
|
capnp = "0.25.3"
|
||||||
clap = { version = "4.5.40", features = ["derive", "env"] }
|
clap = { version = "4.5.40", features = ["derive", "env"] }
|
||||||
dashmap = "6.1.0"
|
dashmap = "6.1.0"
|
||||||
|
extension-traits = "2.0.2"
|
||||||
futures = "0.3.32"
|
futures = "0.3.32"
|
||||||
hound = "3.5.1"
|
hound = "3.5.1"
|
||||||
opendal = { git = "https://github.com/babichjacob/opendal", branch = "rocksdb-0.24.0", features = [
|
moka = { version = "0.12.15", features = ["future"] }
|
||||||
|
opendal = { git = "https://github.com/apache/opendal", rev = "ecf840b04afd2be109830b9978ba89759adfee79", features = [
|
||||||
"services-azfile",
|
"services-azfile",
|
||||||
"services-aliyun-drive",
|
"services-aliyun-drive",
|
||||||
"services-alluxio",
|
"services-alluxio",
|
||||||
@@ -44,7 +47,6 @@ opendal = { git = "https://github.com/babichjacob/opendal", branch = "rocksdb-0.
|
|||||||
"services-postgresql",
|
"services-postgresql",
|
||||||
"services-redb",
|
"services-redb",
|
||||||
"services-redis",
|
"services-redis",
|
||||||
"services-rocksdb",
|
|
||||||
"services-s3",
|
"services-s3",
|
||||||
"services-sled",
|
"services-sled",
|
||||||
"services-webdav",
|
"services-webdav",
|
||||||
@@ -65,11 +67,24 @@ songbird = { version = "0.6.0", default-features = false, features = [
|
|||||||
] }
|
] }
|
||||||
strum = { version = "0.28.0", features = ["derive"] }
|
strum = { version = "0.28.0", features = ["derive"] }
|
||||||
time = "0.3.47"
|
time = "0.3.47"
|
||||||
tokio = { version = "1.46.0", features = ["rt-multi-thread", "macros", "signal"] }
|
tokio = { version = "1.46.0", features = [
|
||||||
tokio-util = "0.7.18"
|
"rt-multi-thread",
|
||||||
|
"macros",
|
||||||
|
"signal",
|
||||||
|
] }
|
||||||
|
tokio-util = { version = "0.7.18", features = ["io"] }
|
||||||
|
tokio-websockets-0-13 = { package = "tokio-websockets", version = "0.13", features = [
|
||||||
|
"rustls-webpki-roots",
|
||||||
|
] }
|
||||||
|
tokio-websockets-0-11 = { package = "tokio-websockets", version = "0.11", features = [
|
||||||
|
"rustls-webpki-roots",
|
||||||
|
] }
|
||||||
tracing = "0.1.41"
|
tracing = "0.1.41"
|
||||||
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
|
||||||
twilight-gateway = { version = "0.17", default-features = false, features = ["rustls-webpki-roots", "twilight-http"] }
|
twilight-gateway = { version = "0.17", default-features = false, features = [
|
||||||
|
"rustls-webpki-roots",
|
||||||
|
"twilight-http",
|
||||||
|
] }
|
||||||
twilight-http = { version = "0.17", default-features = false, features = [
|
twilight-http = { version = "0.17", default-features = false, features = [
|
||||||
"rustls-webpki-roots",
|
"rustls-webpki-roots",
|
||||||
"hickory",
|
"hickory",
|
||||||
@@ -78,6 +93,7 @@ twilight-http = { version = "0.17", default-features = false, features = [
|
|||||||
twilight-model = "0.17"
|
twilight-model = "0.17"
|
||||||
twilight-util = { version = "0.17", features = ["builder"] }
|
twilight-util = { version = "0.17", features = ["builder"] }
|
||||||
typed-builder = "0.23.2"
|
typed-builder = "0.23.2"
|
||||||
|
yoke = "0.8.2"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
capnpc = "0.25.3"
|
capnpc = "0.25.3"
|
||||||
|
|||||||
30
Dockerfile
30
Dockerfile
@@ -1,5 +1,5 @@
|
|||||||
ARG ALPINE_TAG=3.23.4
|
ARG RUST_TAG=1.94.1-alpine3.23
|
||||||
FROM alpine:${ALPINE_TAG}
|
FROM rust:${RUST_TAG} AS builder
|
||||||
|
|
||||||
ARG BUILD_BASE_VERSION=0.5-r3
|
ARG BUILD_BASE_VERSION=0.5-r3
|
||||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
||||||
@@ -9,30 +9,10 @@ ARG CAPNPROTO_DEV_VERSION=1.2.0-r0
|
|||||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
||||||
apk add --update capnproto-dev=${CAPNPROTO_DEV_VERSION}
|
apk add --update capnproto-dev=${CAPNPROTO_DEV_VERSION}
|
||||||
|
|
||||||
ARG CARGO_VERSION=1.91.1-r1
|
|
||||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
|
||||||
apk add --update cargo=${CARGO_VERSION}
|
|
||||||
|
|
||||||
ARG CLANG21_DEV_VERSION=21.1.2-r2
|
|
||||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
|
||||||
apk add --update clang21-dev=${CLANG21_DEV_VERSION}
|
|
||||||
|
|
||||||
ARG CLANG21_STATIC_VERSION=21.1.2-r2
|
|
||||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
|
||||||
apk add --update clang21-static=${CLANG21_STATIC_VERSION}
|
|
||||||
|
|
||||||
ARG CMAKE_VERSION=4.1.3-r0
|
ARG CMAKE_VERSION=4.1.3-r0
|
||||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
||||||
apk add --update cmake=${CMAKE_VERSION}
|
apk add --update cmake=${CMAKE_VERSION}
|
||||||
|
|
||||||
ARG LLVM21_DEV_VERSION=21.1.2-r1
|
|
||||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
|
||||||
apk add --update llvm21-dev=${LLVM21_DEV_VERSION}
|
|
||||||
|
|
||||||
ARG LLVM21_STATIC_VERSION=21.1.2-r1
|
|
||||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
|
||||||
apk add --update llvm21-static=${LLVM21_STATIC_VERSION}
|
|
||||||
|
|
||||||
ARG PROTOC_VERSION=31.1-r1
|
ARG PROTOC_VERSION=31.1-r1
|
||||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
||||||
apk add --update protoc=${PROTOC_VERSION}
|
apk add --update protoc=${PROTOC_VERSION}
|
||||||
@@ -50,6 +30,10 @@ RUN \
|
|||||||
--mount=type=cache,target=/usr/local/cargo/registry/ \
|
--mount=type=cache,target=/usr/local/cargo/registry/ \
|
||||||
cd /root/app && \
|
cd /root/app && \
|
||||||
cargo build --release && \
|
cargo build --release && \
|
||||||
cp target/release/fomo-reducer /program
|
cp target/release/fomo-reducer /root/program
|
||||||
|
|
||||||
|
FROM scratch AS runner
|
||||||
|
|
||||||
|
COPY --from=builder /root/program /program
|
||||||
|
|
||||||
ENTRYPOINT ["/program"]
|
ENTRYPOINT ["/program"]
|
||||||
|
|||||||
175
src/bot_data.rs
Normal file
175
src/bot_data.rs
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
use async_compression::futures::{bufread::BrotliDecoder, write::BrotliEncoder};
|
||||||
|
use capnp::message::TypedBuilder;
|
||||||
|
use futures::{AsyncReadExt, AsyncWriteExt};
|
||||||
|
use opendal::Operator;
|
||||||
|
use snafu::{ResultExt as _, Snafu};
|
||||||
|
|
||||||
|
use crate::{OperatorExt, bot_capnp, option_ext::OptionExt as _};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct BotDataManager {
|
||||||
|
operator: Operator,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BotDataManager {
|
||||||
|
pub fn new(operator: Operator) -> Self {
|
||||||
|
Self { operator }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const PATH: &str = "data.bin.brotli";
|
||||||
|
|
||||||
|
#[derive(Debug, Snafu)]
|
||||||
|
#[snafu(module)]
|
||||||
|
pub enum WithError {
|
||||||
|
/// couldn't read data for this bot from the storage operator
|
||||||
|
ReadError { source: opendal::Error },
|
||||||
|
|
||||||
|
/// couldn't decompress the bot data from storage
|
||||||
|
DecompressionError { source: std::io::Error },
|
||||||
|
|
||||||
|
/// couldn't deserialize the bot data
|
||||||
|
DeserializeError { source: capnp::Error },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BotDataManager {
|
||||||
|
pub async fn with<R>(
|
||||||
|
&self,
|
||||||
|
f: impl FnOnce(bot_capnp::bot::Reader<'_>) -> R,
|
||||||
|
) -> Result<R, WithError> {
|
||||||
|
let compressed_buffer = self
|
||||||
|
.operator
|
||||||
|
.async_reader_if_exists(PATH)
|
||||||
|
.await
|
||||||
|
.context(with_error::ReadSnafu)?;
|
||||||
|
|
||||||
|
let decompressed_reader = compressed_buffer.map(BrotliDecoder::new);
|
||||||
|
let decompressed = decompressed_reader
|
||||||
|
.map_async(|mut reader| async move {
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
reader.read_to_end(&mut vec).await?;
|
||||||
|
Ok(vec)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.transpose()
|
||||||
|
.context(with_error::DecompressionSnafu)?;
|
||||||
|
|
||||||
|
let mut message = TypedBuilder::<bot_capnp::bot::Owned>::new_default();
|
||||||
|
let fallback = message.init_root();
|
||||||
|
|
||||||
|
let mut bot_data = fallback.into_reader();
|
||||||
|
let message_reader;
|
||||||
|
|
||||||
|
if let Some(mut bytes) = decompressed.as_deref() {
|
||||||
|
message_reader = capnp::serialize::read_message_from_flat_slice_no_alloc(
|
||||||
|
&mut bytes,
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
|
.context(with_error::DeserializeSnafu)?;
|
||||||
|
|
||||||
|
bot_data = message_reader
|
||||||
|
.get_root()
|
||||||
|
.context(with_error::DeserializeSnafu)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(f(bot_data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Snafu)]
|
||||||
|
#[snafu(module)]
|
||||||
|
pub enum UpdateError {
|
||||||
|
/// couldn't read data for this bot from the storage operator
|
||||||
|
ReadError { source: opendal::Error },
|
||||||
|
|
||||||
|
/// couldn't decompress the bot data from storage
|
||||||
|
DecompressionError { source: std::io::Error },
|
||||||
|
|
||||||
|
/// couldn't deserialize the bot data
|
||||||
|
DeserializeError { source: capnp::Error },
|
||||||
|
|
||||||
|
/// couldn't serialize the (modified) bot data
|
||||||
|
SerializeError { source: capnp::Error },
|
||||||
|
|
||||||
|
/// couldn't create a writer for this bot data in the storage operator
|
||||||
|
WriterError { source: opendal::Error },
|
||||||
|
|
||||||
|
/// couldn't write (modified) data for this bot to the storage operator
|
||||||
|
WriteError { source: std::io::Error },
|
||||||
|
|
||||||
|
/// couldn't finalize writing (modified) data for this bot to the storage operator
|
||||||
|
FinalizeError { source: std::io::Error },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BotDataManager {
|
||||||
|
pub async fn update<R>(
|
||||||
|
&self,
|
||||||
|
f: impl FnOnce(bot_capnp::bot::Builder<'_>) -> R,
|
||||||
|
) -> Result<R, UpdateError> {
|
||||||
|
let compressed_buffer = self
|
||||||
|
.operator
|
||||||
|
.async_reader_if_exists(PATH)
|
||||||
|
.await
|
||||||
|
.context(update_error::ReadSnafu)?;
|
||||||
|
|
||||||
|
let decompressed_reader = compressed_buffer.map(BrotliDecoder::new);
|
||||||
|
let decompressed = decompressed_reader
|
||||||
|
.map_async(|mut reader| async move {
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
reader.read_to_end(&mut vec).await?;
|
||||||
|
Ok(vec)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.transpose()
|
||||||
|
.context(update_error::DecompressionSnafu)?;
|
||||||
|
|
||||||
|
let mut message = TypedBuilder::<bot_capnp::bot::Owned>::new_default();
|
||||||
|
|
||||||
|
let ret = if let Some(mut bytes) = decompressed.as_deref() {
|
||||||
|
let message_reader = capnp::serialize::read_message_from_flat_slice_no_alloc(
|
||||||
|
&mut bytes,
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
|
.context(update_error::DeserializeSnafu)?;
|
||||||
|
|
||||||
|
let bot_data = message_reader
|
||||||
|
.get_root()
|
||||||
|
.context(update_error::DeserializeSnafu)?;
|
||||||
|
|
||||||
|
message
|
||||||
|
.set_root(bot_data)
|
||||||
|
.context(update_error::DeserializeSnafu)?;
|
||||||
|
|
||||||
|
f(
|
||||||
|
message.get_root().unwrap(), // this is logically impossible
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
f(message.init_root())
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
capnp::serialize::write_message(&mut buffer, message.borrow_inner())
|
||||||
|
.context(update_error::SerializeSnafu)?;
|
||||||
|
|
||||||
|
let compressed_writer = self
|
||||||
|
.operator
|
||||||
|
.writer(PATH)
|
||||||
|
.await
|
||||||
|
.context(update_error::WriterSnafu)?
|
||||||
|
.into_futures_async_write();
|
||||||
|
|
||||||
|
let mut decompressed_writer = BrotliEncoder::new(compressed_writer);
|
||||||
|
|
||||||
|
decompressed_writer
|
||||||
|
.write_all(&buffer)
|
||||||
|
.await
|
||||||
|
.context(update_error::WriteSnafu)?;
|
||||||
|
|
||||||
|
decompressed_writer
|
||||||
|
.close()
|
||||||
|
.await
|
||||||
|
.context(update_error::FinalizeSnafu)?;
|
||||||
|
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
use std::sync::LazyLock;
|
use futures::TryStreamExt;
|
||||||
|
|
||||||
use async_compression::futures::bufread::BrotliDecoder;
|
|
||||||
use capnp::message::ReaderOptions;
|
|
||||||
use futures::AsyncReadExt;
|
|
||||||
use opendal::ErrorKind;
|
|
||||||
use snafu::{OptionExt, Snafu};
|
use snafu::{OptionExt, Snafu};
|
||||||
|
use std::sync::LazyLock;
|
||||||
use twilight_model::{
|
use twilight_model::{
|
||||||
application::{
|
application::{
|
||||||
command::{Command, CommandType},
|
command::{Command, CommandType},
|
||||||
@@ -17,14 +13,13 @@ use twilight_model::{
|
|||||||
use twilight_util::builder::{
|
use twilight_util::builder::{
|
||||||
InteractionResponseDataBuilder,
|
InteractionResponseDataBuilder,
|
||||||
command::CommandBuilder,
|
command::CommandBuilder,
|
||||||
embed::{EmbedBuilder, EmbedFieldBuilder},
|
embed::{EmbedAuthorBuilder, EmbedBuilder, EmbedFieldBuilder},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{bot_capnp, command::State};
|
use crate::command::State;
|
||||||
|
|
||||||
const NAME: &str = "debug";
|
const NAME: &str = "info";
|
||||||
const DESCRIPTION: &str =
|
const DESCRIPTION: &str = "Show various information";
|
||||||
"(Only the bot owner can use this) Show various information for debugging purposes";
|
|
||||||
|
|
||||||
pub static COMMAND: LazyLock<Command> = LazyLock::new(|| {
|
pub static COMMAND: LazyLock<Command> = LazyLock::new(|| {
|
||||||
CommandBuilder::new(NAME, DESCRIPTION, CommandType::ChatInput)
|
CommandBuilder::new(NAME, DESCRIPTION, CommandType::ChatInput)
|
||||||
@@ -114,54 +109,22 @@ pub async fn handle(state: State, interaction: Interaction) {
|
|||||||
.await
|
.await
|
||||||
.expect("TODO");
|
.expect("TODO");
|
||||||
|
|
||||||
let heat_script_description = {
|
let heat_script_description = state
|
||||||
let compressed_result = state
|
.bot_data_manager
|
||||||
.bot_data
|
.with(|bot_data| {
|
||||||
.reader("data.bin.brotli")
|
let heat_script_option = bot_data.has_heat_script().then(|| {
|
||||||
.await
|
bot_data
|
||||||
.expect("TODO")
|
.get_heat_script()
|
||||||
.into_futures_async_read(..)
|
.expect("TODO")
|
||||||
.await;
|
.to_string()
|
||||||
|
.expect("TODO")
|
||||||
let mut buf = Vec::default();
|
});
|
||||||
let mut message = capnp::message::TypedBuilder::<bot_capnp::bot::Owned>::new_default();
|
heat_script_option.map_or("none set yet".into(), |heat_script| {
|
||||||
let fallback = message.init_root();
|
format!("```\n{heat_script}\n```")
|
||||||
|
})
|
||||||
let message_reader;
|
|
||||||
let mut bot_data = fallback.into_reader();
|
|
||||||
match compressed_result {
|
|
||||||
Ok(compressed) => {
|
|
||||||
let mut decompressed = BrotliDecoder::new(compressed);
|
|
||||||
decompressed.read_to_end(&mut buf).await.expect("TODO");
|
|
||||||
|
|
||||||
message_reader =
|
|
||||||
capnp::serialize_packed::read_message(&*buf, ReaderOptions::default())
|
|
||||||
.expect("TODO");
|
|
||||||
|
|
||||||
bot_data = message_reader
|
|
||||||
.get_root::<bot_capnp::bot::Reader>()
|
|
||||||
.expect("TODO");
|
|
||||||
}
|
|
||||||
Err(error) if error.kind() == ErrorKind::NotFound => {
|
|
||||||
tracing::error!("TODO: proceeding with fallback");
|
|
||||||
}
|
|
||||||
Err(error) => {
|
|
||||||
tracing::error!(?error, "TODO");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let heat_script_option = bot_data
|
|
||||||
.has_heat_script()
|
|
||||||
.then(|| bot_data.get_heat_script().expect("TODO"));
|
|
||||||
let heat_script_option =
|
|
||||||
heat_script_option.map(|heat_script| heat_script.to_str().expect("TODO"));
|
|
||||||
|
|
||||||
heat_script_option.map_or("none set yet".into(), |heat_script| {
|
|
||||||
format!("```\n{heat_script}\n```")
|
|
||||||
})
|
})
|
||||||
};
|
.await
|
||||||
|
.expect("TODO");
|
||||||
|
|
||||||
state
|
state
|
||||||
.discord_client
|
.discord_client
|
||||||
@@ -175,4 +138,48 @@ pub async fn handle(state: State, interaction: Interaction) {
|
|||||||
.flags(MessageFlags::EPHEMERAL)
|
.flags(MessageFlags::EPHEMERAL)
|
||||||
.await
|
.await
|
||||||
.expect("TODO");
|
.expect("TODO");
|
||||||
|
|
||||||
|
let mut user_id_stream = state.user_data_manager.list().await.expect("TODO");
|
||||||
|
|
||||||
|
while let Some(user_id) = user_id_stream.try_next().await.expect("TODO") {
|
||||||
|
let (consent, notification_script) = state
|
||||||
|
.user_data_manager
|
||||||
|
.with(user_id, |user_data| {
|
||||||
|
let consent = user_data.get_voice_recording_consent().unwrap();
|
||||||
|
let notification_script = user_data.has_notification_script().then_some(
|
||||||
|
user_data
|
||||||
|
.get_notification_script()
|
||||||
|
.expect("TODO")
|
||||||
|
.to_string()
|
||||||
|
.expect("TODO"),
|
||||||
|
);
|
||||||
|
|
||||||
|
(consent, notification_script)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.expect("TODO");
|
||||||
|
|
||||||
|
let user_mention = format!("<@{user_id}>");
|
||||||
|
|
||||||
|
state
|
||||||
|
.discord_client
|
||||||
|
.interaction(state.discord_application_id)
|
||||||
|
.create_followup(&interaction.token)
|
||||||
|
.embeds(&[EmbedBuilder::new()
|
||||||
|
.author(EmbedAuthorBuilder::new(user_mention))
|
||||||
|
.field(EmbedFieldBuilder::new("Consent", format!("{consent:?}")).build())
|
||||||
|
.field(
|
||||||
|
EmbedFieldBuilder::new(
|
||||||
|
"Notification Script",
|
||||||
|
format!("{notification_script:?}"),
|
||||||
|
)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.validate()
|
||||||
|
.unwrap()
|
||||||
|
.build()])
|
||||||
|
.flags(MessageFlags::EPHEMERAL)
|
||||||
|
.await
|
||||||
|
.expect("TODO");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
use crate::{OneToManyUniqueBTreeMap, VCs, command::State};
|
use crate::{
|
||||||
|
OneToManyUniqueBTreeMap, UserDataManager, VCs, command::State, option_ext::OptionExt as _,
|
||||||
|
user_capnp::user::Consent, user_data::RECORD_IF_CONSENT_UNSPECIFIED,
|
||||||
|
};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use futures::FutureExt;
|
||||||
use hound::{SampleFormat, WavSpec};
|
use hound::{SampleFormat, WavSpec};
|
||||||
use opendal::Operator;
|
use opendal::Operator;
|
||||||
use snafu::{OptionExt, Snafu};
|
use snafu::{OptionExt as _, Snafu};
|
||||||
use songbird::{CoreEvent, Event, EventContext, EventHandler};
|
use songbird::{CoreEvent, Event, EventContext, EventHandler};
|
||||||
use std::{
|
use std::{
|
||||||
io::Cursor,
|
io::Cursor,
|
||||||
@@ -104,6 +108,8 @@ struct Handler {
|
|||||||
|
|
||||||
audio_channels: u16,
|
audio_channels: u16,
|
||||||
audio_sample_rate: u32,
|
audio_sample_rate: u32,
|
||||||
|
|
||||||
|
user_data_manager: UserDataManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
@@ -134,6 +140,26 @@ impl EventHandler for Handler {
|
|||||||
tracing::info!(?user_id);
|
tracing::info!(?user_id);
|
||||||
|
|
||||||
if let Some(pcm) = &voice_data.decoded_voice {
|
if let Some(pcm) = &voice_data.decoded_voice {
|
||||||
|
let may_record = user_id
|
||||||
|
.map_async(|user_id| {
|
||||||
|
self.user_data_manager
|
||||||
|
.with(user_id, |user_data| {
|
||||||
|
user_data.get_voice_recording_consent().unwrap()
|
||||||
|
})
|
||||||
|
.map(|result| result.expect("TODO"))
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.map_or(RECORD_IF_CONSENT_UNSPECIFIED, |consent| match consent {
|
||||||
|
Consent::Unspecified => RECORD_IF_CONSENT_UNSPECIFIED,
|
||||||
|
Consent::Granted => true,
|
||||||
|
Consent::Withheld => false,
|
||||||
|
});
|
||||||
|
|
||||||
|
if !may_record {
|
||||||
|
tracing::warn!(?user_id, "may not be recorded");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let elapsed = self.start_instant.elapsed();
|
let elapsed = self.start_instant.elapsed();
|
||||||
let elapsed = elapsed.try_into().expect("TODO");
|
let elapsed = elapsed.try_into().expect("TODO");
|
||||||
|
|
||||||
@@ -281,6 +307,8 @@ pub async fn handle(state: State, interaction: Interaction) {
|
|||||||
|
|
||||||
audio_channels,
|
audio_channels,
|
||||||
audio_sample_rate,
|
audio_sample_rate,
|
||||||
|
|
||||||
|
user_data_manager: state.user_data_manager,
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -288,12 +316,22 @@ pub async fn handle(state: State, interaction: Interaction) {
|
|||||||
|
|
||||||
call.add_global_event(CoreEvent::SpeakingStateUpdate.into(), handler.clone());
|
call.add_global_event(CoreEvent::SpeakingStateUpdate.into(), handler.clone());
|
||||||
call.add_global_event(CoreEvent::VoiceTick.into(), handler);
|
call.add_global_event(CoreEvent::VoiceTick.into(), handler);
|
||||||
|
|
||||||
|
call.mute(true).await.expect("TODO");
|
||||||
}
|
}
|
||||||
|
|
||||||
let channel_mention = format!("<#{voice_channel_id}>");
|
let channel_mention = format!("<#{voice_channel_id}>");
|
||||||
|
|
||||||
let bot_owner_mention = format!("<@{}>", state.discord_bot_owner_user_id);
|
let bot_owner_mention = format!("<@{}>", state.discord_bot_owner_user_id);
|
||||||
|
|
||||||
|
let opt_in_mention = format!(
|
||||||
|
"</{}:{}>",
|
||||||
|
state.discord_opt_in_command_name, state.discord_opt_in_command_id
|
||||||
|
);
|
||||||
|
let opt_out_mention = format!(
|
||||||
|
"</{}:{}>",
|
||||||
|
state.discord_opt_out_command_name, state.discord_opt_out_command_id
|
||||||
|
);
|
||||||
|
|
||||||
state
|
state
|
||||||
.discord_client
|
.discord_client
|
||||||
.interaction(state.discord_application_id)
|
.interaction(state.discord_application_id)
|
||||||
@@ -302,7 +340,7 @@ pub async fn handle(state: State, interaction: Interaction) {
|
|||||||
).embeds(Some(&[
|
).embeds(Some(&[
|
||||||
EmbedBuilder::new()
|
EmbedBuilder::new()
|
||||||
.title("Joined VC to record")
|
.title("Joined VC to record")
|
||||||
.description(format!("This bot joined {channel_mention} and intends to record. Here are some pledges backed by faith (because there is no way to verify them yourself) in {bot_owner_mention}:"))
|
.description(format!("This bot joined {channel_mention} and intends to record. You can opt out with {opt_out_mention} or explicitly opt in with {opt_in_mention} (I'd appreciate this one). Here are some pledges backed by faith (because there is no way to verify them yourself) in {bot_owner_mention}:"))
|
||||||
.field(
|
.field(
|
||||||
EmbedFieldBuilder::new("Recordings are never shared", "Audio recordings are only stored on my home server and desktop computer and will never be uploaded to services or hardware that is owned by another person: not even curated clips, and not even to people who were in the recording. When transcription to text is implemented, this will only be run on my personally owned devices and not on any internet or cloud offering.").build()
|
EmbedFieldBuilder::new("Recordings are never shared", "Audio recordings are only stored on my home server and desktop computer and will never be uploaded to services or hardware that is owned by another person: not even curated clips, and not even to people who were in the recording. When transcription to text is implemented, this will only be run on my personally owned devices and not on any internet or cloud offering.").build()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,37 +3,45 @@ use std::{fmt::Debug, sync::Arc};
|
|||||||
use futures::future::BoxFuture;
|
use futures::future::BoxFuture;
|
||||||
use opendal::Operator;
|
use opendal::Operator;
|
||||||
use patricia_tree::StringPatriciaMap;
|
use patricia_tree::StringPatriciaMap;
|
||||||
use songbird::{Songbird, driver::{Channels, SampleRate}};
|
use songbird::{
|
||||||
|
Songbird,
|
||||||
|
driver::{Channels, SampleRate},
|
||||||
|
};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
use twilight_model::{
|
use twilight_model::{
|
||||||
application::{command::Command, interaction::Interaction},
|
application::{command::Command, interaction::Interaction},
|
||||||
id::{
|
id::{
|
||||||
Id,
|
Id,
|
||||||
marker::{ApplicationMarker, UserMarker},
|
marker::{ApplicationMarker, CommandMarker, UserMarker},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::VCs;
|
use crate::{BotDataManager, GuildVoiceChannelToTextChannel, UserDataManager, VCs};
|
||||||
|
|
||||||
mod debug;
|
pub mod info;
|
||||||
mod join;
|
pub mod join;
|
||||||
mod leave;
|
pub mod leave;
|
||||||
mod opt_in;
|
pub mod opt_in;
|
||||||
mod opt_out;
|
pub mod opt_out;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub audio_channels: Channels,
|
pub audio_channels: Channels,
|
||||||
pub audio_sample_rate: SampleRate,
|
pub audio_sample_rate: SampleRate,
|
||||||
pub bot_data: Operator,
|
pub bot_data_manager: BotDataManager,
|
||||||
pub cancellation_token: CancellationToken,
|
pub cancellation_token: CancellationToken,
|
||||||
pub discord_application_id: Id<ApplicationMarker>,
|
pub discord_application_id: Id<ApplicationMarker>,
|
||||||
pub discord_bot_owner_user_id: Id<UserMarker>,
|
pub discord_bot_owner_user_id: Id<UserMarker>,
|
||||||
pub discord_client: Arc<twilight_http::Client>,
|
pub discord_client: Arc<twilight_http::Client>,
|
||||||
|
pub discord_opt_in_command_id: Id<CommandMarker>,
|
||||||
|
pub discord_opt_in_command_name: Arc<str>,
|
||||||
|
pub discord_opt_out_command_id: Id<CommandMarker>,
|
||||||
|
pub discord_opt_out_command_name: Arc<str>,
|
||||||
pub discord_user_id: Id<UserMarker>,
|
pub discord_user_id: Id<UserMarker>,
|
||||||
|
pub discord_voice_channel_corresponding_text_channel: Arc<GuildVoiceChannelToTextChannel>,
|
||||||
pub recording_data: Operator,
|
pub recording_data: Operator,
|
||||||
pub songbird: Arc<Songbird>,
|
pub songbird: Arc<Songbird>,
|
||||||
pub user_data: Operator,
|
pub user_data_manager: UserDataManager,
|
||||||
pub vcs: Arc<VCs>,
|
pub vcs: Arc<VCs>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +58,7 @@ where
|
|||||||
|
|
||||||
pub fn all() -> Vec<(&'static Command, BoxedHandler)> {
|
pub fn all() -> Vec<(&'static Command, BoxedHandler)> {
|
||||||
vec![
|
vec![
|
||||||
(&debug::COMMAND, box_handler(debug::handle)),
|
(&info::COMMAND, box_handler(info::handle)),
|
||||||
(&join::COMMAND, box_handler(join::handle)),
|
(&join::COMMAND, box_handler(join::handle)),
|
||||||
(&leave::COMMAND, box_handler(leave::handle)),
|
(&leave::COMMAND, box_handler(leave::handle)),
|
||||||
(&opt_in::COMMAND, box_handler(opt_in::handle)),
|
(&opt_in::COMMAND, box_handler(opt_in::handle)),
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
use twilight_model::application::{
|
use twilight_model::{
|
||||||
command::{Command, CommandType},
|
application::{
|
||||||
interaction::Interaction,
|
command::{Command, CommandType},
|
||||||
|
interaction::Interaction,
|
||||||
|
},
|
||||||
|
channel::message::MessageFlags,
|
||||||
|
http::interaction::{InteractionResponse, InteractionResponseType},
|
||||||
};
|
};
|
||||||
use twilight_util::builder::command::CommandBuilder;
|
use twilight_util::builder::{InteractionResponseDataBuilder, command::CommandBuilder};
|
||||||
|
|
||||||
use crate::command::State;
|
use crate::{command::State, user_capnp::user::Consent};
|
||||||
|
|
||||||
const NAME: &str = "opt-in";
|
const NAME: &str = "opt-in";
|
||||||
const DESCRIPTION: &str = "Opt in to being recorded";
|
const DESCRIPTION: &str = "Opt in to being recorded";
|
||||||
@@ -20,5 +24,67 @@ pub static COMMAND: LazyLock<Command> = LazyLock::new(|| {
|
|||||||
|
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
pub async fn handle(state: State, interaction: Interaction) {
|
pub async fn handle(state: State, interaction: Interaction) {
|
||||||
todo!();
|
let user_id = interaction
|
||||||
|
.member
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|member| member.user.as_ref().map(|user| user.id));
|
||||||
|
|
||||||
|
let user_id = match user_id {
|
||||||
|
Some(user_id) => user_id,
|
||||||
|
None => {
|
||||||
|
state
|
||||||
|
.discord_client
|
||||||
|
.interaction(state.discord_application_id)
|
||||||
|
.create_response(
|
||||||
|
interaction.id,
|
||||||
|
&interaction.token,
|
||||||
|
&InteractionResponse {
|
||||||
|
kind: InteractionResponseType::ChannelMessageWithSource,
|
||||||
|
data: Some(
|
||||||
|
InteractionResponseDataBuilder::new()
|
||||||
|
.content("TODO")
|
||||||
|
.build(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("TODO");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let previous_consent = state
|
||||||
|
.user_data_manager
|
||||||
|
.update(user_id, |mut user_data| {
|
||||||
|
let previous_consent = user_data
|
||||||
|
.reborrow()
|
||||||
|
.get_voice_recording_consent()
|
||||||
|
.expect("TODO");
|
||||||
|
user_data.set_voice_recording_consent(Consent::Granted);
|
||||||
|
|
||||||
|
previous_consent
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.expect("TODO");
|
||||||
|
|
||||||
|
state
|
||||||
|
.discord_client
|
||||||
|
.interaction(state.discord_application_id)
|
||||||
|
.create_response(
|
||||||
|
interaction.id,
|
||||||
|
&interaction.token,
|
||||||
|
&InteractionResponse {
|
||||||
|
kind: InteractionResponseType::ChannelMessageWithSource,
|
||||||
|
data: Some(
|
||||||
|
InteractionResponseDataBuilder::new()
|
||||||
|
.content(format!(
|
||||||
|
"opted you in, your previous consent was {previous_consent:?}"
|
||||||
|
))
|
||||||
|
.flags(MessageFlags::EPHEMERAL)
|
||||||
|
.build(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("TODO");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
use twilight_model::application::{
|
use twilight_model::{
|
||||||
command::{Command, CommandType},
|
application::{
|
||||||
interaction::Interaction,
|
command::{Command, CommandType},
|
||||||
|
interaction::Interaction,
|
||||||
|
},
|
||||||
|
channel::message::MessageFlags,
|
||||||
|
http::interaction::{InteractionResponse, InteractionResponseType},
|
||||||
};
|
};
|
||||||
use twilight_util::builder::command::CommandBuilder;
|
use twilight_util::builder::{InteractionResponseDataBuilder, command::CommandBuilder};
|
||||||
|
|
||||||
use crate::command::State;
|
use crate::{command::State, user_capnp::user::Consent};
|
||||||
|
|
||||||
const NAME: &str = "opt-out";
|
const NAME: &str = "opt-out";
|
||||||
const DESCRIPTION: &str = "Opt out of being recorded";
|
const DESCRIPTION: &str = "Opt out of being recorded";
|
||||||
@@ -20,5 +24,67 @@ pub static COMMAND: LazyLock<Command> = LazyLock::new(|| {
|
|||||||
|
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
pub async fn handle(state: State, interaction: Interaction) {
|
pub async fn handle(state: State, interaction: Interaction) {
|
||||||
todo!();
|
let user_id = interaction
|
||||||
|
.member
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|member| member.user.as_ref().map(|user| user.id));
|
||||||
|
|
||||||
|
let user_id = match user_id {
|
||||||
|
Some(user_id) => user_id,
|
||||||
|
None => {
|
||||||
|
state
|
||||||
|
.discord_client
|
||||||
|
.interaction(state.discord_application_id)
|
||||||
|
.create_response(
|
||||||
|
interaction.id,
|
||||||
|
&interaction.token,
|
||||||
|
&InteractionResponse {
|
||||||
|
kind: InteractionResponseType::ChannelMessageWithSource,
|
||||||
|
data: Some(
|
||||||
|
InteractionResponseDataBuilder::new()
|
||||||
|
.content("TODO")
|
||||||
|
.build(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("TODO");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let previous_consent = state
|
||||||
|
.user_data_manager
|
||||||
|
.update(user_id, |mut user_data| {
|
||||||
|
let previous_consent = user_data
|
||||||
|
.reborrow()
|
||||||
|
.get_voice_recording_consent()
|
||||||
|
.expect("TODO");
|
||||||
|
user_data.set_voice_recording_consent(Consent::Withheld);
|
||||||
|
|
||||||
|
previous_consent
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.expect("TODO");
|
||||||
|
|
||||||
|
state
|
||||||
|
.discord_client
|
||||||
|
.interaction(state.discord_application_id)
|
||||||
|
.create_response(
|
||||||
|
interaction.id,
|
||||||
|
&interaction.token,
|
||||||
|
&InteractionResponse {
|
||||||
|
kind: InteractionResponseType::ChannelMessageWithSource,
|
||||||
|
data: Some(
|
||||||
|
InteractionResponseDataBuilder::new()
|
||||||
|
.content(format!(
|
||||||
|
"opted you out, your previous consent was {previous_consent:?}"
|
||||||
|
))
|
||||||
|
.flags(MessageFlags::EPHEMERAL)
|
||||||
|
.build(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("TODO");
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/lib.rs
16
src/lib.rs
@@ -1,18 +1,24 @@
|
|||||||
mod command;
|
mod bot_data;
|
||||||
|
pub mod command;
|
||||||
mod one_to_many;
|
mod one_to_many;
|
||||||
mod one_to_many_with_data;
|
mod one_to_many_with_data;
|
||||||
mod one_to_one;
|
mod one_to_one;
|
||||||
|
mod operator_ext;
|
||||||
|
mod option_ext;
|
||||||
mod storage;
|
mod storage;
|
||||||
mod track_vcs;
|
mod track_vcs;
|
||||||
|
mod user_data;
|
||||||
mod vc_user;
|
mod vc_user;
|
||||||
|
capnp::generated_code!(mod bot_capnp);
|
||||||
|
capnp::generated_code!(mod user_capnp);
|
||||||
|
|
||||||
|
pub use bot_data::BotDataManager;
|
||||||
pub use command::{Router as CommandRouter, State, all as all_commands};
|
pub use command::{Router as CommandRouter, State, all as all_commands};
|
||||||
pub use one_to_many::OneToManyUniqueBTreeMap;
|
pub use one_to_many::OneToManyUniqueBTreeMap;
|
||||||
pub use one_to_many_with_data::OneToManyUniqueBTreeMapWithData;
|
pub use one_to_many_with_data::OneToManyUniqueBTreeMapWithData;
|
||||||
pub use one_to_one::OneToOneBTreeMap;
|
pub use one_to_one::OneToOneBTreeMap;
|
||||||
|
pub use operator_ext::OperatorExt;
|
||||||
pub use storage::Storage;
|
pub use storage::Storage;
|
||||||
pub use track_vcs::{VCs, initialize_vcs, update_vcs};
|
pub use track_vcs::{GuildVoiceChannelToTextChannel, VCs, initialize_vcs, update_vcs};
|
||||||
|
pub use user_data::UserDataManager;
|
||||||
pub use vc_user::{UserInVCData, VoiceStatus};
|
pub use vc_user::{UserInVCData, VoiceStatus};
|
||||||
|
|
||||||
capnp::generated_code!(pub mod user_capnp);
|
|
||||||
capnp::generated_code!(pub mod bot_capnp);
|
|
||||||
|
|||||||
114
src/main.rs
114
src/main.rs
@@ -1,13 +1,16 @@
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use fomo_reducer::{CommandRouter, State, Storage, all_commands, initialize_vcs, update_vcs};
|
use fomo_reducer::{
|
||||||
|
BotDataManager, CommandRouter, GuildVoiceChannelToTextChannel, State, Storage, UserDataManager,
|
||||||
|
all_commands, command, initialize_vcs, update_vcs,
|
||||||
|
};
|
||||||
use secrecy::{ExposeSecret, SecretString};
|
use secrecy::{ExposeSecret, SecretString};
|
||||||
use snafu::Snafu;
|
use snafu::{OptionExt, ResultExt, Snafu};
|
||||||
use songbird::{
|
use songbird::{
|
||||||
Config, Songbird,
|
Config, Songbird,
|
||||||
driver::{Channels, DecodeConfig, SampleRate},
|
driver::{Channels, DecodeConfig, SampleRate},
|
||||||
shards::TwilightMap,
|
shards::TwilightMap,
|
||||||
};
|
};
|
||||||
use std::{fmt::Debug, sync::Arc};
|
use std::{collections::BTreeMap, fmt::Debug, str::FromStr, sync::Arc};
|
||||||
use strum::EnumString;
|
use strum::EnumString;
|
||||||
use tokio::{select, signal::ctrl_c, task::JoinSet};
|
use tokio::{select, signal::ctrl_c, task::JoinSet};
|
||||||
use tokio_util::{sync::CancellationToken, time::FutureExt as _};
|
use tokio_util::{sync::CancellationToken, time::FutureExt as _};
|
||||||
@@ -19,7 +22,10 @@ use twilight_model::{
|
|||||||
payload::{incoming::InteractionCreate, outgoing::UpdatePresence},
|
payload::{incoming::InteractionCreate, outgoing::UpdatePresence},
|
||||||
presence::{ActivityType, MinimalActivity, Status},
|
presence::{ActivityType, MinimalActivity, Status},
|
||||||
},
|
},
|
||||||
id::{Id, marker::UserMarker},
|
id::{
|
||||||
|
Id,
|
||||||
|
marker::{ChannelMarker, GuildMarker, UserMarker},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, strum::Display, EnumString)]
|
#[derive(Clone, Copy, Debug, strum::Display, EnumString)]
|
||||||
@@ -63,6 +69,41 @@ impl From<AudioSampleRate> for SampleRate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Snafu)]
|
||||||
|
enum ParseGuildVCToTextChannelError {
|
||||||
|
NoScope,
|
||||||
|
|
||||||
|
NoRelation,
|
||||||
|
|
||||||
|
ParseGuildError {
|
||||||
|
source: <Id<GuildMarker> as FromStr>::Err,
|
||||||
|
},
|
||||||
|
|
||||||
|
ParseVoiceChannelError {
|
||||||
|
source: <Id<ChannelMarker> as FromStr>::Err,
|
||||||
|
},
|
||||||
|
|
||||||
|
ParseTextChannelError {
|
||||||
|
source: <Id<ChannelMarker> as FromStr>::Err,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_guild_vc_to_text_channel(
|
||||||
|
source: &str,
|
||||||
|
) -> Result<(Id<GuildMarker>, Id<ChannelMarker>, Id<ChannelMarker>), ParseGuildVCToTextChannelError>
|
||||||
|
{
|
||||||
|
let (guild, voice_channel_and_text_channel) = source.split_once(':').context(NoScopeSnafu)?;
|
||||||
|
let (voice_channel, text_channel) = voice_channel_and_text_channel
|
||||||
|
.split_once("->")
|
||||||
|
.context(NoRelationSnafu)?;
|
||||||
|
|
||||||
|
let guild = guild.parse().context(ParseGuildSnafu)?;
|
||||||
|
let voice_channel = voice_channel.parse().context(ParseVoiceChannelSnafu)?;
|
||||||
|
let text_channel = text_channel.parse().context(ParseTextChannelSnafu)?;
|
||||||
|
|
||||||
|
Ok((guild, voice_channel, text_channel))
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
struct AppArgs {
|
struct AppArgs {
|
||||||
#[arg(long, env)]
|
#[arg(long, env)]
|
||||||
@@ -77,6 +118,10 @@ struct AppArgs {
|
|||||||
#[arg(long, env)]
|
#[arg(long, env)]
|
||||||
discord_status: Option<Arc<str>>,
|
discord_status: Option<Arc<str>>,
|
||||||
|
|
||||||
|
#[arg(long, env, value_parser = parse_guild_vc_to_text_channel)]
|
||||||
|
discord_voice_channel_corresponding_text_channel:
|
||||||
|
Vec<(Id<GuildMarker>, Id<ChannelMarker>, Id<ChannelMarker>)>,
|
||||||
|
|
||||||
#[arg(long, env, default_value_t = AudioChannels::Mono)]
|
#[arg(long, env, default_value_t = AudioChannels::Mono)]
|
||||||
audio_channels: AudioChannels,
|
audio_channels: AudioChannels,
|
||||||
|
|
||||||
@@ -141,6 +186,7 @@ async fn main() -> Result<(), MainError> {
|
|||||||
discord_bot_owner_user_id,
|
discord_bot_owner_user_id,
|
||||||
discord_nickname,
|
discord_nickname,
|
||||||
discord_status,
|
discord_status,
|
||||||
|
discord_voice_channel_corresponding_text_channel,
|
||||||
audio_channels,
|
audio_channels,
|
||||||
audio_sample_rate,
|
audio_sample_rate,
|
||||||
bot_data,
|
bot_data,
|
||||||
@@ -229,7 +275,7 @@ async fn main() -> Result<(), MainError> {
|
|||||||
|
|
||||||
let commands = all_commands();
|
let commands = all_commands();
|
||||||
|
|
||||||
let _returned_commands = interaction_client
|
let returned_commands = interaction_client
|
||||||
.set_global_commands(
|
.set_global_commands(
|
||||||
Vec::from_iter(
|
Vec::from_iter(
|
||||||
commands
|
commands
|
||||||
@@ -244,11 +290,30 @@ async fn main() -> Result<(), MainError> {
|
|||||||
.await
|
.await
|
||||||
.expect("failed to deserialize set commands"); // TODO
|
.expect("failed to deserialize set commands"); // TODO
|
||||||
|
|
||||||
let command_router = CommandRouter::from_iter(commands);
|
let mut discord_command_name_to_returned_command = BTreeMap::from_iter(
|
||||||
let command_router = Arc::new(command_router);
|
returned_commands
|
||||||
|
.into_iter()
|
||||||
|
.map(|command| (command.name.clone(), command)),
|
||||||
|
);
|
||||||
|
|
||||||
|
let discord_opt_in_command = discord_command_name_to_returned_command
|
||||||
|
.remove(&command::opt_in::COMMAND.name)
|
||||||
|
.expect("TODO");
|
||||||
|
let discord_opt_out_command = discord_command_name_to_returned_command
|
||||||
|
.remove(&command::opt_out::COMMAND.name)
|
||||||
|
.expect("TODO");
|
||||||
|
|
||||||
|
let discord_opt_in_command_id = discord_opt_in_command.id.expect("TODO");
|
||||||
|
let discord_opt_out_command_id = discord_opt_out_command.id.expect("TODO");
|
||||||
|
|
||||||
|
let discord_opt_in_command_name = discord_opt_in_command.name.into();
|
||||||
|
let discord_opt_out_command_name = discord_opt_out_command.name.into();
|
||||||
|
|
||||||
let vcs = initialize_vcs(&discord_client).await;
|
let vcs = initialize_vcs(&discord_client).await;
|
||||||
|
|
||||||
|
let command_router = CommandRouter::from_iter(commands);
|
||||||
|
let command_router = Arc::new(command_router);
|
||||||
|
|
||||||
let discord_client = Arc::new(discord_client);
|
let discord_client = Arc::new(discord_client);
|
||||||
let songbird = Arc::new(songbird);
|
let songbird = Arc::new(songbird);
|
||||||
let vcs = Arc::new(vcs);
|
let vcs = Arc::new(vcs);
|
||||||
@@ -257,18 +322,42 @@ async fn main() -> Result<(), MainError> {
|
|||||||
let recording_data = recording_data.into_inner();
|
let recording_data = recording_data.into_inner();
|
||||||
let user_data = user_data.into_inner();
|
let user_data = user_data.into_inner();
|
||||||
|
|
||||||
|
let bot_data_manager = BotDataManager::new(bot_data);
|
||||||
|
let user_data_manager = UserDataManager::new(user_data);
|
||||||
|
|
||||||
|
let discord_voice_channel_corresponding_text_channel = {
|
||||||
|
let mut map = GuildVoiceChannelToTextChannel::default();
|
||||||
|
|
||||||
|
for (guild_id, voice_channel_id, text_channel_id) in
|
||||||
|
discord_voice_channel_corresponding_text_channel
|
||||||
|
{
|
||||||
|
map.entry(guild_id)
|
||||||
|
.or_default()
|
||||||
|
.insert(voice_channel_id, text_channel_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
map
|
||||||
|
};
|
||||||
|
let discord_voice_channel_corresponding_text_channel =
|
||||||
|
Arc::new(discord_voice_channel_corresponding_text_channel);
|
||||||
|
|
||||||
let state = State {
|
let state = State {
|
||||||
audio_channels,
|
audio_channels,
|
||||||
audio_sample_rate,
|
audio_sample_rate,
|
||||||
bot_data,
|
bot_data_manager,
|
||||||
cancellation_token: cancellation_token.clone(),
|
cancellation_token: cancellation_token.clone(),
|
||||||
discord_application_id,
|
discord_application_id,
|
||||||
discord_bot_owner_user_id,
|
discord_bot_owner_user_id,
|
||||||
discord_client,
|
discord_client,
|
||||||
|
discord_opt_in_command_id,
|
||||||
|
discord_opt_in_command_name,
|
||||||
|
discord_opt_out_command_id,
|
||||||
|
discord_opt_out_command_name,
|
||||||
discord_user_id,
|
discord_user_id,
|
||||||
|
discord_voice_channel_corresponding_text_channel,
|
||||||
recording_data,
|
recording_data,
|
||||||
songbird,
|
songbird,
|
||||||
user_data,
|
user_data_manager,
|
||||||
vcs,
|
vcs,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -344,7 +433,12 @@ async fn handle_events(command_router: Arc<CommandRouter>, state: State, mut sha
|
|||||||
Ok(event) => {
|
Ok(event) => {
|
||||||
handle_event(command_router.clone(), state.clone(), event).await;
|
handle_event(command_router.clone(), state.clone(), event).await;
|
||||||
}
|
}
|
||||||
Err(reconnect_error) if matches!(reconnect_error.kind(), &twilight_gateway::error::ReceiveMessageErrorType::Reconnect) => {
|
Err(reconnect_error)
|
||||||
|
if matches!(
|
||||||
|
reconnect_error.kind(),
|
||||||
|
&twilight_gateway::error::ReceiveMessageErrorType::Reconnect
|
||||||
|
) =>
|
||||||
|
{
|
||||||
tracing::error!(?reconnect_error);
|
tracing::error!(?reconnect_error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/operator_ext.rs
Normal file
25
src/operator_ext.rs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
use extension_traits::extension;
|
||||||
|
use opendal::{Buffer, Error, ErrorKind, FuturesAsyncReader, Operator};
|
||||||
|
|
||||||
|
#[extension(pub trait OperatorExt)]
|
||||||
|
impl Operator {
|
||||||
|
async fn read_if_exists(&self, path: &str) -> Result<Option<Buffer>, Error> {
|
||||||
|
match self.read(path).await {
|
||||||
|
Ok(buffer) => Ok(Some(buffer)),
|
||||||
|
Err(error) if matches!(error.kind(), ErrorKind::NotFound) => Ok(None),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn async_reader_if_exists(
|
||||||
|
&self,
|
||||||
|
path: &str,
|
||||||
|
) -> Result<Option<FuturesAsyncReader>, Error> {
|
||||||
|
let reader = self.reader(path).await?;
|
||||||
|
match reader.into_futures_async_read(..).await {
|
||||||
|
Ok(reader) => Ok(Some(reader)),
|
||||||
|
Err(error) if matches!(error.kind(), ErrorKind::NotFound) => Ok(None),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/option_ext.rs
Normal file
11
src/option_ext.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use extension_traits::extension;
|
||||||
|
|
||||||
|
#[extension(pub trait OptionExt)]
|
||||||
|
impl<S> Option<S> {
|
||||||
|
async fn map_async<M, Fut: Future<Output = M>, F: FnOnce(S) -> Fut>(self, f: F) -> Option<M> {
|
||||||
|
match self {
|
||||||
|
Some(s) => Some(f(s).await),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ use std::{fmt::Debug, str::FromStr};
|
|||||||
|
|
||||||
use opendal::{IntoOperatorUri, Operator, OperatorUri};
|
use opendal::{IntoOperatorUri, Operator, OperatorUri};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Storage {
|
pub struct Storage {
|
||||||
uri: OperatorUri,
|
uri: OperatorUri,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use futures::{StreamExt, stream::FuturesUnordered};
|
use futures::{StreamExt, stream::FuturesUnordered};
|
||||||
use twilight_model::{
|
use twilight_model::{
|
||||||
@@ -8,10 +10,12 @@ use twilight_model::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{OneToManyUniqueBTreeMapWithData, UserInVCData, VoiceStatus};
|
use crate::{OneToManyUniqueBTreeMapWithData, OneToOneBTreeMap, UserInVCData, VoiceStatus};
|
||||||
|
|
||||||
|
pub type GuildVoiceChannelToTextChannel =
|
||||||
|
BTreeMap<Id<GuildMarker>, OneToOneBTreeMap<Id<ChannelMarker>, Id<ChannelMarker>>>;
|
||||||
|
|
||||||
type VCsInGuild = OneToManyUniqueBTreeMapWithData<Id<ChannelMarker>, Id<UserMarker>, UserInVCData>;
|
type VCsInGuild = OneToManyUniqueBTreeMapWithData<Id<ChannelMarker>, Id<UserMarker>, UserInVCData>;
|
||||||
|
|
||||||
pub type VCs = DashMap<Id<GuildMarker>, VCsInGuild>;
|
pub type VCs = DashMap<Id<GuildMarker>, VCsInGuild>;
|
||||||
|
|
||||||
#[tracing::instrument(skip(discord_client), ret)]
|
#[tracing::instrument(skip(discord_client), ret)]
|
||||||
|
|||||||
254
src/user_data.rs
Normal file
254
src/user_data.rs
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use async_compression::futures::{bufread::BrotliDecoder, write::BrotliEncoder};
|
||||||
|
use capnp::message::TypedBuilder;
|
||||||
|
use futures::{AsyncReadExt, AsyncWriteExt, TryStream, TryStreamExt};
|
||||||
|
use opendal::Operator;
|
||||||
|
use snafu::{OptionExt as _, ResultExt as _, Snafu, ensure};
|
||||||
|
use twilight_model::id::{Id, marker::UserMarker};
|
||||||
|
|
||||||
|
use crate::{OperatorExt, option_ext::OptionExt as _, user_capnp};
|
||||||
|
|
||||||
|
pub const RECORD_IF_CONSENT_UNSPECIFIED: bool = true;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct UserDataManager {
|
||||||
|
operator: Operator,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserDataManager {
|
||||||
|
pub fn new(operator: Operator) -> Self {
|
||||||
|
Self { operator }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(id: Id<UserMarker>) -> String {
|
||||||
|
format!("{id}/data.bin.brotli")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Snafu)]
|
||||||
|
#[snafu(module)]
|
||||||
|
pub enum ParsePathError {
|
||||||
|
/// paths must have a / in them because that's how user data is stored, but this one doesn't have one
|
||||||
|
MissingSlashError,
|
||||||
|
|
||||||
|
/// if this isn't a directory, then the file must be "data.bin.brotli" but it was actually {actual:?}
|
||||||
|
WrongFileError { actual: String },
|
||||||
|
|
||||||
|
/// couldn't parse the directory as a user ID
|
||||||
|
ParseUserIdError {
|
||||||
|
source: <Id<UserMarker> as FromStr>::Err,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(path: &str) -> Result<Id<UserMarker>, ParsePathError> {
|
||||||
|
let (directory, file) = path
|
||||||
|
.rsplit_once("/")
|
||||||
|
.context(parse_path_error::MissingSlashSnafu)?;
|
||||||
|
|
||||||
|
ensure!(
|
||||||
|
file == "" || file == "data.bin.brotli",
|
||||||
|
parse_path_error::WrongFileSnafu {
|
||||||
|
actual: file.to_owned()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let user_id = directory
|
||||||
|
.parse()
|
||||||
|
.context(parse_path_error::ParseUserIdSnafu)?;
|
||||||
|
|
||||||
|
Ok(user_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Snafu)]
|
||||||
|
#[snafu(module)]
|
||||||
|
pub enum ListError {
|
||||||
|
/// error creating a lister through the storage operator
|
||||||
|
CreateListerError { source: opendal::Error },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Snafu)]
|
||||||
|
#[snafu(module)]
|
||||||
|
pub enum EntryError {
|
||||||
|
/// failed to get an entry from the storage operator's lister
|
||||||
|
ReceiveEntryError { source: opendal::Error },
|
||||||
|
|
||||||
|
/// failed to parse the entry as an acceptable path
|
||||||
|
ParsePathError { source: ParsePathError },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserDataManager {
|
||||||
|
pub async fn list(
|
||||||
|
&self,
|
||||||
|
) -> Result<impl TryStream<Ok = Id<UserMarker>, Error = EntryError> + Unpin, ListError> {
|
||||||
|
let lister = self
|
||||||
|
.operator
|
||||||
|
.lister("")
|
||||||
|
.await
|
||||||
|
.context(list_error::CreateListerSnafu)?;
|
||||||
|
|
||||||
|
Ok(lister
|
||||||
|
.map_err(|error| EntryError::ReceiveEntryError { source: error })
|
||||||
|
.and_then(|entry| {
|
||||||
|
std::future::ready(parse(entry.path()).context(entry_error::ParsePathSnafu))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Snafu)]
|
||||||
|
#[snafu(module)]
|
||||||
|
pub enum WithError {
|
||||||
|
/// couldn't read data for this user from the storage operator
|
||||||
|
ReadError { source: opendal::Error },
|
||||||
|
|
||||||
|
/// couldn't decompress the user data from storage
|
||||||
|
DecompressionError { source: std::io::Error },
|
||||||
|
|
||||||
|
/// couldn't deserialize the user data
|
||||||
|
DeserializeError { source: capnp::Error },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserDataManager {
|
||||||
|
pub async fn with<R>(
|
||||||
|
&self,
|
||||||
|
id: Id<UserMarker>,
|
||||||
|
f: impl FnOnce(user_capnp::user::Reader<'_>) -> R,
|
||||||
|
) -> Result<R, WithError> {
|
||||||
|
let compressed_buffer = self
|
||||||
|
.operator
|
||||||
|
.async_reader_if_exists(&path(id))
|
||||||
|
.await
|
||||||
|
.context(with_error::ReadSnafu)?;
|
||||||
|
|
||||||
|
let decompressed_reader = compressed_buffer.map(BrotliDecoder::new);
|
||||||
|
let decompressed = decompressed_reader
|
||||||
|
.map_async(|mut reader| async move {
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
reader.read_to_end(&mut vec).await?;
|
||||||
|
Ok(vec)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.transpose()
|
||||||
|
.context(with_error::DecompressionSnafu)?;
|
||||||
|
|
||||||
|
let mut message = TypedBuilder::<user_capnp::user::Owned>::new_default();
|
||||||
|
let fallback = message.init_root();
|
||||||
|
|
||||||
|
let mut user_data = fallback.into_reader();
|
||||||
|
let message_reader;
|
||||||
|
|
||||||
|
if let Some(mut bytes) = decompressed.as_deref() {
|
||||||
|
message_reader = capnp::serialize::read_message_from_flat_slice_no_alloc(
|
||||||
|
&mut bytes,
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
|
.context(with_error::DeserializeSnafu)?;
|
||||||
|
|
||||||
|
user_data = message_reader
|
||||||
|
.get_root()
|
||||||
|
.context(with_error::DeserializeSnafu)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(f(user_data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Snafu)]
|
||||||
|
#[snafu(module)]
|
||||||
|
pub enum UpdateError {
|
||||||
|
/// couldn't read data for this user from the storage operator
|
||||||
|
ReadError { source: opendal::Error },
|
||||||
|
|
||||||
|
/// couldn't decompress the user data from storage
|
||||||
|
DecompressionError { source: std::io::Error },
|
||||||
|
|
||||||
|
/// couldn't deserialize the user data
|
||||||
|
DeserializeError { source: capnp::Error },
|
||||||
|
|
||||||
|
/// couldn't serialize the (modified) user data
|
||||||
|
SerializeError { source: capnp::Error },
|
||||||
|
|
||||||
|
/// couldn't create a writer for this user data in the storage operator
|
||||||
|
WriterError { source: opendal::Error },
|
||||||
|
|
||||||
|
/// couldn't write (modified) data for this user to the storage operator
|
||||||
|
WriteError { source: std::io::Error },
|
||||||
|
|
||||||
|
/// couldn't finalize writing (modified) data for this user to the storage operator
|
||||||
|
FinalizeError { source: std::io::Error },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserDataManager {
|
||||||
|
pub async fn update<R>(
|
||||||
|
&self,
|
||||||
|
id: Id<UserMarker>,
|
||||||
|
f: impl FnOnce(user_capnp::user::Builder<'_>) -> R,
|
||||||
|
) -> Result<R, UpdateError> {
|
||||||
|
let path = path(id);
|
||||||
|
let compressed_buffer = self
|
||||||
|
.operator
|
||||||
|
.async_reader_if_exists(&path)
|
||||||
|
.await
|
||||||
|
.context(update_error::ReadSnafu)?;
|
||||||
|
|
||||||
|
let decompressed_reader = compressed_buffer.map(BrotliDecoder::new);
|
||||||
|
let decompressed = decompressed_reader
|
||||||
|
.map_async(|mut reader| async move {
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
reader.read_to_end(&mut vec).await?;
|
||||||
|
Ok(vec)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.transpose()
|
||||||
|
.context(update_error::DecompressionSnafu)?;
|
||||||
|
|
||||||
|
let mut message = TypedBuilder::<user_capnp::user::Owned>::new_default();
|
||||||
|
|
||||||
|
let ret = if let Some(mut bytes) = decompressed.as_deref() {
|
||||||
|
let message_reader = capnp::serialize::read_message_from_flat_slice_no_alloc(
|
||||||
|
&mut bytes,
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
|
.context(update_error::DeserializeSnafu)?;
|
||||||
|
|
||||||
|
let user_data = message_reader
|
||||||
|
.get_root()
|
||||||
|
.context(update_error::DeserializeSnafu)?;
|
||||||
|
|
||||||
|
message
|
||||||
|
.set_root(user_data)
|
||||||
|
.context(update_error::DeserializeSnafu)?;
|
||||||
|
|
||||||
|
f(
|
||||||
|
message.get_root().unwrap(), // this is logically impossible
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
f(message.init_root())
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
capnp::serialize::write_message(&mut buffer, message.borrow_inner())
|
||||||
|
.context(update_error::SerializeSnafu)?;
|
||||||
|
|
||||||
|
let compressed_writer = self
|
||||||
|
.operator
|
||||||
|
.writer(&path)
|
||||||
|
.await
|
||||||
|
.context(update_error::WriterSnafu)?
|
||||||
|
.into_futures_async_write();
|
||||||
|
|
||||||
|
let mut decompressed_writer = BrotliEncoder::new(compressed_writer);
|
||||||
|
|
||||||
|
decompressed_writer
|
||||||
|
.write_all(&buffer)
|
||||||
|
.await
|
||||||
|
.context(update_error::WriteSnafu)?;
|
||||||
|
|
||||||
|
decompressed_writer
|
||||||
|
.close()
|
||||||
|
.await
|
||||||
|
.context(update_error::FinalizeSnafu)?;
|
||||||
|
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,5 +3,11 @@
|
|||||||
struct User {
|
struct User {
|
||||||
notificationScript @0 :Text;
|
notificationScript @0 :Text;
|
||||||
|
|
||||||
voiceRecordingConsent @1 :Bool;
|
voiceRecordingConsent @1 :Consent = unspecified;
|
||||||
|
|
||||||
|
enum Consent {
|
||||||
|
unspecified @0;
|
||||||
|
granted @1;
|
||||||
|
withheld @2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user