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

View file

@ -0,0 +1,199 @@
//! Types that represent the various error states that can occur when interacting with
//! Szurubooru
use crate::models::SzuruEither;
use base64::EncodeSliceError;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use url::ParseError as UParseError;
/// Trait to support conversion into a [SzurubooruResult]
#[doc(hidden)]
pub trait IntoClientResult<T> {
/// Convert `self` into a SzurubooruResult
fn into_result(self) -> SzurubooruResult<T>;
}
#[derive(Debug, Error)]
/// Type that represents the various error states that can occur when interacting with
/// Szurubooru
pub enum SzurubooruClientError {
/// Error occurred when trying to Bas64 encode the `username:token` string
#[error("Error encoding authentication token: {0}")]
Base64EncodingError(#[source] EncodeSliceError),
/// Error parsing the given host URL
#[error("Error parsing URL {url}: {source}")]
UrlParseError {
/// The resulting error
source: UParseError,
/// The URL in question
url: String,
},
/// Error occurred building the request before it's sent to the server
#[error("Error building request {0}")]
RequestBuilderError(#[source] reqwest::Error),
/// Error occurred pas part of the request to the server
#[error("Request error {0}")]
RequestError(#[source] reqwest::Error),
/// Error parsing the JSON response from the server
#[error("Response Parsing error: {0}: {1}")]
ResponseParsingError(
/// The JSON parsing error
#[source]
serde_json::Error,
/// The string we attempted to parse
String,
),
/// Error serializing an object as JSON
#[error("JSON Serialization error: {0}")]
JSONSerializationError(#[source] serde_json::Error),
/// Error occurred when reading a file
#[error("IO Error: {0}")]
IOError(#[source] std::io::Error),
/// Error returned by the Szurubooru server
#[error("Error returned from Szurubooru host: {0:?}")]
SzurubooruServerError(SzurubooruServerError),
}
impl From<SzurubooruServerError> for SzurubooruClientError {
fn from(value: SzurubooruServerError) -> Self {
SzurubooruClientError::SzurubooruServerError(value)
}
}
/// Type used to represent success or a failure of some kind
pub type SzurubooruResult<T> = Result<T, SzurubooruClientError>;
#[doc(hidden)]
impl<T> IntoClientResult<T> for SzuruEither<T, SzurubooruServerError> {
fn into_result(self) -> SzurubooruResult<T> {
match self {
SzuruEither::Left(v) => Ok(v),
SzuruEither::Right(e) => Err(SzurubooruClientError::SzurubooruServerError(e)),
}
}
}
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
/// An error type returned by the server
pub enum SzurubooruServerErrorType {
/// Missing required file
MissingRequiredFileError,
/// Missing required parameter
MissingRequiredParameterError,
/// Invalid parameter
InvalidParameterError,
/// Integrity error
IntegrityError,
/// Search error
SearchError,
/// Invalid authentication
AuthError,
/// Post with the given ID not found
PostNotFoundError,
/// Post is already featured
PostAlreadyFeaturedError,
/// Post is already uploaded
PostAlreadyUploadedError,
/// Invalid post ID
InvalidPostIdError,
/// Invalid Post Safety
InvalidPostSafetyError,
/// Invalid post source
InvalidPostSourceError,
/// Invalid post content
InvalidPostContentError,
/// Invalid post relation
InvalidPostRelationError,
/// Invalid post note
InvalidPostNoteError,
/// Invalid post flag
InvalidPostFlagError,
/// Invalid favorite target
InvalidFavoriteTargetError,
/// Invalid comment ID
InvalidCommentIdError,
/// Comment not found
CommentNotFoundError,
/// Empty comment text
EmptyCommentTextError,
/// Invalid score target
InvalidScoreTargetError,
/// Invalid score value
InvalidScoreValueError,
/// Tag category not found
TagCategoryNotFoundError,
/// Tag category already exists
TagCategoryAlreadyExistsError,
/// Tag category is in use
TagCategoryIsInUseError,
/// Invalid tag category name
InvalidTagCategoryNameError,
/// Invalid tag category color
InvalidTagCategoryColorError,
/// Tag not found
TagNotFoundError,
/// Tag already exists
TagAlreadyExistsError,
/// Tag is in use
TagIsInUseError,
/// Invalid tag name
InvalidTagNameError,
/// Invalid tag relation
InvalidTagRelationError,
/// Invalid tag category
InvalidTagCategoryError,
/// Invalid tag description
InvalidTagDescriptionError,
/// User not found
UserNotFoundError,
/// User already exists
UserAlreadyExistsError,
/// Invalid user name
InvalidUserNameError,
/// Invalid email
InvalidEmailError,
/// Invalid password
InvalidPasswordError,
/// Invalid rank
InvalidRankError,
/// Invalid avatar
InvalidAvatarError,
/// Processing error
ProcessingError,
/// Validation error
ValidationError,
}
#[derive(Debug, Serialize, Deserialize)]
/// Type describing an error returned from Szurubooru
pub struct SzurubooruServerError {
/// The name (or type) of error
pub name: SzurubooruServerErrorType,
/// Title of the error
pub title: String,
/// More of a description of the error
pub description: String,
}
#[cfg(test)]
mod test {
use super::*;
use serde_json;
#[test]
fn test_parse_server_error() {
let json_response = r#"{
"name": "ValidationError",
"title": "Validation Error",
"description": "Some sort of validation error"
}"#;
let sse = serde_json::from_str::<SzurubooruServerError>(json_response)
.expect("Failed to parse the JSON response");
assert_eq!(sse.name, SzurubooruServerErrorType::ValidationError);
assert_eq!(sse.title, "Validation Error");
assert_eq!(sse.description, "Some sort of validation error");
}
}