Compare commits
No commits in common. "6c6a87ce5b8b11f48e3b0b8e12a23299e3e5fcca" and "7683ce49a39e65f78c438520bd571fc10806b332" have entirely different histories.
6c6a87ce5b
...
7683ce49a3
|
@ -1,35 +0,0 @@
|
|||
name: cargo doc lints
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main", "preserve/*" ]
|
||||
pull_request:
|
||||
branches: [ "main", "dev" ]
|
||||
|
||||
jobs:
|
||||
cargo-doc-lints:
|
||||
name: Run cargo doc for doc lints
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Install aditional components for sarif
|
||||
run: cargo install clippy-sarif sarif-fmt
|
||||
|
||||
- name: Run cargo doc
|
||||
run: cargo doc --no-deps --all-features --locked --message-format=json | clippy-sarif | sed 's/rust-lang.github.io\/rust-clippy/doc.rust-lang.org\/rustdoc\/lints.html/g' | sed 's/clippy/rustdoc/g' | tee cargo-doc-results.sarif | sarif-fmt
|
||||
continue-on-error: true
|
||||
|
||||
- name: Upload analysis results to GitHub
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: cargo-doc-results.sarif
|
||||
wait-for-processing: true
|
|
@ -34,6 +34,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
|
@ -291,15 +292,6 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console_error_panic_hook"
|
||||
version = "0.1.7"
|
||||
|
@ -549,14 +541,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "5.3.1"
|
||||
version = "2.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"parking",
|
||||
"pin-project-lite",
|
||||
]
|
||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
|
@ -786,9 +773,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hashlink"
|
||||
version = "0.9.1"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
|
||||
checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
|
||||
dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
]
|
||||
|
@ -819,9 +806,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
|
@ -1151,9 +1141,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
|||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.28.0"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f"
|
||||
checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
|
@ -1237,14 +1227,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.0.1"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1356,6 +1345,16 @@ dependencies = [
|
|||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.1"
|
||||
|
@ -1377,12 +1376,6 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
|
@ -1604,9 +1597,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pubserve"
|
||||
version = "1.1.0"
|
||||
version = "1.1.0-alpha.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a2cf5f495fc9c61de736666ebcbc473fe28a2a1aaf7e5619e5925b13c0275a4"
|
||||
checksum = "b1781b2a51798c98a381e839e61bc5ce6426bd89bb9c3f9142de2086a80591cd"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
]
|
||||
|
@ -1979,9 +1972,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_with"
|
||||
version = "3.9.0"
|
||||
version = "3.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857"
|
||||
checksum = "e73139bc5ec2d45e6c5fd85be5a46949c1c39a4c18e56915f5eb4c12f975e377"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
|
@ -1997,9 +1990,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_with_macros"
|
||||
version = "3.9.0"
|
||||
version = "3.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350"
|
||||
checksum = "b80d3d6b56b64335c0180e5ffde23b3c5e08c14c585b51a15bd0e95393f46703"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
|
@ -2075,9 +2068,6 @@ name = "smallvec"
|
|||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
|
@ -2126,9 +2116,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sqlx"
|
||||
version = "0.8.0"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27144619c6e5802f1380337a209d2ac1c431002dd74c6e60aebff3c506dc4f0c"
|
||||
checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa"
|
||||
dependencies = [
|
||||
"sqlx-core",
|
||||
"sqlx-macros",
|
||||
|
@ -2139,10 +2129,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sqlx-core"
|
||||
version = "0.8.0"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a999083c1af5b5d6c071d34a708a19ba3e02106ad82ef7bbd69f5e48266b613b"
|
||||
checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"atoi",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
|
@ -2156,7 +2147,6 @@ dependencies = [
|
|||
"futures-intrusive",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"hashbrown 0.14.5",
|
||||
"hashlink",
|
||||
"hex",
|
||||
"indexmap 2.2.6",
|
||||
|
@ -2183,22 +2173,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sqlx-macros"
|
||||
version = "0.8.0"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a23217eb7d86c584b8cbe0337b9eacf12ab76fe7673c513141ec42565698bb88"
|
||||
checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"sqlx-core",
|
||||
"sqlx-macros-core",
|
||||
"syn 2.0.70",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-macros-core"
|
||||
version = "0.8.0"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a099220ae541c5db479c6424bdf1b200987934033c2584f79a0e1693601e776"
|
||||
checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8"
|
||||
dependencies = [
|
||||
"dotenvy",
|
||||
"either",
|
||||
|
@ -2214,7 +2204,7 @@ dependencies = [
|
|||
"sqlx-mysql",
|
||||
"sqlx-postgres",
|
||||
"sqlx-sqlite",
|
||||
"syn 2.0.70",
|
||||
"syn 1.0.109",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"url",
|
||||
|
@ -2222,12 +2212,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sqlx-mysql"
|
||||
version = "0.8.0"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5afe4c38a9b417b6a9a5eeffe7235d0a106716495536e7727d1c7f4b1ff3eba6"
|
||||
checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"base64 0.22.1",
|
||||
"base64 0.21.7",
|
||||
"bitflags 2.6.0",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
|
@ -2265,12 +2255,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sqlx-postgres"
|
||||
version = "0.8.0"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1dbb157e65f10dbe01f729339c06d239120221c9ad9fa0ba8408c4cc18ecf21"
|
||||
checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"base64 0.22.1",
|
||||
"base64 0.21.7",
|
||||
"bitflags 2.6.0",
|
||||
"byteorder",
|
||||
"chrono",
|
||||
|
@ -2305,9 +2295,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sqlx-sqlite"
|
||||
version = "0.8.0"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b2cdd83c008a622d94499c0006d8ee5f821f36c89b7d625c900e5dc30b5c5ee"
|
||||
checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"chrono",
|
||||
|
@ -2321,10 +2311,10 @@ dependencies = [
|
|||
"log",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"serde_urlencoded",
|
||||
"sqlx-core",
|
||||
"tracing",
|
||||
"url",
|
||||
"urlencoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2422,18 +2412,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.63"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.63"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2488,25 +2478,26 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.39.2"
|
||||
version = "1.38.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1"
|
||||
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.4.0"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2694,6 +2685,12 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
|
||||
|
||||
[[package]]
|
||||
name = "unicode_categories"
|
||||
version = "0.1.1"
|
||||
|
@ -2733,6 +2730,12 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urlencoding"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
|
||||
|
||||
[[package]]
|
||||
name = "utf-8"
|
||||
version = "0.7.6"
|
||||
|
|
47
Cargo.toml
47
Cargo.toml
|
@ -8,7 +8,7 @@ repository = "https://github.com/polyphony-chat/chorus"
|
|||
readme = "README.md"
|
||||
keywords = ["spacebar", "discord", "polyphony"]
|
||||
website = ["https://discord.com/invite/m3FpcapGDD"]
|
||||
rust-version = "1.70.0"
|
||||
rust-version = "1.67.1"
|
||||
|
||||
|
||||
[features]
|
||||
|
@ -22,33 +22,33 @@ voice_udp = ["dep:discortp", "dep:crypto_secretbox"]
|
|||
voice_gateway = []
|
||||
|
||||
[dependencies]
|
||||
tokio = { version = "1.38.1", features = ["macros", "sync"] }
|
||||
serde = { version = "1.0.204", features = ["derive", "rc"] }
|
||||
serde_json = { version = "1.0.120", features = ["raw_value"] }
|
||||
serde-aux = "4.5.0"
|
||||
serde_with = "3.9.0"
|
||||
serde_repr = "0.1.19"
|
||||
tokio = { version = "1.35.1", features = ["macros", "sync"] }
|
||||
serde = { version = "1.0.195", features = ["derive", "rc"] }
|
||||
serde_json = { version = "1.0.111", features = ["raw_value"] }
|
||||
serde-aux = "4.3.1"
|
||||
serde_with = "3.4.0"
|
||||
serde_repr = "0.1.18"
|
||||
reqwest = { features = [
|
||||
"multipart",
|
||||
"json",
|
||||
"rustls-tls-webpki-roots",
|
||||
], version = "=0.11.26", default-features = false }
|
||||
url = "2.5.2"
|
||||
chrono = { version = "0.4.38", features = ["serde"] }
|
||||
regex = "1.10.5"
|
||||
url = "2.5.0"
|
||||
chrono = { version = "0.4.31", features = ["serde"] }
|
||||
regex = "1.10.2"
|
||||
custom_error = "1.9.2"
|
||||
futures-util = "0.3.30"
|
||||
http = "0.2.12"
|
||||
base64 = "0.21.7"
|
||||
bitflags = { version = "2.6.0", features = ["serde"] }
|
||||
lazy_static = "1.5.0"
|
||||
bitflags = { version = "2.4.1", features = ["serde"] }
|
||||
lazy_static = "1.4.0"
|
||||
poem = { version = "3.0.1", features = ["multipart"], optional = true }
|
||||
thiserror = "1.0.63"
|
||||
thiserror = "1.0.56"
|
||||
jsonwebtoken = "8.3.0"
|
||||
log = "0.4.22"
|
||||
async-trait = "0.1.81"
|
||||
log = "0.4.20"
|
||||
async-trait = "0.1.77"
|
||||
chorus-macros = { path = "./chorus-macros", version = "0" } # Note: version here is used when releasing. This will use the latest release. Make sure to republish the crate when code in macros is changed!
|
||||
sqlx = { version = "0.8.0", features = [
|
||||
sqlx = { version = "0.7.3", features = [
|
||||
"mysql",
|
||||
"sqlite",
|
||||
"json",
|
||||
|
@ -66,27 +66,24 @@ crypto_secretbox = { version = "0.1.1", optional = true }
|
|||
rand = "0.8.5"
|
||||
flate2 = { version = "1.0.30", optional = true }
|
||||
webpki-roots = "0.26.3"
|
||||
pubserve = { version = "1.1.0", features = ["async", "send"] }
|
||||
pubserve = { version = "1.1.0-alpha.1", features = ["async", "send"] }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
rustls = "0.21.12"
|
||||
rustls = "0.21.10"
|
||||
tokio-tungstenite = { version = "0.20.1", features = [
|
||||
"rustls-tls-webpki-roots",
|
||||
] }
|
||||
hostname = "0.3.1"
|
||||
getrandom = { version = "0.2.15" }
|
||||
getrandom = { version = "0.2.12" }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
getrandom = { version = "0.2.15", features = ["js"] }
|
||||
getrandom = { version = "0.2.12", features = ["js"] }
|
||||
ws_stream_wasm = "0.7.4"
|
||||
wasm-bindgen-futures = "0.4.42"
|
||||
wasm-bindgen-futures = "0.4.39"
|
||||
wasmtimer = "0.2.0"
|
||||
|
||||
[dev-dependencies]
|
||||
lazy_static = "1.5.0"
|
||||
lazy_static = "1.4.0"
|
||||
wasm-bindgen-test = "0.3.42"
|
||||
wasm-bindgen = "0.2.92"
|
||||
simple_logger = { version = "5.0.0", default-features = false }
|
||||
|
||||
[lints.rust]
|
||||
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(tarpaulin_include)'] }
|
||||
|
|
|
@ -119,11 +119,11 @@ We recommend checking out the "examples" directory, as well as the documentation
|
|||
|
||||
## MSRV (Minimum Supported Rust Version)
|
||||
|
||||
Rust **1.70.0**. This number might change at any point while Chorus is not yet at version 1.0.0.
|
||||
Rust **1.67.1**. This number might change at any point while Chorus is not yet at version 1.0.0.
|
||||
|
||||
## Development Setup
|
||||
|
||||
Make sure that you have at least Rust 1.70.0 installed. You can check your Rust version by running `cargo --version`
|
||||
Make sure that you have at least Rust 1.67.1 installed. You can check your Rust version by running `cargo --version`
|
||||
in your terminal. To compile for `wasm32-unknown-unknown`, you need to install the `wasm32-unknown-unknown` target.
|
||||
You can do this by running `rustup target add wasm32-unknown-unknown`.
|
||||
|
||||
|
|
|
@ -156,6 +156,7 @@ pub fn composite_derive(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[proc_macro_derive(SqlxBitFlags)]
|
||||
pub fn sqlx_bitflag_derive(input: TokenStream) -> TokenStream {
|
||||
let ast: syn::DeriveInput = syn::parse(input).unwrap();
|
||||
|
@ -164,46 +165,25 @@ pub fn sqlx_bitflag_derive(input: TokenStream) -> TokenStream {
|
|||
|
||||
quote!{
|
||||
#[cfg(feature = "sqlx")]
|
||||
impl sqlx::Type<sqlx::Any> for #name {
|
||||
fn type_info() -> sqlx::any::AnyTypeInfo {
|
||||
<Vec<u8> as sqlx::Type<sqlx::Any>>::type_info()
|
||||
impl sqlx::Type<sqlx::MySql> for #name {
|
||||
fn type_info() -> sqlx::mysql::MySqlTypeInfo {
|
||||
u64::type_info()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "sqlx")]
|
||||
impl<'q> sqlx::Encode<'q, sqlx::Any> for #name {
|
||||
fn encode_by_ref(&self, buf: &mut <sqlx::Any as sqlx::Database>::ArgumentBuffer<'q>) -> Result<sqlx::encode::IsNull, sqlx::error::BoxDynError> {
|
||||
<Vec<u8> as sqlx::Encode<sqlx::Any>>::encode_by_ref(&self.bits().to_be_bytes().into(), buf)
|
||||
impl<'q> sqlx::Encode<'q, sqlx::MySql> for #name {
|
||||
fn encode_by_ref(&self, buf: &mut <sqlx::MySql as sqlx::database::HasArguments<'q>>::ArgumentBuffer) -> sqlx::encode::IsNull {
|
||||
u64::encode_by_ref(&self.bits(), buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "sqlx")]
|
||||
impl<'q> sqlx::Decode<'q, sqlx::Any> for #name {
|
||||
fn decode(value: <sqlx::Any as sqlx::Database>::ValueRef<'q>) -> Result<Self, sqlx::error::BoxDynError> {
|
||||
let vec = <Vec<u8> as sqlx::Decode<sqlx::Any>>::decode(value)?;
|
||||
Ok(Self::from_bits(vec_u8_to_u64(vec)).unwrap())
|
||||
impl<'q> sqlx::Decode<'q, sqlx::MySql> for #name {
|
||||
fn decode(value: <sqlx::MySql as sqlx::database::HasValueRef<'q>>::ValueRef) -> Result<Self, sqlx::error::BoxDynError> {
|
||||
u64::decode(value).map(|d| #name::from_bits(d).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a [Vec<u8>] to an unsigned, 64 bit integer. The [u64] is created using [u64::from_be_bytes].
|
||||
///
|
||||
/// Empty vectors will result in an output of `0_u64`. Only the first 8 values from the vector are
|
||||
/// being processed. Any additional values will be skipped.
|
||||
///
|
||||
/// Vectors holding less than 8 values will be treated as a vector holding 8 values, where the
|
||||
/// missing values are padded with `0_u8`.
|
||||
fn vec_u8_to_u64(vec: Vec<u8>) -> u64 {
|
||||
let mut buf: [u8; 8] = [0; 8];
|
||||
let mut position = 0;
|
||||
for read in vec.iter() {
|
||||
buf[position] = *read;
|
||||
position += 1;
|
||||
if position > 7 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
u64::from_be_bytes(buf)
|
||||
}
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
|
|
@ -2,10 +2,7 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use reqwest::Client;
|
||||
use serde_json::to_string;
|
||||
|
@ -15,11 +12,10 @@ use crate::{
|
|||
instance::{ChorusUser, Instance},
|
||||
ratelimiter::ChorusRequest,
|
||||
types::{
|
||||
CreateUserHarvestSchema, DeleteDisableUserSchema, GetPomeloEligibilityReturn,
|
||||
GetPomeloSuggestionsReturn, GetRecentMentionsSchema, GetUserProfileSchema, Harvest,
|
||||
HarvestBackendType, LimitType, ModifyUserNoteSchema, PublicUser, Snowflake, User,
|
||||
UserModifyProfileSchema, UserModifySchema, UserNote, UserProfile, UserProfileMetadata,
|
||||
UserSettings, VerifyUserEmailChangeResponse, VerifyUserEmailChangeSchema,
|
||||
DeleteDisableUserSchema, GetPomeloEligibilityReturn, GetPomeloSuggestionsReturn,
|
||||
GetUserProfileSchema, LimitType, PublicUser, Snowflake, User, UserModifyProfileSchema,
|
||||
UserModifySchema, UserProfile, UserProfileMetadata, UserSettings,
|
||||
VerifyUserEmailChangeResponse, VerifyUserEmailChangeSchema,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -227,12 +223,11 @@ impl ChorusUser {
|
|||
|
||||
/// Verifies a code sent to change the current user's email.
|
||||
///
|
||||
/// Should be the follow-up to [Self::initiate_email_change]
|
||||
///
|
||||
/// This endpoint returns a token which can be used with [Self::modify]
|
||||
/// to set a new email address (email_token).
|
||||
///
|
||||
/// # Notes
|
||||
/// Should be the follow-up to [Self::initiate_email_change]
|
||||
///
|
||||
/// As of 2024/08/08, Spacebar does not yet implement this endpoint.
|
||||
// FIXME: Does this mean PUT users/@me/email is different?
|
||||
///
|
||||
|
@ -260,7 +255,8 @@ impl ChorusUser {
|
|||
|
||||
/// Returns a suggested unique username based on the current user's username.
|
||||
///
|
||||
/// # Notes:
|
||||
/// Note:
|
||||
///
|
||||
/// "This endpoint is used during the pomelo migration flow.
|
||||
///
|
||||
/// The user must be in the rollout to use this endpoint."
|
||||
|
@ -270,7 +266,6 @@ impl ChorusUser {
|
|||
///
|
||||
/// As of 2024/08/08, Spacebar does not yet implement this endpoint.
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#get-pomelo-suggestions>
|
||||
pub async fn get_pomelo_suggestions(&mut self) -> ChorusResult<String> {
|
||||
let request = Client::new()
|
||||
|
@ -294,10 +289,8 @@ impl ChorusUser {
|
|||
///
|
||||
/// Returns whether the username is not taken yet.
|
||||
///
|
||||
/// # Notes
|
||||
/// As of 2024/08/08, Spacebar does not yet implement this endpoint.
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#get-pomelo-eligibility>
|
||||
pub async fn get_pomelo_eligibility(&mut self, username: &String) -> ChorusResult<bool> {
|
||||
let request = Client::new()
|
||||
|
@ -327,7 +320,8 @@ impl ChorusUser {
|
|||
/// Updates [Self::object] to an updated representation returned by the server.
|
||||
// FIXME: Is this appropriate behaviour?
|
||||
///
|
||||
/// # Notes
|
||||
/// Note:
|
||||
///
|
||||
/// "This endpoint is used during the pomelo migration flow.
|
||||
///
|
||||
/// The user must be in the rollout to use this endpoint."
|
||||
|
@ -337,7 +331,6 @@ impl ChorusUser {
|
|||
//
|
||||
/// As of 2024/08/08, Spacebar does not yet implement this endpoint.
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#create-pomelo-migration>
|
||||
pub async fn create_pomelo_migration(&mut self, username: &String) -> ChorusResult<()> {
|
||||
let request = Client::new()
|
||||
|
@ -365,211 +358,6 @@ impl ChorusUser {
|
|||
|
||||
ChorusResult::Err(result.err().unwrap())
|
||||
}
|
||||
|
||||
/// Fetches a list of [Message](crate::types::Message)s that the current user has been
|
||||
/// mentioned in during the last 7 days.
|
||||
///
|
||||
/// # Notes
|
||||
/// As of 2024/08/09, Spacebar does not yet implement this endpoint.
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#get-recent-mentions>
|
||||
pub async fn get_recent_mentions(
|
||||
&mut self,
|
||||
query_parameters: GetRecentMentionsSchema,
|
||||
) -> ChorusResult<Vec<crate::types::Message>> {
|
||||
let request = Client::new()
|
||||
.get(format!(
|
||||
"{}/users/@me/mentions",
|
||||
self.belongs_to.read().unwrap().urls.api
|
||||
))
|
||||
.header("Authorization", self.token())
|
||||
.query(&query_parameters);
|
||||
|
||||
let chorus_request = ChorusRequest {
|
||||
request,
|
||||
limit_type: LimitType::default(),
|
||||
};
|
||||
|
||||
chorus_request
|
||||
.deserialize_response::<Vec<crate::types::Message>>(self)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Acknowledges a message the current user has been mentioned in.
|
||||
///
|
||||
/// Fires a `RecentMentionDelete` gateway event. (Note: yet to be implemented in chorus, see [#545](https://github.com/polyphony-chat/chorus/issues/545))
|
||||
///
|
||||
/// # Notes
|
||||
/// As of 2024/08/09, Spacebar does not yet implement this endpoint.
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#delete-recent-mention>
|
||||
pub async fn delete_recent_mention(&mut self, message_id: Snowflake) -> ChorusResult<()> {
|
||||
let request = Client::new()
|
||||
.delete(format!(
|
||||
"{}/users/@me/mentions/{}",
|
||||
self.belongs_to.read().unwrap().urls.api,
|
||||
message_id
|
||||
))
|
||||
.header("Authorization", self.token());
|
||||
|
||||
let chorus_request = ChorusRequest {
|
||||
request,
|
||||
limit_type: LimitType::default(),
|
||||
};
|
||||
|
||||
chorus_request.handle_request_as_result(self).await
|
||||
}
|
||||
|
||||
/// If it exists, returns the most recent [Harvest] (personal data harvest request).
|
||||
///
|
||||
/// To create a new [Harvest], see [Self::create_harvest].
|
||||
///
|
||||
/// # Notes
|
||||
/// As of 2024/08/09, Spacebar does not yet implement this endpoint. (Or data harvesting)
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#get-user-harvest>
|
||||
pub async fn get_harvest(&mut self) -> ChorusResult<Option<Harvest>> {
|
||||
let request = Client::new()
|
||||
.get(format!(
|
||||
"{}/users/@me/harvest",
|
||||
self.belongs_to.read().unwrap().urls.api,
|
||||
))
|
||||
.header("Authorization", self.token());
|
||||
|
||||
let chorus_request = ChorusRequest {
|
||||
request,
|
||||
limit_type: LimitType::default(),
|
||||
};
|
||||
|
||||
// Manual handling, because a 204 with no harvest is a success state
|
||||
// TODO: Maybe make this a method on ChorusRequest if we need it a lot
|
||||
let response = chorus_request.send_request(self).await?;
|
||||
log::trace!("Got response: {:?}", response);
|
||||
|
||||
if response.status() == http::StatusCode::NO_CONTENT {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let response_text = match response.text().await {
|
||||
Ok(string) => string,
|
||||
Err(e) => {
|
||||
return Err(ChorusError::InvalidResponse {
|
||||
error: format!(
|
||||
"Error while trying to process the HTTP response into a String: {}",
|
||||
e
|
||||
),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let object = match serde_json::from_str::<Harvest>(&response_text) {
|
||||
Ok(object) => object,
|
||||
Err(e) => {
|
||||
return Err(ChorusError::InvalidResponse {
|
||||
error: format!(
|
||||
"Error while trying to deserialize the JSON response into requested type T: {}. JSON Response: {}",
|
||||
e, response_text
|
||||
),
|
||||
})
|
||||
}
|
||||
};
|
||||
Ok(Some(object))
|
||||
}
|
||||
|
||||
/// Creates a personal data harvest request ([Harvest]) for the current user.
|
||||
///
|
||||
/// # Notes
|
||||
/// To fetch the latest existing harvest, see [Self::get_harvest].
|
||||
///
|
||||
/// Invalid options in the backends array are ignored.
|
||||
///
|
||||
/// If the array is empty (after ignoring), it requests all [HarvestBackendType]s.
|
||||
///
|
||||
/// As of 2024/08/09, Spacebar does not yet implement this endpoint. (Or data harvesting)
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#create-user-harvest>
|
||||
pub async fn create_harvest(
|
||||
&mut self,
|
||||
backends: Vec<HarvestBackendType>,
|
||||
) -> ChorusResult<Harvest> {
|
||||
let schema = if backends.is_empty() {
|
||||
CreateUserHarvestSchema { backends: None }
|
||||
} else {
|
||||
CreateUserHarvestSchema {
|
||||
backends: Some(backends),
|
||||
}
|
||||
};
|
||||
|
||||
let request = Client::new()
|
||||
.post(format!(
|
||||
"{}/users/@me/harvest",
|
||||
self.belongs_to.read().unwrap().urls.api,
|
||||
))
|
||||
.header("Authorization", self.token())
|
||||
.json(&schema);
|
||||
|
||||
let chorus_request = ChorusRequest {
|
||||
request,
|
||||
limit_type: LimitType::default(),
|
||||
};
|
||||
|
||||
chorus_request.deserialize_response(self).await
|
||||
}
|
||||
|
||||
/// Returns a mapping of user IDs ([Snowflake]s) to notes ([String]s) for the current user.
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#get-user-notes>
|
||||
pub async fn get_user_notes(&mut self) -> ChorusResult<HashMap<Snowflake, String>> {
|
||||
let request = Client::new()
|
||||
.get(format!(
|
||||
"{}/users/@me/notes",
|
||||
self.belongs_to.read().unwrap().urls.api,
|
||||
))
|
||||
.header("Authorization", self.token());
|
||||
|
||||
let chorus_request = ChorusRequest {
|
||||
request,
|
||||
limit_type: LimitType::default(),
|
||||
};
|
||||
|
||||
chorus_request.deserialize_response(self).await
|
||||
}
|
||||
|
||||
/// Fetches the note ([UserNote]) for the given user.
|
||||
///
|
||||
/// If the current user has no note for the target, this endpoint
|
||||
/// returns `Err(NotFound { error: "{\"message\": \"Unknown User\", \"code\": 10013}" })`
|
||||
///
|
||||
/// # Notes
|
||||
/// This function is a wrapper around [`User::get_note`].
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#get-user-note>
|
||||
pub async fn get_user_note(&mut self, target_user_id: Snowflake) -> ChorusResult<UserNote> {
|
||||
User::get_note(self, target_user_id).await
|
||||
}
|
||||
|
||||
/// Sets the note for the given user.
|
||||
///
|
||||
/// Fires a `UserNoteUpdate` gateway event. (Note: yet to be implemented in chorus, see [#546](https://github.com/polyphony-chat/chorus/issues/546))
|
||||
///
|
||||
/// # Notes
|
||||
/// This function is a wrapper around [`User::set_note`].
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#modify-user-note>
|
||||
pub async fn set_user_note(
|
||||
&mut self,
|
||||
target_user_id: Snowflake,
|
||||
note: Option<String>,
|
||||
) -> ChorusResult<()> {
|
||||
User::set_note(self, target_user_id, note).await
|
||||
}
|
||||
}
|
||||
|
||||
impl User {
|
||||
|
@ -724,61 +512,4 @@ impl User {
|
|||
.deserialize_response::<UserProfileMetadata>(user)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Fetches the note ([UserNote]) for the given user.
|
||||
///
|
||||
/// If the current user has no note for the target, this endpoint
|
||||
/// returns `Err(NotFound { error: "{\"message\": \"Unknown User\", \"code\": 10013}" })`
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#get-user-note>
|
||||
pub async fn get_note(
|
||||
user: &mut ChorusUser,
|
||||
target_user_id: Snowflake,
|
||||
) -> ChorusResult<UserNote> {
|
||||
let request = Client::new()
|
||||
.get(format!(
|
||||
"{}/users/@me/notes/{}",
|
||||
user.belongs_to.read().unwrap().urls.api,
|
||||
target_user_id
|
||||
))
|
||||
.header("Authorization", user.token());
|
||||
|
||||
let chorus_request = ChorusRequest {
|
||||
request,
|
||||
limit_type: LimitType::default(),
|
||||
};
|
||||
|
||||
chorus_request.deserialize_response(user).await
|
||||
}
|
||||
|
||||
/// Sets the note for the given user.
|
||||
///
|
||||
/// Fires a `UserNoteUpdate` gateway event. (Note: yet to be implemented in chorus, see [#546](https://github.com/polyphony-chat/chorus/issues/546))
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#modify-user-note>
|
||||
pub async fn set_note(
|
||||
user: &mut ChorusUser,
|
||||
target_user_id: Snowflake,
|
||||
note: Option<String>,
|
||||
) -> ChorusResult<()> {
|
||||
let schema = ModifyUserNoteSchema { note };
|
||||
|
||||
let request = Client::new()
|
||||
.put(format!(
|
||||
"{}/users/@me/notes/{}",
|
||||
user.belongs_to.read().unwrap().urls.api,
|
||||
target_user_id
|
||||
))
|
||||
.header("Authorization", user.token())
|
||||
.json(&schema);
|
||||
|
||||
let chorus_request = ChorusRequest {
|
||||
request,
|
||||
limit_type: LimitType::default(),
|
||||
};
|
||||
|
||||
chorus_request.handle_request_as_result(user).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,14 +69,12 @@ pub struct Message {
|
|||
pub reaction_remove: Publisher<types::MessageReactionRemove>,
|
||||
pub reaction_remove_all: Publisher<types::MessageReactionRemoveAll>,
|
||||
pub reaction_remove_emoji: Publisher<types::MessageReactionRemoveEmoji>,
|
||||
pub recent_mention_delete: Publisher<types::RecentMentionDelete>,
|
||||
pub ack: Publisher<types::MessageACK>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct User {
|
||||
pub update: Publisher<types::UserUpdate>,
|
||||
pub note_update: Publisher<types::UserNoteUpdate>,
|
||||
pub guild_settings_update: Publisher<types::UserGuildSettingsUpdate>,
|
||||
pub presence_update: Publisher<types::PresenceUpdate>,
|
||||
pub typing_start: Publisher<types::TypingStartEvent>,
|
||||
|
|
|
@ -404,7 +404,6 @@ impl Gateway {
|
|||
"MESSAGE_REACTION_REMOVE" => message.reaction_remove, // TODO
|
||||
"MESSAGE_REACTION_REMOVE_ALL" => message.reaction_remove_all, // TODO
|
||||
"MESSAGE_REACTION_REMOVE_EMOJI" => message.reaction_remove_emoji, // TODO
|
||||
"RECENT_MENTION_DELETE" => message.recent_mention_delete,
|
||||
"MESSAGE_ACK" => message.ack,
|
||||
"PRESENCE_UPDATE" => user.presence_update, // TODO
|
||||
"RELATIONSHIP_ADD" => relationship.add,
|
||||
|
@ -414,7 +413,6 @@ impl Gateway {
|
|||
"STAGE_INSTANCE_DELETE" => stage_instance.delete,
|
||||
"TYPING_START" => user.typing_start,
|
||||
"USER_UPDATE" => user.update, // TODO
|
||||
"USER_NOTE_UPDATE" => user.note_update,
|
||||
"USER_GUILD_SETTINGS_UPDATE" => user.guild_settings_update,
|
||||
"VOICE_STATE_UPDATE" => voice.state_update, // TODO
|
||||
"VOICE_SERVER_UPDATE" => voice.server_update,
|
||||
|
|
|
@ -162,11 +162,9 @@ impl Display for GuildFeaturesList {
|
|||
}
|
||||
|
||||
#[cfg(feature = "sqlx")]
|
||||
impl<'r> sqlx::Decode<'r, sqlx::Any> for GuildFeaturesList {
|
||||
fn decode(
|
||||
value: <sqlx::Any as sqlx::Database>::ValueRef<'r>,
|
||||
) -> Result<Self, sqlx::error::BoxDynError> {
|
||||
let v = <String as sqlx::Decode<sqlx::Any>>::decode(value)?;
|
||||
impl<'r> sqlx::Decode<'r, sqlx::MySql> for GuildFeaturesList {
|
||||
fn decode(value: <sqlx::MySql as sqlx::database::HasValueRef<'r>>::ValueRef) -> Result<Self, sqlx::error::BoxDynError> {
|
||||
let v = <String as sqlx::Decode<sqlx::MySql>>::decode(value)?;
|
||||
Ok(Self(
|
||||
v.split(',')
|
||||
.filter(|f| !f.is_empty())
|
||||
|
@ -177,13 +175,10 @@ impl<'r> sqlx::Decode<'r, sqlx::Any> for GuildFeaturesList {
|
|||
}
|
||||
|
||||
#[cfg(feature = "sqlx")]
|
||||
impl<'q> sqlx::Encode<'q, sqlx::Any> for GuildFeaturesList {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
buf: &mut <sqlx::Any as sqlx::Database>::ArgumentBuffer<'q>,
|
||||
) -> Result<sqlx::encode::IsNull, Box<dyn std::error::Error + Send + Sync>> {
|
||||
impl<'q> sqlx::Encode<'q, sqlx::MySql> for GuildFeaturesList {
|
||||
fn encode_by_ref(&self, buf: &mut <sqlx::MySql as sqlx::database::HasArguments<'q>>::ArgumentBuffer) -> sqlx::encode::IsNull {
|
||||
if self.is_empty() {
|
||||
return Ok(sqlx::encode::IsNull::Yes);
|
||||
return sqlx::encode::IsNull::Yes;
|
||||
}
|
||||
let features = self
|
||||
.iter()
|
||||
|
@ -191,18 +186,18 @@ impl<'q> sqlx::Encode<'q, sqlx::Any> for GuildFeaturesList {
|
|||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
|
||||
<String as sqlx::Encode<sqlx::Any>>::encode_by_ref(&features, buf)
|
||||
<String as sqlx::Encode<sqlx::MySql>>::encode_by_ref(&features, buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "sqlx")]
|
||||
impl sqlx::Type<sqlx::Any> for GuildFeaturesList {
|
||||
fn type_info() -> sqlx::any::AnyTypeInfo {
|
||||
<String as sqlx::Type<sqlx::Any>>::type_info()
|
||||
impl sqlx::Type<sqlx::MySql> for GuildFeaturesList {
|
||||
fn type_info() -> sqlx::mysql::MySqlTypeInfo {
|
||||
<String as sqlx::Type<sqlx::MySql>>::type_info()
|
||||
}
|
||||
|
||||
fn compatible(ty: &sqlx::any::AnyTypeInfo) -> bool {
|
||||
<String as sqlx::Type<sqlx::Any>>::compatible(ty)
|
||||
fn compatible(ty: &sqlx::mysql::MySqlTypeInfo) -> bool {
|
||||
<String as sqlx::Type<sqlx::MySql>>::compatible(ty)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -102,10 +102,7 @@ fn compare_install_params(
|
|||
b: &Option<sqlx::types::Json<InstallParams>>,
|
||||
) -> bool {
|
||||
match (a, b) {
|
||||
(Some(a), Some(b)) => match (a.encode_to_string(), b.encode_to_string()) {
|
||||
(Ok(a), Ok(b)) => a == b,
|
||||
_ => false,
|
||||
},
|
||||
(Some(a), Some(b)) => a.encode_to_string() == b.encode_to_string(),
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
}
|
||||
|
|
|
@ -51,10 +51,7 @@ fn compare_options(
|
|||
b: &Option<sqlx::types::Json<AuditEntryInfo>>,
|
||||
) -> bool {
|
||||
match (a, b) {
|
||||
(Some(a), Some(b)) => match (a.encode_to_string(), b.encode_to_string()) {
|
||||
(Ok(a), Ok(b)) => a == b,
|
||||
_ => false,
|
||||
},
|
||||
(Some(a), Some(b)) => a.encode_to_string() == b.encode_to_string(),
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
}
|
||||
|
@ -72,10 +69,7 @@ fn compare_changes(
|
|||
a: &sqlx::types::Json<Option<Vec<Shared<AuditLogChange>>>>,
|
||||
b: &sqlx::types::Json<Option<Vec<Shared<AuditLogChange>>>>,
|
||||
) -> bool {
|
||||
match (a.encode_to_string(), b.encode_to_string()) {
|
||||
(Ok(a), Ok(b)) => a == b,
|
||||
_ => false,
|
||||
}
|
||||
a.encode_to_string() == b.encode_to_string()
|
||||
}
|
||||
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
|
|
|
@ -156,10 +156,7 @@ fn compare_permission_overwrites(
|
|||
b: &Option<Json<Vec<PermissionOverwrite>>>,
|
||||
) -> bool {
|
||||
match (a, b) {
|
||||
(Some(a), Some(b)) => match (a.encode_to_string(), b.encode_to_string()) {
|
||||
(Ok(a), Ok(b)) => a == b,
|
||||
_ => false,
|
||||
},
|
||||
(Some(a), Some(b)) => a.encode_to_string() == b.encode_to_string(),
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
}
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||
|
||||
use crate::types::Snowflake;
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
use crate::gateway::Updateable;
|
||||
|
||||
// FIXME: Should this type be Composite?
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
|
||||
/// A user's data harvest.
|
||||
///
|
||||
/// # Reference
|
||||
///
|
||||
/// See <https://docs.discord.sex/resources/user#harvest-object>
|
||||
pub struct Harvest {
|
||||
pub harvest_id: Snowflake,
|
||||
/// The id of the user being harvested
|
||||
pub user_id: Snowflake,
|
||||
pub status: HarvestStatus,
|
||||
/// The time the harvest was created
|
||||
pub created_at: DateTime<Utc>,
|
||||
/// The time the harvest was last polled
|
||||
pub polled_at: Option<DateTime<Utc>>,
|
||||
/// The time the harvest was completed
|
||||
pub completed_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
impl Updateable for Harvest {
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
fn id(&self) -> Snowflake {
|
||||
self.harvest_id
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Serialize_repr,
|
||||
Deserialize_repr,
|
||||
Debug,
|
||||
Default,
|
||||
Clone,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Hash,
|
||||
Copy,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
)]
|
||||
#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
|
||||
#[repr(u8)]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
/// Current status of a [Harvest]
|
||||
///
|
||||
/// See <https://docs.discord.sex/resources/user#harvest-status> and <https://docs.discord.sex/resources/user#harvest-object>
|
||||
pub enum HarvestStatus {
|
||||
/// The harvest is queued and has not been started
|
||||
Queued = 0,
|
||||
/// The harvest is currently running / being processed
|
||||
Running = 1,
|
||||
/// The harvest has failed
|
||||
Failed = 2,
|
||||
/// The harvest has been completed successfully
|
||||
Completed = 3,
|
||||
#[default]
|
||||
Unknown = 4,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash, Copy, PartialOrd, Ord)]
|
||||
#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
|
||||
/// A type of backend / service a harvest can be requested for.
|
||||
///
|
||||
/// See <https://docs.discord.sex/resources/user#harvest-backend-type> and <https://support.discord.com/hc/en-us/articles/360004957991-Your-Discord-Data-Package>
|
||||
pub enum HarvestBackendType {
|
||||
/// All account information;
|
||||
Accounts,
|
||||
/// Actions the user has taken;
|
||||
///
|
||||
/// Represented as "Your Activity" in the discord client
|
||||
Analytics,
|
||||
/// First-party embedded activity information;
|
||||
///
|
||||
/// e.g.: Chess in the Park, Checkers in the Park, Poker Night 2.0;
|
||||
/// Sketch Heads, Watch Together, Letter League, Land-io, Know What I Meme
|
||||
Activities,
|
||||
/// The user's messages
|
||||
Messages,
|
||||
/// Official Discord programes;
|
||||
///
|
||||
/// e.g.: Partner, HypeSquad, Verified Server
|
||||
Programs,
|
||||
/// Guilds the user is a member of;
|
||||
Servers,
|
||||
}
|
|
@ -11,7 +11,6 @@ pub use config::*;
|
|||
pub use emoji::*;
|
||||
pub use guild::*;
|
||||
pub use guild_member::*;
|
||||
pub use harvest::*;
|
||||
pub use integration::*;
|
||||
pub use invite::*;
|
||||
pub use message::*;
|
||||
|
@ -53,7 +52,6 @@ mod config;
|
|||
mod emoji;
|
||||
mod guild;
|
||||
mod guild_member;
|
||||
mod harvest;
|
||||
mod integration;
|
||||
mod invite;
|
||||
mod message;
|
||||
|
|
|
@ -116,32 +116,32 @@ impl TryFrom<Vec<u8>> for ThemeColors {
|
|||
|
||||
#[cfg(feature = "sqlx")]
|
||||
// TODO: Add tests for Encode and Decode.
|
||||
impl<'q> sqlx::Encode<'q, sqlx::Any> for ThemeColors {
|
||||
impl<'q> sqlx::Encode<'q, sqlx::MySql> for ThemeColors {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
buf: &mut <sqlx::Any as sqlx::Database>::ArgumentBuffer<'q>,
|
||||
) -> Result<sqlx::encode::IsNull, Box<dyn std::error::Error + Send + Sync>> {
|
||||
buf: &mut <sqlx::MySql as sqlx::database::HasArguments<'q>>::ArgumentBuffer,
|
||||
) -> sqlx::encode::IsNull {
|
||||
let mut vec_u8 = Vec::new();
|
||||
vec_u8.extend_from_slice(&self.inner.0.to_be_bytes());
|
||||
vec_u8.extend_from_slice(&self.inner.1.to_be_bytes());
|
||||
<Vec<u8> as sqlx::Encode<sqlx::Any>>::encode_by_ref(&vec_u8, buf)
|
||||
<Vec<u8> as sqlx::Encode<'q, sqlx::MySql>>::encode_by_ref(&vec_u8, buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "sqlx")]
|
||||
impl<'d> sqlx::Decode<'d, sqlx::Any> for ThemeColors {
|
||||
impl<'d> sqlx::Decode<'d, sqlx::MySql> for ThemeColors {
|
||||
fn decode(
|
||||
value: <sqlx::Any as sqlx::Database>::ValueRef<'d>,
|
||||
value: <sqlx::MySql as sqlx::database::HasValueRef<'d>>::ValueRef,
|
||||
) -> Result<Self, sqlx::error::BoxDynError> {
|
||||
let value_vec = <Vec<u8> as sqlx::Decode<'d, sqlx::Any>>::decode(value)?;
|
||||
let value_vec = <Vec<u8> as sqlx::Decode<'d, sqlx::MySql>>::decode(value)?;
|
||||
value_vec.try_into().map_err(|e: ChorusError| e.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "sqlx")]
|
||||
impl sqlx::Type<sqlx::Any> for ThemeColors {
|
||||
fn type_info() -> <sqlx::Any as sqlx::Database>::TypeInfo {
|
||||
<String as sqlx::Type<sqlx::Any>>::type_info()
|
||||
impl sqlx::Type<sqlx::MySql> for ThemeColors {
|
||||
fn type_info() -> <sqlx::MySql as sqlx::Database>::TypeInfo {
|
||||
<String as sqlx::Type<sqlx::MySql>>::type_info()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,8 +331,8 @@ pub struct ProfileBadge {
|
|||
/// A link (potentially used for href) for the badge.
|
||||
///
|
||||
/// e.g.:
|
||||
/// `"staff"` badge links to `"https://discord.com/company"`
|
||||
/// `"certified_moderator"` links to `"https://discord.com/safety"`
|
||||
/// "staff" badge links to "https://discord.com/company"
|
||||
/// "certified_moderator" links to "https://discord.com/safety"
|
||||
pub link: Option<String>,
|
||||
}
|
||||
|
||||
|
@ -765,22 +765,3 @@ pub struct MutualGuild {
|
|||
/// The user's nickname in the guild, if any
|
||||
pub nick: Option<String>,
|
||||
}
|
||||
|
||||
/// Structure which is returned by the [crate::instance::ChorusUser::get_user_note] endpoint.
|
||||
///
|
||||
/// Note that [crate::instance::ChorusUser::get_user_notes] endpoint
|
||||
/// returns a completely different structure;
|
||||
// Specualation: this is probably how Discord stores notes internally
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/resources/user#get-user-note>
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
|
||||
pub struct UserNote {
|
||||
/// Actual note contents; max 256 characters
|
||||
pub note: String,
|
||||
/// The ID of the user the note is on
|
||||
pub note_user_id: Snowflake,
|
||||
/// The ID of the user who created the note (always the current user)
|
||||
pub user_id: Snowflake,
|
||||
}
|
||||
|
|
|
@ -5,52 +5,14 @@
|
|||
use crate::types::events::WebSocketEvent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(
|
||||
Debug, Deserialize, Serialize, WebSocketEvent, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord,
|
||||
)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize, WebSocketEvent, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct GatewayHeartbeat {
|
||||
pub op: u8,
|
||||
pub d: Option<u64>,
|
||||
}
|
||||
|
||||
impl GatewayHeartbeat {
|
||||
/// The Heartbeat packet a server would receive from a new or fresh Gateway connection.
|
||||
pub fn first() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Quickly create a [GatewayHeartbeat] with the correct `opcode` and the given `sequence_number`.
|
||||
///
|
||||
/// Shorthand for
|
||||
/// ```rs
|
||||
/// Self {
|
||||
/// op: 1,
|
||||
/// d: Some(sequence_number)
|
||||
/// }
|
||||
/// ```
|
||||
pub fn new(sequence_number: u64) -> Self {
|
||||
Self {
|
||||
op: 1,
|
||||
d: Some(sequence_number),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::default::Default for GatewayHeartbeat {
|
||||
fn default() -> Self {
|
||||
Self { op: 1, d: None }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Debug, Deserialize, Serialize, Clone, WebSocketEvent, Copy, PartialEq, Eq, Hash, PartialOrd, Ord,
|
||||
)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, WebSocketEvent, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct GatewayHeartbeatAck {
|
||||
pub op: i32,
|
||||
}
|
||||
|
||||
impl std::default::Default for GatewayHeartbeatAck {
|
||||
fn default() -> Self {
|
||||
Self { op: 11 }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,15 +149,6 @@ pub struct MessageReactionRemoveEmoji {
|
|||
pub emoji: Emoji,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Default, Clone, Copy, WebSocketEvent)]
|
||||
/// Sent when a message that mentioned the current user in the last week is acknowledged and deleted.
|
||||
///
|
||||
/// # Reference
|
||||
/// See <https://docs.discord.sex/topics/gateway-events#recent-mention-delete>
|
||||
pub struct RecentMentionDelete {
|
||||
pub message_id: Snowflake,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone, WebSocketEvent)]
|
||||
/// Officially Undocumented
|
||||
///
|
||||
|
|
|
@ -16,18 +16,6 @@ pub struct UserUpdate {
|
|||
pub user: PublicUser,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq, WebSocketEvent)]
|
||||
/// See <https://docs.discord.sex/topics/gateway-events#user-note-update-structure>;
|
||||
///
|
||||
/// Sent when a note the current user has on another user is modified;
|
||||
///
|
||||
/// If the field "note" is an empty string, the note was removed.
|
||||
pub struct UserNoteUpdate {
|
||||
/// Id of the user the note is for
|
||||
pub id: Snowflake,
|
||||
pub note: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq, WebSocketEvent)]
|
||||
/// Undocumented;
|
||||
///
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::collections::HashMap;
|
|||
use chrono::NaiveDate;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::types::{HarvestBackendType, Snowflake, ThemeColors};
|
||||
use crate::types::{Snowflake, ThemeColors};
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
|
@ -218,7 +218,7 @@ pub struct GetUserProfileSchema {
|
|||
///
|
||||
/// See <https://docs.discord.sex/resources/user#get-pomelo-suggestions>
|
||||
pub(crate) struct GetPomeloSuggestionsReturn {
|
||||
pub username: String,
|
||||
pub username: String
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
|
@ -226,52 +226,5 @@ pub(crate) struct GetPomeloSuggestionsReturn {
|
|||
///
|
||||
/// See <https://docs.discord.sex/resources/user#get-pomelo-eligibility>
|
||||
pub(crate) struct GetPomeloEligibilityReturn {
|
||||
pub taken: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
|
||||
/// Query string parameters for the route GET /users/@me/mentions
|
||||
/// ([crate::instance::ChorusUser::get_recent_mentions])
|
||||
///
|
||||
/// See <https://docs.discord.sex/resources/user#get-recent-mentions>
|
||||
pub struct GetRecentMentionsSchema {
|
||||
/// Only fetch messages before this message id
|
||||
///
|
||||
/// Due to the nature of snowflakes, this can be easily used to fetch
|
||||
/// messages before a certain timestamp
|
||||
pub before: Option<Snowflake>,
|
||||
/// Max number of messages to return
|
||||
///
|
||||
/// Should be between 1 and 100.
|
||||
///
|
||||
/// If unset the limit is 25 messages
|
||||
pub limit: Option<u8>,
|
||||
/// Limit messages to a specific guild
|
||||
pub guild_id: Option<Snowflake>,
|
||||
/// Whether to include role mentions.
|
||||
///
|
||||
/// If unset the server assumes true
|
||||
pub roles: Option<bool>,
|
||||
/// Whether to include @everyone and @here mentions.
|
||||
///
|
||||
/// If unset the server assumes true
|
||||
pub everyone: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
/// Internal type for the [crate::instance::ChorusUser::create_harvest] endpoint.
|
||||
// (koza): imo it's nicer if the user can just pass a vec, instead of having to bother with
|
||||
// a specific type
|
||||
///
|
||||
/// See <https://docs.discord.sex/resources/user#create-user-harvest>
|
||||
pub(crate) struct CreateUserHarvestSchema {
|
||||
pub backends: Option<Vec<HarvestBackendType>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
/// Internal type for the [crate::instance::ChorusUser::set_user_note] endpoint.
|
||||
///
|
||||
/// See <https://docs.discord.sex/resources/user#modify-user-note>
|
||||
pub(crate) struct ModifyUserNoteSchema {
|
||||
pub note: Option<String>,
|
||||
pub taken: bool
|
||||
}
|
||||
|
|
|
@ -99,29 +99,23 @@ impl<'de> serde::Deserialize<'de> for Snowflake {
|
|||
}
|
||||
|
||||
#[cfg(feature = "sqlx")]
|
||||
impl sqlx::Type<sqlx::Any> for Snowflake {
|
||||
fn type_info() -> <sqlx::Any as sqlx::Database>::TypeInfo {
|
||||
<String as sqlx::Type<sqlx::Any>>::type_info()
|
||||
impl sqlx::Type<sqlx::MySql> for Snowflake {
|
||||
fn type_info() -> <sqlx::MySql as sqlx::Database>::TypeInfo {
|
||||
<String as sqlx::Type<sqlx::MySql>>::type_info()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "sqlx")]
|
||||
impl<'q> sqlx::Encode<'q, sqlx::Any> for Snowflake {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
buf: &mut <sqlx::Any as sqlx::Database>::ArgumentBuffer<'q>,
|
||||
) -> Result<sqlx::encode::IsNull, sqlx::error::BoxDynError> {
|
||||
<String as sqlx::Encode<'q, sqlx::Any>>::encode_by_ref(&self.0.to_string(), buf)
|
||||
impl<'q> sqlx::Encode<'q, sqlx::MySql> for Snowflake {
|
||||
fn encode_by_ref(&self, buf: &mut <sqlx::MySql as sqlx::database::HasArguments<'q>>::ArgumentBuffer) -> sqlx::encode::IsNull {
|
||||
<String as sqlx::Encode<'q, sqlx::MySql>>::encode_by_ref(&self.0.to_string(), buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "sqlx")]
|
||||
impl<'d> sqlx::Decode<'d, sqlx::Any> for Snowflake {
|
||||
fn decode(
|
||||
value: <sqlx::Any as sqlx::Database>::ValueRef<'d>,
|
||||
) -> Result<Self, sqlx::error::BoxDynError> {
|
||||
<String as sqlx::Decode<'d, sqlx::Any>>::decode(value)
|
||||
.map(|s| s.parse::<u64>().map(Snowflake).unwrap())
|
||||
impl<'d> sqlx::Decode<'d, sqlx::MySql> for Snowflake {
|
||||
fn decode(value: <sqlx::MySql as sqlx::database::HasValueRef<'d>>::ValueRef) -> Result<Self, sqlx::error::BoxDynError> {
|
||||
<String as sqlx::Decode<'d, sqlx::MySql>>::decode(value).map(|s| s.parse::<u64>().map(Snowflake).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue