use oauth2::basic::BasicErrorResponseType;
use serde::Deserialize;
use snafu::prelude::*;
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, Snafu)]
#[snafu(visibility(pub(crate)))]
pub enum Error {
NotAuthenticated,
ExpiredToken,
#[snafu(display(
"The supplied (CSRF) state parameter is not the same as the one sent to the authorisation server. Learn more about CSRF here: https://datatracker.ietf.org/doc/html/rfc6749#section-10.12"
))]
InvalidStateParameter,
RefreshUnavailable,
NoRemainingPages,
#[snafu(display(
"Internal error: the client's PKCE verifier was missing when authenticating."
))]
InvalidClientState,
InvalidResponse,
#[snafu(display("Error returned by the Spotify API: {status} {description}"))]
Spotify {
status: u16,
description: String,
},
#[snafu(display("An error ocurred during the authentication process."))]
Authentication {
source: OauthError,
},
#[snafu(display("{description}"))]
Parse {
description: String,
},
#[snafu(display("An error occurred during deserialization."))]
Deserialization {
source: serde_json::Error,
body: String,
},
#[snafu(display("An HTTP error occurred."))]
Http {
source: reqwest::Error,
},
}
#[derive(Deserialize)]
pub(crate) struct SpotifyError {
error: Details,
}
#[derive(Deserialize)]
struct Details {
status: u16,
message: String,
}
type OauthError = oauth2::RequestTokenError<
oauth2::reqwest::Error<reqwest::Error>,
oauth2::StandardErrorResponse<BasicErrorResponseType>,
>;
impl From<OauthError> for Error {
fn from(source: OauthError) -> Self {
Self::Authentication { source }
}
}
impl From<reqwest::Error> for Error {
fn from(source: reqwest::Error) -> Self {
Self::Http { source }
}
}
impl From<SpotifyError> for Error {
fn from(value: SpotifyError) -> Self {
Self::Spotify {
status: value.error.status,
description: value.error.message,
}
}
}