use std::borrow::Cow;
use axum::body::Body;
use http::{header, StatusCode};
use serde::Serialize;
use serde_json::{json, Value};
use crate::http::response;
use crate::support::database::Paginator;
use crate::SharedString;
mod error;
#[derive(Debug, Serialize)]
pub struct Response {
code: u16,
success: bool,
data: Value,
message: Option<SharedString>,
}
impl Response {
fn new(code: StatusCode) -> Self {
Self {
code: code.as_u16(),
success: code.is_success(),
data: Value::Object(Default::default()),
message: code.canonical_reason().map(Cow::Borrowed), }
}
pub fn code(&mut self, code: StatusCode) -> &mut Self {
self.code = code.as_u16();
self.message = code.canonical_reason().map(Cow::Borrowed);
self.success = code.is_success();
self
}
pub fn data<T: Serialize>(&mut self, data: &T) -> &mut Self {
match serde_json::to_value(data) {
Ok(value) => self.data = value,
Err(err) => self.message = Some(Cow::from(err.to_string())),
}
self
}
pub fn paginator(&mut self, paginator: Paginator) -> &mut Self {
let data = json!({
"items": paginator.items,
"meta":{
"pagination": {
"count": paginator.count,
"per_page": paginator.per_page,
"current_page": paginator.current_page,
"total": paginator.total,
"total_pages": paginator.total_pages,
}
}
});
self.data(&data)
}
pub fn message(&mut self, message: impl Into<SharedString>) -> &mut Self {
let message = message.into();
self.message = Some(message);
self
}
pub fn json(&self) -> axum::response::Response {
let bytes = serde_json::to_vec(&self).unwrap_or_else(|err| err.to_string().into_bytes());
axum::response::Response::builder()
.header(header::CONTENT_TYPE, "application/json; charset=utf-8")
.body(Body::from(bytes))
.unwrap_or_default()
}
}
impl Default for Response {
fn default() -> Self {
Self::new(StatusCode::OK)
}
}