use crate::response::{ElifResponse, ElifStatusCode};
use serde::Serialize;
use std::collections::HashMap;
pub fn json<T: Serialize>(data: &T) -> ElifResponse {
ElifResponse::ok().json(data).unwrap_or_else(|err| {
tracing::error!("JSON serialization failed in response helper: {}", err);
ElifResponse::internal_server_error()
})
}
pub fn json_status<T: Serialize>(data: &T, status: ElifStatusCode) -> ElifResponse {
ElifResponse::with_status(status)
.json(data)
.unwrap_or_else(|err| {
tracing::error!("JSON serialization failed in json_status helper: {}", err);
ElifResponse::internal_server_error()
})
}
pub fn json_with_headers<T: Serialize>(data: &T, headers: &[(&str, &str)]) -> ElifResponse {
let mut response = ElifResponse::ok()
.json(data)
.unwrap_or_else(|_| ElifResponse::internal_server_error());
for (key, value) in headers {
response = response
.header(key, value)
.unwrap_or_else(|_| ElifResponse::internal_server_error());
}
response
}
pub fn redirect(url: &str) -> ElifResponse {
ElifResponse::redirect_temporary(url).unwrap_or_else(|_| ElifResponse::internal_server_error())
}
pub fn redirect_permanent(url: &str) -> ElifResponse {
ElifResponse::redirect_permanent(url).unwrap_or_else(|_| ElifResponse::internal_server_error())
}
pub fn text<S: AsRef<str>>(content: S) -> ElifResponse {
ElifResponse::ok().text(content.as_ref())
}
pub fn html<S: AsRef<str>>(content: S) -> ElifResponse {
ElifResponse::ok()
.text(content.as_ref())
.with_header("content-type", "text/html; charset=utf-8")
}
pub fn no_content() -> ElifResponse {
ElifResponse::no_content()
}
pub fn created<T: Serialize>(data: &T) -> ElifResponse {
json_status(data, ElifStatusCode::CREATED)
}
pub fn accepted<T: Serialize>(data: &T) -> ElifResponse {
json_status(data, ElifStatusCode::ACCEPTED)
}
pub fn bad_request<S: AsRef<str>>(message: S) -> ElifResponse {
let error = HashMap::from([("error", message.as_ref())]);
json_status(&error, ElifStatusCode::BAD_REQUEST)
}
pub fn unauthorized<S: AsRef<str>>(message: S) -> ElifResponse {
let error = HashMap::from([("error", message.as_ref())]);
json_status(&error, ElifStatusCode::UNAUTHORIZED)
}
pub fn forbidden<S: AsRef<str>>(message: S) -> ElifResponse {
let error = HashMap::from([("error", message.as_ref())]);
json_status(&error, ElifStatusCode::FORBIDDEN)
}
pub fn not_found<S: AsRef<str>>(message: S) -> ElifResponse {
let error = HashMap::from([("error", message.as_ref())]);
json_status(&error, ElifStatusCode::NOT_FOUND)
}
pub fn server_error<S: AsRef<str>>(message: S) -> ElifResponse {
let error = HashMap::from([("error", message.as_ref())]);
json_status(&error, ElifStatusCode::INTERNAL_SERVER_ERROR)
}
pub fn validation_error<T: Serialize>(errors: &T) -> ElifResponse {
let response_body = HashMap::from([("errors", errors)]);
json_status(&response_body, ElifStatusCode::UNPROCESSABLE_ENTITY)
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn test_json_response() {
let data = vec!["Alice", "Bob"];
let response = json(&data);
assert_eq!(response.status_code(), ElifStatusCode::OK);
}
#[test]
fn test_json_status_response() {
let data = vec!["Alice"];
let response = json_status(&data, ElifStatusCode::CREATED);
assert_eq!(response.status_code(), ElifStatusCode::CREATED);
}
#[test]
fn test_redirect_response() {
let response = redirect("https://example.com");
assert_eq!(response.status_code(), ElifStatusCode::FOUND);
}
#[test]
fn test_text_response() {
let response = text("Hello, World!");
assert_eq!(response.status_code(), ElifStatusCode::OK);
}
#[test]
fn test_html_response() {
let response = html("<h1>Hello, World!</h1>");
assert_eq!(response.status_code(), ElifStatusCode::OK);
}
#[test]
fn test_no_content_response() {
let response = no_content();
assert_eq!(response.status_code(), ElifStatusCode::NO_CONTENT);
}
#[test]
fn test_created_response() {
let data = vec!["Alice"];
let response = created(&data);
assert_eq!(response.status_code(), ElifStatusCode::CREATED);
}
#[test]
fn test_error_responses() {
let bad_req = bad_request("Invalid input");
assert_eq!(bad_req.status_code(), ElifStatusCode::BAD_REQUEST);
let unauthorized_resp = unauthorized("Please login");
assert_eq!(
unauthorized_resp.status_code(),
ElifStatusCode::UNAUTHORIZED
);
let forbidden_resp = forbidden("Access denied");
assert_eq!(forbidden_resp.status_code(), ElifStatusCode::FORBIDDEN);
let not_found_resp = not_found("User not found");
assert_eq!(not_found_resp.status_code(), ElifStatusCode::NOT_FOUND);
let server_err = server_error("Database connection failed");
assert_eq!(
server_err.status_code(),
ElifStatusCode::INTERNAL_SERVER_ERROR
);
}
#[test]
fn test_validation_error() {
let errors = json!({
"name": ["The name field is required"],
"email": ["The email must be a valid email address"]
});
let response = validation_error(&errors);
assert_eq!(response.status_code(), ElifStatusCode::UNPROCESSABLE_ENTITY);
}
#[test]
fn test_json_with_headers() {
let data = vec!["Alice", "Bob"];
let headers = [("X-Total-Count", "2"), ("X-Custom", "value")];
let response = json_with_headers(&data, &headers);
assert_eq!(response.status_code(), ElifStatusCode::OK);
}
}