use axum::{ http::StatusCode, response::{IntoResponse, Response}, }; use serde::Serialize; use utoipa::ToSchema; use crate::ApiError; #[derive(Serialize, ToSchema)] #[serde(tag = "status")] pub enum ErrorResponse { #[serde(rename = "fail")] Fail { #[schema(examples("SomeErrorKind", "NotAuthorized", "Database"))] kind: String, #[schema(examples("some error text"))] message: String, }, #[serde(rename = "error")] Error { #[schema(examples("SomeErrorKind", "NotAuthorized", "Database"))] kind: String, #[schema(examples("some error text"))] message: String, }, } impl ErrorResponse { pub fn fail(kind: impl Into, message: impl Into) -> Self { Self::Fail { kind: kind.into(), message: message.into(), } } pub fn error(kind: impl Into, message: impl Into) -> Self { Self::Error { kind: kind.into(), message: message.into(), } } } impl IntoResponse for ErrorResponse { fn into_response(self) -> Response { ( match self { Self::Fail { .. } => StatusCode::BAD_REQUEST, Self::Error { .. } => StatusCode::INTERNAL_SERVER_ERROR, }, axum::Json(self), ) .into_response() } } impl From for ErrorResponse where T: Into, { fn from(value: T) -> Self { match value.into() { ApiError::Client(e) => Self::Fail { kind: e.kind(), message: e.into_message(), }, ApiError::Server(e) => Self::Error { kind: e.kind(), message: e.into_message(), }, } } }