1use std::error::Error as StdError;
4use std::fmt::Display;
5
6use reqwest::{StatusCode, Url};
7
8#[derive(Debug, thiserror::Error)]
10pub enum CredentialError {
11 #[error("{0}")]
13 Invalid(String),
14 #[error("{url} returned {status}: {body}")]
16 Rejected {
17 url: Url,
18 status: StatusCode,
19 body: String,
20 },
21 #[error(transparent)]
23 Url(#[from] url::ParseError),
24 #[error(transparent)]
26 Http(#[from] reqwest::Error),
27 #[error(transparent)]
29 Json(#[from] serde_json::Error),
30 #[error(transparent)]
32 Io(#[from] std::io::Error),
33 #[error(transparent)]
35 External(Box<dyn StdError + Send + Sync>),
36}
37
38pub type CredentialResult<T> = Result<T, CredentialError>;
40
41impl CredentialError {
42 pub fn invalid(message: impl Display) -> Self {
44 Self::Invalid(message.to_string())
45 }
46
47 pub fn external(error: impl Into<Box<dyn StdError + Send + Sync>>) -> Self {
49 Self::External(error.into())
50 }
51}
52
53impl From<reqwest_middleware::Error> for CredentialError {
54 fn from(error: reqwest_middleware::Error) -> Self {
55 match error {
56 reqwest_middleware::Error::Reqwest(error) => Self::Http(error),
57 reqwest_middleware::Error::Middleware(error) => Self::External(error.into()),
58 }
59 }
60}