#![macro_use]
use serde::{Deserialize, Serialize};
#[autodoc(category = "Errors", hidden = true)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SharedErrorData {
pub status: u16,
pub message: String,
}
#[autodoc(category = "Errors")]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ErrorResponse {
RateLimited {
#[serde(flatten)]
shared: SharedErrorData,
try_after: u64,
},
Validation {
#[serde(flatten)]
shared: SharedErrorData,
value_name: String,
info: String,
},
NotFound {
#[serde(flatten)]
shared: SharedErrorData,
},
Server {
#[serde(flatten)]
shared: SharedErrorData,
info: String,
},
}
#[cfg(feature = "logic")]
#[macro_export]
macro_rules! error {
($rate_limiter:expr, $error:ident, $($val:expr),+) => {
return $rate_limiter.wrap_response(Err(error!($error, $($val),+)));
};
(RATE_LIMITED, $try_after:expr) => {
ErrorResponse::RateLimited {
shared: $crate::models::SharedErrorData {
status: 429,
message: "You have been rate limited".to_string(),
},
try_after: $try_after,
}
};
(VALIDATION, $value_name:expr, $info:expr) => {
ErrorResponse::Validation {
shared: $crate::models::SharedErrorData {
status: 422,
message: "Invalid request".to_string(),
},
value_name: $value_name.to_string(),
info: $info.to_string(),
}
};
(NOT_FOUND) => {
ErrorResponse::NotFound {
shared: $crate::models::SharedErrorData {
status: 404,
message: "The requested resource could not be found".to_string(),
},
}
};
(SERVER, $info:expr) => {
ErrorResponse::Server {
shared: $crate::models::SharedErrorData {
status: 500,
message: "Server encountered an unexpected error".to_string(),
},
info: $info.to_string(),
}
}
}
#[cfg(feature = "logic")]
#[cfg(test)]
mod tests {
use crate::models::{ErrorResponse, SharedErrorData};
#[test]
fn rate_limited_error() {
assert_eq!(
error!(RATE_LIMITED, 1234),
ErrorResponse::RateLimited {
shared: SharedErrorData {
status: 429,
message: "You have been rate limited".to_string(),
},
try_after: 1234,
}
);
}
#[test]
fn validation_error() {
assert_eq!(
error!(
VALIDATION,
"beans", "You have supplied an invalid amount of beans"
),
ErrorResponse::Validation {
shared: SharedErrorData {
status: 422,
message: "Invalid request".to_string(),
},
value_name: "beans".to_string(),
info: "You have supplied an invalid amount of beans".to_string()
}
);
}
#[test]
fn not_found_error() {
assert_eq!(
error!(NOT_FOUND),
ErrorResponse::NotFound {
shared: SharedErrorData {
status: 404,
message: "The requested resource could not be found".to_string(),
},
}
);
}
#[test]
fn server_error() {
assert_eq!(
error!(SERVER, "Server ran out of Day Do Doh Don De Doh"),
ErrorResponse::Server {
shared: SharedErrorData {
status: 500,
message: "Server encountered an unexpected error".to_string(),
},
info: "Server ran out of Day Do Doh Don De Doh".to_string(),
}
);
}
}