use super::*;
#[derive(Debug, Serialize)]
pub(super) struct ErrorBody<'a> {
pub(super) error: &'a str,
#[serde(skip_serializing_if = "Option::is_none")]
pub(super) running_actions: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(super) code: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(super) action_limit: Option<usize>,
}
#[derive(Debug)]
pub(super) struct ApiError {
pub(super) status: StatusCode,
pub(super) message: std::borrow::Cow<'static, str>,
pub(super) busy: Option<(usize, usize)>,
pub(super) code: Option<&'static str>,
}
impl ApiError {
pub(super) fn new(
status: StatusCode,
message: impl Into<std::borrow::Cow<'static, str>>,
) -> Self {
Self {
status,
message: message.into(),
busy: None,
code: None,
}
}
pub(super) fn with_code(mut self, code: Option<&'static str>) -> Self {
self.code = code;
self
}
pub(super) fn with_busy(mut self, running: usize, limit: usize) -> Self {
self.busy = Some((running, limit));
self
}
pub(super) fn unauthorized() -> Self {
Self::new(StatusCode::UNAUTHORIZED, "unauthorized")
}
pub(super) fn bad_request(message: impl Into<std::borrow::Cow<'static, str>>) -> Self {
Self::new(StatusCode::BAD_REQUEST, message)
}
pub(super) fn not_found(message: impl Into<std::borrow::Cow<'static, str>>) -> Self {
Self::new(StatusCode::NOT_FOUND, message)
}
pub(super) fn controller_unavailable() -> Self {
Self::new(StatusCode::SERVICE_UNAVAILABLE, "controller unavailable")
}
}
impl IntoResponse for ApiError {
fn into_response(self) -> Response<Body> {
(
self.status,
Json(ErrorBody {
error: &self.message,
code: self.code,
running_actions: self.busy.map(|(running, _)| running),
action_limit: self.busy.map(|(_, limit)| limit),
}),
)
.into_response()
}
}