use std::collections::HashMap;
use axum::{
Json,
response::{IntoResponse, Response},
};
use inflector::string::pluralize::to_plural;
use serde::Serialize;
pub trait ResponseKey {
fn response_key() -> &'static str;
}
#[derive(Serialize)]
struct ApiResponse<T: Serialize> {
#[serde(flatten)]
data: HashMap<String, T>,
}
#[derive(Serialize)]
struct ApiListResponse<T: Serialize> {
#[serde(flatten)]
data: HashMap<String, Vec<T>>,
}
pub struct WrappedJson<T>(pub T);
impl<T> IntoResponse for WrappedJson<T>
where
T: Serialize + ResponseKey,
{
fn into_response(self) -> Response {
let mut map = HashMap::new();
map.insert(T::response_key().to_string(), self.0);
let json = Json(ApiResponse { data: map });
json.into_response()
}
}
impl<T> IntoResponse for WrappedJson<Vec<T>>
where
T: Serialize + ResponseKey,
{
fn into_response(self) -> Response {
let mut map = HashMap::new();
map.insert(to_plural(T::response_key()), self.0);
let json = Json(ApiListResponse { data: map });
json.into_response()
}
}