use std::fmt::{Display, Formatter}; use std::ops::Deref; use actix_web::http::StatusCode; use actix_web::{HttpResponse, ResponseError}; use serde::Serialize; use thiserror::Error; use bank::account::AccountError; #[derive(Serialize)] struct ErrorResponse { code: u16, message: String, } #[derive(Debug, Error)] pub struct HttpAccountError(pub AccountError); impl Display for HttpAccountError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.deref()) } } impl Deref for HttpAccountError { type Target = AccountError; fn deref(&self) -> &Self::Target { &self.0 } } impl ResponseError for HttpAccountError { fn status_code(&self) -> StatusCode { match self.deref() { AccountError::NotFound => StatusCode::NOT_FOUND, AccountError::InvalidAmount => StatusCode::BAD_REQUEST, AccountError::Inactive => StatusCode::GONE, AccountError::Overdraw => StatusCode::BAD_REQUEST, AccountError::AccountNotZero => StatusCode::BAD_REQUEST, } } fn error_response(&self) -> HttpResponse { let status_code = self.status_code(); let error_response = ErrorResponse { code: status_code.as_u16(), message: self.to_string(), }; HttpResponse::build(status_code).json(error_response) } }