1use reqwest::{Error as ReqwestError, StatusCode};
2use serde::Deserialize;
3use serde_json::Error as JsonError;
4use thiserror::Error as ThisError;
5
6pub type OsuResult<T> = Result<T, OsuError>;
8
9#[derive(Debug, ThisError)]
10pub enum OsuError {
12 #[error("Could not parse i8 `{0}` into ApprovalStatus")]
13 ApprovalStatusParsing(i8),
14 #[error("Failed to build reqwest client")]
15 BuildingClient(#[source] ReqwestError),
16 #[error("Failed to chunk a response")]
17 ChunkingResponse(#[source] ReqwestError),
18 #[error("Failed to parse grade")]
19 GradeParsing,
20 #[error("Either the specified multiplayer match id was invalid or the match is private")]
21 InvalidMultiplayerMatch,
22 #[error("Failed to parse mods")]
23 ModParsing(#[source] ModError),
24 #[error("Failed to deserialize a response")]
25 Parsing {
26 body: String,
27 #[source]
28 source: JsonError,
29 },
30 #[error("Failed to send a request")]
31 RequestError(#[source] ReqwestError),
32 #[error("The response contained an error code={status}")]
33 Response {
34 body: String,
35 #[source]
36 error: ApiError,
37 status: StatusCode,
38 },
39 #[error("The API may be temporarily unavailable (received 503)")]
40 ServiceUnavailable(Option<String>),
41}
42
43#[derive(Debug, Deserialize, ThisError)]
44#[error("{error}")]
45pub struct ApiError {
46 error: String,
47}
48
49#[derive(Debug, ThisError)]
50pub enum ModError {
51 #[error("Failed to parse `{0}`")]
52 U32(u32),
53 #[error("Failed to parse string")]
54 Str,
55}