use std::{fmt, io};
use serde::Deserialize;
#[derive(Debug, PartialEq, Eq)]
pub enum ErrorKind {
IO,
Json,
UrlParsing,
Request,
Response,
HexDecoding,
MismatchedScopes,
MismatchedState,
LocalServer,
NoAuthorizationCode,
}
#[derive(Debug, PartialEq, Eq)]
pub struct Error {
pub kind: ErrorKind,
pub message: String,
}
impl fmt::Display for Error {
fn fmt( &self, f: &mut fmt::Formatter ) -> fmt::Result {
write!(f, "{}", self.message)
}
}
#[derive(Deserialize)]
struct GoogleDriveAPIError {
code: usize,
message: String,
}
#[derive(Deserialize)]
struct GoogleDriveAPIResponse {
error: GoogleDriveAPIError,
}
#[doc(hidden)]
impl From<reqwest::blocking::Response> for Error {
fn from( response: reqwest::blocking::Response ) -> Self {
let response_code = format!("{}", response.status());
let body = match response.text() {
Ok(body) => body,
Err(error) => return Self {
kind: ErrorKind::Response,
message: format!("{}, (unable to get the body of this error response)", error),
},
};
match serde_json::from_str::<GoogleDriveAPIResponse>(&body) {
Ok(response) => {
Self {
kind: ErrorKind::Response,
message: format!("({}) {}", response.error.code, response.error.message),
}
},
Err(_) => {
Self {
kind: ErrorKind::Response,
message: format!("({}) {}", response_code, body),
}
}
}
}
}
#[doc(hidden)]
impl From<io::Error> for Error {
fn from( error: io::Error ) -> Self {
Self {
kind: ErrorKind::IO,
message: error.to_string(),
}
}
}
#[doc(hidden)]
impl From<serde_json::Error> for Error {
fn from( error: serde_json::Error ) -> Self {
Self {
kind: ErrorKind::Json,
message: error.to_string(),
}
}
}
#[doc(hidden)]
impl From<hex::FromHexError> for Error {
fn from( error: hex::FromHexError ) -> Self {
Self {
kind: ErrorKind::HexDecoding,
message: error.to_string(),
}
}
}
#[doc(hidden)]
impl From<url::ParseError> for Error {
fn from( error: url::ParseError ) -> Self {
Self {
kind: ErrorKind::UrlParsing,
message: error.to_string(),
}
}
}
#[doc(hidden)]
impl From<reqwest::Error> for Error {
fn from( error: reqwest::Error ) -> Self {
Self {
kind: ErrorKind::Request,
message: error.to_string(),
}
}
}
#[doc(hidden)]
impl From<reqwest::header::InvalidHeaderValue> for Error {
fn from( error: reqwest::header::InvalidHeaderValue ) -> Self {
Self {
kind: ErrorKind::Request,
message: error.to_string(),
}
}
}
#[doc(hidden)]
impl From<reqwest::header::ToStrError> for Error {
fn from( error: reqwest::header::ToStrError ) -> Self {
Self {
kind: ErrorKind::Request,
message: error.to_string(),
}
}
}