Reorganizing and documenting

This commit is contained in:
Scott Lyons 2024-08-09 09:18:12 -07:00
commit 5fc286fb09
14 changed files with 2341 additions and 175 deletions

2
.gitignore vendored
View file

@ -1 +1,3 @@
/target /target
.idea/

247
Cargo.lock generated
View file

@ -112,16 +112,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]] [[package]]
name = "bytes" name = "byteorder"
version = "1.6.1" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.1.6" version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -341,6 +347,23 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-io"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-macro"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.30" version = "0.3.30"
@ -360,9 +383,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task", "futures-task",
"memchr",
"pin-project-lite", "pin-project-lite",
"pin-utils", "pin-utils",
"slab",
] ]
[[package]] [[package]]
@ -392,25 +420,6 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
[[package]]
name = "h2"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http 0.2.12",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.4.5" version = "0.4.5"
@ -422,7 +431,7 @@ dependencies = [
"fnv", "fnv",
"futures-core", "futures-core",
"futures-sink", "futures-sink",
"http 1.1.0", "http",
"indexmap", "indexmap",
"slab", "slab",
"tokio", "tokio",
@ -454,17 +463,6 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "http"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]] [[package]]
name = "http" name = "http"
version = "1.1.0" version = "1.1.0"
@ -476,17 +474,6 @@ dependencies = [
"itoa", "itoa",
] ]
[[package]]
name = "http-body"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes",
"http 0.2.12",
"pin-project-lite",
]
[[package]] [[package]]
name = "http-body" name = "http-body"
version = "1.0.1" version = "1.0.1"
@ -494,7 +481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [ dependencies = [
"bytes", "bytes",
"http 1.1.0", "http",
] ]
[[package]] [[package]]
@ -505,8 +492,8 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-util", "futures-util",
"http 1.1.0", "http",
"http-body 1.0.1", "http-body",
"pin-project-lite", "pin-project-lite",
] ]
@ -522,29 +509,6 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "0.14.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2 0.3.26",
"http 0.2.12",
"http-body 0.4.6",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "1.4.1" version = "1.4.1"
@ -554,10 +518,11 @@ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
"futures-util", "futures-util",
"h2 0.4.5", "h2",
"http 1.1.0", "http",
"http-body 1.0.1", "http-body",
"httparse", "httparse",
"httpdate",
"itoa", "itoa",
"pin-project-lite", "pin-project-lite",
"smallvec", "smallvec",
@ -572,8 +537,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155"
dependencies = [ dependencies = [
"futures-util", "futures-util",
"http 1.1.0", "http",
"hyper 1.4.1", "hyper",
"hyper-util", "hyper-util",
"rustls", "rustls",
"rustls-pki-types", "rustls-pki-types",
@ -590,7 +555,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
dependencies = [ dependencies = [
"bytes", "bytes",
"http-body-util", "http-body-util",
"hyper 1.4.1", "hyper",
"hyper-util", "hyper-util",
"native-tls", "native-tls",
"tokio", "tokio",
@ -600,16 +565,16 @@ dependencies = [
[[package]] [[package]]
name = "hyper-util" name = "hyper-util"
version = "0.1.6" version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
"futures-util", "futures-util",
"http 1.1.0", "http",
"http-body 1.0.1", "http-body",
"hyper 1.4.1", "hyper",
"pin-project-lite", "pin-project-lite",
"socket2", "socket2",
"tokio", "tokio",
@ -659,9 +624,9 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.2.6" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown",
@ -767,14 +732,19 @@ dependencies = [
[[package]] [[package]]
name = "mockito" name = "mockito"
version = "1.4.0" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2f6e023aa5bdf392aa06c78e4a4e6d498baab5138d0c993503350ebbc37bf1e" checksum = "09b34bd91b9e5c5b06338d392463e1318d683cf82ec3d3af4014609be6e2108d"
dependencies = [ dependencies = [
"assert-json-diff", "assert-json-diff",
"bytes",
"colored", "colored",
"futures-core", "futures-util",
"hyper 0.14.30", "http",
"http-body",
"http-body-util",
"hyper",
"hyper-util",
"log", "log",
"rand", "rand",
"regex", "regex",
@ -812,9 +782,9 @@ dependencies = [
[[package]] [[package]]
name = "object" name = "object"
version = "0.36.2" version = "0.36.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -938,9 +908,12 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.17" version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [
"zerocopy",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
@ -1001,9 +974,9 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.10.5" version = "1.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@ -1039,11 +1012,11 @@ dependencies = [
"encoding_rs", "encoding_rs",
"futures-core", "futures-core",
"futures-util", "futures-util",
"h2 0.4.5", "h2",
"http 1.1.0", "http",
"http-body 1.0.1", "http-body",
"http-body-util", "http-body-util",
"hyper 1.4.1", "hyper",
"hyper-rustls", "hyper-rustls",
"hyper-tls", "hyper-tls",
"hyper-util", "hyper-util",
@ -1064,10 +1037,12 @@ dependencies = [
"system-configuration", "system-configuration",
"tokio", "tokio",
"tokio-native-tls", "tokio-native-tls",
"tokio-util",
"tower-service", "tower-service",
"url", "url",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"wasm-streams",
"web-sys", "web-sys",
"winreg", "winreg",
] ]
@ -1121,9 +1096,9 @@ dependencies = [
[[package]] [[package]]
name = "rustls-pemfile" name = "rustls-pemfile"
version = "2.1.2" version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425"
dependencies = [ dependencies = [
"base64", "base64",
"rustls-pki-types", "rustls-pki-types",
@ -1131,9 +1106,9 @@ dependencies = [
[[package]] [[package]]
name = "rustls-pki-types" name = "rustls-pki-types"
version = "1.7.0" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
[[package]] [[package]]
name = "rustls-webpki" name = "rustls-webpki"
@ -1198,18 +1173,18 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.204" version = "1.0.205"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.204" version = "1.0.205"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1218,11 +1193,12 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.120" version = "1.0.122"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr",
"ryu", "ryu",
"serde", "serde",
] ]
@ -1376,6 +1352,7 @@ dependencies = [
"bytes", "bytes",
"chrono", "chrono",
"derive_builder", "derive_builder",
"futures-util",
"hex", "hex",
"mockito", "mockito",
"reqwest", "reqwest",
@ -1393,14 +1370,15 @@ dependencies = [
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.10.1" version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand",
"once_cell",
"rustix", "rustix",
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@ -1717,6 +1695,19 @@ version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "wasm-streams"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129"
dependencies = [
"futures-util",
"js-sys",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.69" version = "0.3.69"
@ -1754,6 +1745,15 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets 0.52.6",
]
[[package]] [[package]]
name = "windows-targets" name = "windows-targets"
version = "0.48.5" version = "0.48.5"
@ -1885,6 +1885,27 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"byteorder",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "zeroize" name = "zeroize"
version = "1.8.1" version = "1.8.1"

View file

@ -1,25 +1,5 @@
[package] [workspace]
name = "szurubooru-client" resolver = "2"
version = "0.1.0" members = [
edition = "2021" "szurubooru-client"
]
[dependencies]
base64 = "0.22.1"
bytes = "1.6.1"
chrono = { version = "0.4.38", features = ["serde"] }
derive_builder = "0.20.0"
hex = "0.4.3"
reqwest = { version = "0.12.5", features = ["json", "multipart"] }
serde = { version = "1.0.204", features = ["derive"] }
serde_json = "1.0.120"
sha1 = "0.10.6"
strum = { version = "0.26.3", features = ["derive", "strum_macros"] }
strum_macros = "0.26.4"
thiserror = "1.0.63"
tracing = "0.1.40"
url = "2.5.2"
urlencoding = "2.1.3"
[dev-dependencies]
mockito = "1.4.0"
tokio = { version = "1.39.2", features = ["full"] }

26
README.md Normal file
View file

@ -0,0 +1,26 @@
# szurubooru-client
SzurubooruClient is a wrapper around the excellently-documented Szurubooru API,
including type-safe (if not API-safe) Query and Sort tokens.
## Creating a new client
### Basic authentication
Please keep in mind that this is not the preferred method of authentication. Tokens
are far superior.
```rust
use szurubooru_client::SzurubooruClient;
let client = SzurubooruClient::new_with_basic_auth("http://localhost:5001", "myuser",
"mypassword", true).unwrap();
```
### Token authentication
The far superior and more secure means of authentication
```rust
use szurubooru_client::SzurubooruClient;
let client = SzurubooruClient::new_with_token("http://localhost:5001", "myuser", "sz-123456", true).unwrap();
```
For all other methods for making the requests, see the documentation.

View file

@ -1,16 +0,0 @@
//! The core library for SzurubooruClient
#![warn(missing_docs)]
#![warn(rustdoc::missing_crate_level_docs)]
/// Core client module
pub mod client;
pub use client::SzurubooruClient;
pub use client::SzurubooruRequest;
pub mod errors;
pub use errors::SzurubooruResult;
pub mod models;
#[cfg(test)]
mod tests;
pub mod tokens;

1930
szurubooru-client/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,26 @@
[package]
name = "szurubooru-client"
version = "0.1.0"
edition = "2021"
[dependencies]
base64 = "0.22.1"
bytes = "1.6.1"
chrono = { version = "0.4.38", features = ["serde"] }
derive_builder = "0.20.0"
futures-util = "0.3.30"
hex = "0.4.3"
reqwest = { version = "0.12.5", features = ["json", "multipart", "stream"] }
serde = { version = "1.0.204", features = ["derive"] }
serde_json = "1.0.120"
sha1 = "0.10.6"
strum = { version = "0.26.3", features = ["derive", "strum_macros"] }
strum_macros = "0.26.4"
thiserror = "1.0.63"
tracing = "0.1.40"
url = "2.5.2"
urlencoding = "2.1.3"
[dev-dependencies]
mockito = "1.4.0"
tokio = { version = "1.39.2", features = ["full"] }

View file

@ -0,0 +1,26 @@
# szurubooru-client
SzurubooruClient is a wrapper around the excellently-documented Szurubooru API,
including type-safe (if not API-safe) Query and Sort tokens.
## Creating a new client
### Basic authentication
Please keep in mind that this is not the preferred method of authentication. Tokens
are far superior.
```rust
use szurubooru_client::SzurubooruClient;
let client = SzurubooruClient::new_with_basic_auth("http://localhost:5001", "myuser",
"mypassword", true).unwrap();
```
### Token authentication
The far superior and more secure means of authentication
```rust
use szurubooru_client::SzurubooruClient;
let client = SzurubooruClient::new_with_token("http://localhost:5001", "myuser", "sz-123456", true).unwrap();
```
For all other methods for making the requests, see the documentation.

View file

@ -5,7 +5,7 @@ use base64::{engine::general_purpose::STANDARD, Engine as _};
use reqwest::{ use reqwest::{
header::{HeaderMap, ACCEPT, AUTHORIZATION}, header::{HeaderMap, ACCEPT, AUTHORIZATION},
multipart::{Form, Part}, multipart::{Form, Part},
Client, ClientBuilder, Method, RequestBuilder, Client, ClientBuilder, Method, RequestBuilder, Response,
}; };
use serde::{de::DeserializeOwned, Serialize}; use serde::{de::DeserializeOwned, Serialize};
use sha1::{Digest, Sha1}; use sha1::{Digest, Sha1};
@ -33,7 +33,7 @@ impl SzurubooruClient {
/// ///
/// Construct a new `SzurubooruClient` using a username and token. /// Construct a new `SzurubooruClient` using a username and token.
/// ///
/// * `host` - The host to connect to, including `http` or `https`. Any path fragments will /// * `host` - The host to connect to, including `http` or `https`. Any trailing slashes will
/// be stripped /// be stripped
/// * `username` - The username to authenticate as /// * `username` - The username to authenticate as
/// * `token` - The token used to authenticate as `username` /// * `token` - The token used to authenticate as `username`
@ -118,30 +118,88 @@ impl SzurubooruClient {
} }
/// Construct a new request using the existing client auth and base URL /// Construct a new request using the existing client auth and base URL
/// All requests start with the [SzurubooruClient] struct.
/// The (request)[SzurubooruClient::request],
/// (with_fields)[SzurubooruClient::fields],
/// (limit)[SzurubooruClient::limit] and
/// (offset)[SzurubooruClient::offset] methods all return a [SzurubooruRequest] struct that will
/// enable you to actually make the requests.
/// ```no_run
/// # use szurubooru_client::SzurubooruClient;
/// # async {
/// let client = SzurubooruClient::new_with_token("http://localhost:5001", "myuser", "sz-123456", true).unwrap();
/// let new_request = client.request();
/// let tag_categories = new_request.list_tag_categories().await;
/// # }
/// ```
pub fn request(&self) -> SzurubooruRequest { pub fn request(&self) -> SzurubooruRequest {
SzurubooruRequest::new(self) SzurubooruRequest::new(self)
} }
/// Construct a new request while selecting only the given fields /// Construct a new request while selecting only the given fields
pub fn with_fields<'a>(&'a self, fields: &'a Vec<String>) -> SzurubooruRequest { /// The Szurubooru API supports selecting a subset of fields for a given resource.
self.request().fields(fields) /// Most resource (models)[szurubooru_client::models] have [Option] fields because of that.
/// The default is to return all fields for a given resource.
/// See [here](https://github.com/rr-/szurubooru/blob/master/doc/API.md#field-selecting) for
/// more details
///
/// For example, to select only the `version`, `id` and `content_url` fields of a
/// (PostResource)[szurubooru_client::models::PostResource]
/// ```no_run
/// # use szurubooru_client::SzurubooruClient;
/// # async {
/// let client = SzurubooruClient::new_with_token("http://localhost:5001", "myuser", "sz-123456", true).unwrap();
/// let new_request = client.request().with_fields(vec!["version", "id", "content_url"]);
/// # }
/// ```
pub fn with_fields<'a>(&'a self, fields: Vec<&'a str>) -> SzurubooruRequest {
self.request().with_fields(fields)
} }
/// Construct a new request with the given limit /// Construct a new request with the given limit
pub fn limit(&self, limit: u32) -> SzurubooruRequest { /// The Szurubooru API supports limiting the number of resources returned for Paginated
self.request().limit(limit) /// API endpoints.
///
/// For example, to limit the number of pools returned by (list_pools)[SzurubooruRequest::list_pools]
/// ```no_run
/// # use szurubooru_client::SzurubooruClient;
/// # async {
/// let client = SzurubooruClient::new_with_token("http://localhost:5001", "myuser", "sz-123456", true).unwrap();
/// // Limit the number of results per page to 10
/// let pools_result = client.with_limit(10)
/// .list_pools(None)
/// .await;
/// # }
/// ```
pub fn with_limit(&self, limit: u32) -> SzurubooruRequest {
self.request().with_limit(limit)
} }
/// Construct a new request starting at the given offset /// Construct a new request starting at the given offset
pub fn offset(&self, offset: u32) -> SzurubooruRequest { /// The Szurubooru API supports offsetting the results returned from Paginated API
self.request().offset(offset) /// endpoints. Use this offset in combination with the limit to page through
/// large result sets.
///
/// For example, to offset the list of pools returned by (list_pools)[SzurubooruRequest::list_pools]
/// ```no_run
/// # use szurubooru_client::SzurubooruClient;
/// # async {
/// let client = SzurubooruClient::new_with_token("http://localhost:5001", "myuser", "sz-123456", true).unwrap();
/// // Skip the first ten pools in the list
/// let pools_result = client.with_offset(10)
/// .list_pools(None)
/// .await;
/// # }
/// ```
pub fn with_offset(&self, offset: u32) -> SzurubooruRequest {
self.request().with_offset(offset)
} }
} }
#[derive(Debug)] #[derive(Debug)]
/// A type that represents a single Szurubooru request. /// A type that represents a single Szurubooru request.
pub struct SzurubooruRequest<'a> { pub struct SzurubooruRequest<'a> {
fields: Option<&'a Vec<String>>, fields: Option<Vec<&'a str>>,
limit: Option<u32>, limit: Option<u32>,
offset: Option<u32>, offset: Option<u32>,
client: &'a SzurubooruClient, client: &'a SzurubooruClient,
@ -158,25 +216,63 @@ impl<'a> SzurubooruRequest<'a> {
} }
/// Select which fields to return from the query. /// Select which fields to return from the query.
/// Most of the fields in [models] are [Option]s because they can potentially be omitted /// The Szurubooru API supports selecting a subset of fields for a given resource.
/// using this method. /// Most resource (models)[szurubooru_client::models] have [Option] fields because of that.
/// The default is to return all fields for a given resource.
/// See [here](https://github.com/rr-/szurubooru/blob/master/doc/API.md#field-selecting) for /// See [here](https://github.com/rr-/szurubooru/blob/master/doc/API.md#field-selecting) for
/// more details /// more details
pub fn fields(mut self, fields: &'a Vec<String>) -> Self { ///
/// For example, to select only the `version`, `id` and `content_url` fields of a
/// (PostResource)[szurubooru_client::models::PostResource]
/// ```no_run
/// # use szurubooru_client::SzurubooruClient;
/// # async {
/// let client = SzurubooruClient::new_with_token("http://localhost:5001", "myuser", "sz-123456", true).unwrap();
/// let new_request = client.request().with_fields(vec!["version", "id", "content_url"]);
/// # }
/// ```
pub fn with_fields(mut self, fields: Vec<&'a str>) -> Self {
self.fields = Some(fields); self.fields = Some(fields);
self self
} }
/// Limit the number of returned results. Only applies to endpoints that return multiple /// Limit the number of returned results
/// records /// The Szurubooru API supports limiting the number of resources returned for Paginated
pub fn limit(mut self, limit: u32) -> Self { /// API endpoints.
///
/// For example, to limit the number of pools returned by (list_pools)[SzurubooruRequest::list_pools]
/// ```no_run
/// # use szurubooru_client::SzurubooruClient;
/// # async {
/// let client = SzurubooruClient::new_with_token("http://localhost:5001", "myuser", "sz-123456", true).unwrap();
/// // Limit the number of results per page to 10
/// let pools_result = client.with_limit(10)
/// .list_pools(None)
/// .await;
/// # }
/// ```
pub fn with_limit(mut self, limit: u32) -> Self {
self.limit = Some(limit); self.limit = Some(limit);
self self
} }
/// Skip a certain number of records. Only applies to endpoints that return /// Skip a certain number of records
/// [PagedSearchResults](models::PagedSearchResult) /// The Szurubooru API supports offsetting the results returned from Paginated API
pub fn offset(mut self, offset: u32) -> Self { /// endpoints. Use this offset in combination with the limit to page through
/// large result sets.
///
/// For example, to offset the list of pools returned by (list_pools)[SzurubooruRequest::list_pools]
/// ```no_run
/// # use szurubooru_client::SzurubooruClient;
/// # async {
/// let client = SzurubooruClient::new_with_token("http://localhost:5001", "myuser", "sz-123456", true).unwrap();
/// // Skip the first ten pools in the list
/// let pools_result = client.with_offset(10)
/// .list_pools(None)
/// .await;
/// # }
/// ```
pub fn with_offset(mut self, offset: u32) -> Self {
self.offset = Some(offset); self.offset = Some(offset);
self self
} }
@ -200,7 +296,7 @@ impl<'a> SzurubooruRequest<'a> {
qpm.append_pair("query", &query_string); qpm.append_pair("query", &query_string);
} }
if let Some(fields) = self.fields { if let Some(fields) = &self.fields {
let mut qpm = req_url.query_pairs_mut(); let mut qpm = req_url.query_pairs_mut();
let fields_list = fields.join(","); let fields_list = fields.join(",");
qpm.append_pair("fields", &fields_list); qpm.append_pair("fields", &fields_list);
@ -593,6 +689,41 @@ impl<'a> SzurubooruRequest<'a> {
.await .await
} }
async fn get_post_content(&self, post_id: u32) -> SzurubooruResult<Response> {
let post_resource = self.get_post(post_id).await?;
let req = self.prep_request(Method::GET, post_resource.content_url.unwrap(), None);
let request = req
.build()
.map_err(SzurubooruClientError::RequestBuilderError)?;
self.client
.client
.execute(request)
.await
.map_err(SzurubooruClientError::RequestError)
}
///Downloads the given post ID's image as a stream of bytes
pub async fn get_post_content_bytestream(
&self,
post_id: u32,
) -> SzurubooruResult<
impl futures_util::Stream<Item = std::result::Result<bytes::Bytes, reqwest::Error>>,
> {
let content_response = self.get_post_content(post_id).await?;
Ok(content_response.bytes_stream())
}
///Downloads the given post ID's image as a (Bytes)[bytes::Bytes] struct
pub async fn get_post_content_bytes(&self, post_id: u32) -> SzurubooruResult<bytes::Bytes> {
let content_response = self.get_post_content(post_id).await?;
content_response
.bytes()
.await
.map_err(SzurubooruClientError::RequestError)
}
/// Retrieves posts that look like the input image /// Retrieves posts that look like the input image
pub async fn reverse_search_file( pub async fn reverse_search_file(
&self, &self,
@ -653,21 +784,21 @@ impl<'a> SzurubooruRequest<'a> {
} }
/// Retrieves information about an existing post. /// Retrieves information about an existing post.
pub async fn get_post(&self, post_id: i32) -> SzurubooruResult<PostResource> { pub async fn get_post(&self, post_id: u32) -> SzurubooruResult<PostResource> {
let path = format!("/post/{post_id}"); let path = format!("/post/{post_id}");
self.do_request(Method::GET, &path, None, None::<&String>) self.do_request(Method::GET, &path, None, None::<&String>)
.await .await
} }
/// Retrieves information about posts that are before or after an existing post. /// Retrieves information about posts that are before or after an existing post.
pub async fn get_around_post(&self, post_id: i32) -> SzurubooruResult<AroundPostResult> { pub async fn get_around_post(&self, post_id: u32) -> SzurubooruResult<AroundPostResult> {
let path = format!("/post/{post_id}/around"); let path = format!("/post/{post_id}/around");
self.do_request(Method::GET, &path, None, None::<&String>) self.do_request(Method::GET, &path, None, None::<&String>)
.await .await
} }
/// Deletes existing post. Related posts and tags are kept. /// Deletes existing post. Related posts and tags are kept.
pub async fn delete_post(&self, post_id: i32, version: u32) -> SzurubooruResult<()> { pub async fn delete_post(&self, post_id: u32, version: u32) -> SzurubooruResult<()> {
let path = format!("/post/{post_id}"); let path = format!("/post/{post_id}");
let version_obj = ResourceVersion { version }; let version_obj = ResourceVersion { version };
self.do_request(Method::DELETE, &path, None, Some(&version_obj)) self.do_request(Method::DELETE, &path, None, Some(&version_obj))

View file

@ -0,0 +1,40 @@
//! SzurubooruClient is a wrapper around the excellently-documented Szurubooru API,
//! including type-safe (if not API-safe) Query and Sort tokens.
//!
//! # Creating a new client
//!
//! ## Basic authentication
//! Please keep in mind that this is not the preferred method of authentication. Tokens
//! are far superior.
//!
//! ```rust,no_run
//! use szurubooru_client::SzurubooruClient;
//! let client = SzurubooruClient::new_with_basic_auth("http://localhost:5001", "myuser",
//! "mypassword", true).unwrap();
//! ```
//!
//! ## Token authentication
//! The far superior and more secure means of authentication
//!
//! ```rust,no_run
//! use szurubooru_client::SzurubooruClient;
//! let client = SzurubooruClient::new_with_token("http://localhost:5001", "myuser", "sz-123456", true).unwrap();
//! ```
//!
//! For all other methods for making the requests, see the documentation.
#![warn(missing_docs)]
#![warn(rustdoc::missing_crate_level_docs)]
/// Core client module
pub mod client;
pub use client::SzurubooruClient;
pub use client::SzurubooruRequest;
pub mod errors;
pub use errors::SzurubooruResult;
pub mod models;
#[cfg(test)]
mod tests;
pub mod tokens;