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
.idea/

247
Cargo.lock generated
View file

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

View file

@ -1,25 +1,5 @@
[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"
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"] }
[workspace]
resolver = "2"
members = [
"szurubooru-client"
]

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::{
header::{HeaderMap, ACCEPT, AUTHORIZATION},
multipart::{Form, Part},
Client, ClientBuilder, Method, RequestBuilder,
Client, ClientBuilder, Method, RequestBuilder, Response,
};
use serde::{de::DeserializeOwned, Serialize};
use sha1::{Digest, Sha1};
@ -33,7 +33,7 @@ impl SzurubooruClient {
///
/// 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
/// * `username` - The username to authenticate as
/// * `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
/// 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 {
SzurubooruRequest::new(self)
}
/// Construct a new request while selecting only the given fields
pub fn with_fields<'a>(&'a self, fields: &'a Vec<String>) -> SzurubooruRequest {
self.request().fields(fields)
/// The Szurubooru API supports selecting a subset of fields for a given resource.
/// 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
pub fn limit(&self, limit: u32) -> SzurubooruRequest {
self.request().limit(limit)
/// The Szurubooru API supports limiting the number of resources returned for Paginated
/// 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
pub fn offset(&self, offset: u32) -> SzurubooruRequest {
self.request().offset(offset)
/// The Szurubooru API supports offsetting the results returned from Paginated API
/// 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)]
/// A type that represents a single Szurubooru request.
pub struct SzurubooruRequest<'a> {
fields: Option<&'a Vec<String>>,
fields: Option<Vec<&'a str>>,
limit: Option<u32>,
offset: Option<u32>,
client: &'a SzurubooruClient,
@ -158,25 +216,63 @@ impl<'a> SzurubooruRequest<'a> {
}
/// Select which fields to return from the query.
/// Most of the fields in [models] are [Option]s because they can potentially be omitted
/// using this method.
/// The Szurubooru API supports selecting a subset of fields for a given resource.
/// 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
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
}
/// Limit the number of returned results. Only applies to endpoints that return multiple
/// records
pub fn limit(mut self, limit: u32) -> Self {
/// Limit the number of returned results
/// The Szurubooru API supports limiting the number of resources returned for Paginated
/// 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
}
/// Skip a certain number of records. Only applies to endpoints that return
/// [PagedSearchResults](models::PagedSearchResult)
pub fn offset(mut self, offset: u32) -> Self {
/// Skip a certain number of records
/// The Szurubooru API supports offsetting the results returned from Paginated API
/// 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
}
@ -200,7 +296,7 @@ impl<'a> SzurubooruRequest<'a> {
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 fields_list = fields.join(",");
qpm.append_pair("fields", &fields_list);
@ -593,6 +689,41 @@ impl<'a> SzurubooruRequest<'a> {
.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
pub async fn reverse_search_file(
&self,
@ -653,21 +784,21 @@ impl<'a> SzurubooruRequest<'a> {
}
/// 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}");
self.do_request(Method::GET, &path, None, None::<&String>)
.await
}
/// 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");
self.do_request(Method::GET, &path, None, None::<&String>)
.await
}
/// 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 version_obj = ResourceVersion { version };
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;