convert-invert 0.1.0

Orchestrate spotify playlist downloads using soulseek-rs
Documentation
use actix_web::http::StatusCode;
use actix_web::{HttpResponse, ResponseError};
use serde_json::json;
use std::fmt;

#[derive(Debug)]
pub enum ApiError {
    BadRequest(String),
    Unauthorized,
    NotFound(&'static str),
    Internal(String),
}

impl fmt::Display for ApiError {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ApiError::BadRequest(message) => write!(formatter, "{message}"),
            ApiError::Unauthorized => write!(formatter, "Unauthorized"),
            ApiError::NotFound(message) => write!(formatter, "{message}"),
            ApiError::Internal(message) => write!(formatter, "{message}"),
        }
    }
}

impl ResponseError for ApiError {
    fn status_code(&self) -> StatusCode {
        match self {
            ApiError::BadRequest(_) => StatusCode::BAD_REQUEST,
            ApiError::Unauthorized => StatusCode::UNAUTHORIZED,
            ApiError::NotFound(_) => StatusCode::NOT_FOUND,
            ApiError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
        }
    }

    fn error_response(&self) -> HttpResponse {
        let body = json!({
            "error": self.to_string(),
            "code": match self {
                ApiError::BadRequest(_) => "bad_request",
                ApiError::Unauthorized => "unauthorized",
                ApiError::NotFound(_) => "not_found",
                ApiError::Internal(_) => "internal",
            },
        });
        HttpResponse::build(self.status_code()).json(body)
    }
}

impl From<anyhow::Error> for ApiError {
    fn from(error: anyhow::Error) -> Self {
        ApiError::Internal(error.to_string())
    }
}

impl From<diesel::result::Error> for ApiError {
    fn from(error: diesel::result::Error) -> Self {
        ApiError::Internal(error.to_string())
    }
}

impl From<diesel::r2d2::PoolError> for ApiError {
    fn from(error: diesel::r2d2::PoolError) -> Self {
        ApiError::Internal(error.to_string())
    }
}

impl From<redis::RedisError> for ApiError {
    fn from(error: redis::RedisError) -> Self {
        ApiError::Internal(error.to_string())
    }
}

pub type ApiResult<T> = Result<T, ApiError>;