use actix_web::{HttpResponse, Responder};
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Serialize, Deserialize)]
pub struct Any {}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ResultPagination {
total: i64,
page: i64,
page_size: i64,
current_page: i64,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ApiResult<T> {
success: bool,
#[serde(skip_serializing_if = "Option::is_none")]
data: Option<T>,
#[serde(skip_serializing_if = "Option::is_none")]
list: Option<Vec<T>>,
#[serde(skip_serializing_if = "Option::is_none")]
message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
code: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pagination: Option<ResultPagination>,
#[serde(skip_serializing_if = "Option::is_none")]
extra: Option<Value>,
}
impl<T> ApiResult<T> {
pub fn value(v: T) -> Self {
ApiResult {
success: true,
data: Some(v),
list: None,
message: None,
code: None,
pagination: None,
extra: None,
}
}
pub fn list(v: Vec<T>) -> Self {
ApiResult {
success: true,
data: None,
list: Some(v),
message: None,
code: None,
pagination: None,
extra: None,
}
}
pub fn fail(message: &str) -> Self {
Self::failure(message)
}
pub fn failure(message: &str) -> Self {
ApiResult {
success: false,
data: None,
list: None,
message: Some(message.to_string()),
code: None,
pagination: None,
extra: None,
}
}
pub fn success() -> Self {
ApiResult {
success: true,
data: None,
list: None,
message: None,
code: None,
pagination: None,
extra: None,
}
}
pub fn extra(&mut self, key: &str, value: Value) -> &mut Self {
match self.extra {
Some(ref mut v) => {
v[key] = value;
}
None => {
let mut v = serde_json::Map::new();
v.insert(key.to_string(), value);
self.extra = Some(v.into());
}
}
self
}
}
impl<T: Serialize> Responder for ApiResult<T> {
type Body = actix_web::body::BoxBody;
fn respond_to(self, _req: &actix_web::HttpRequest) -> actix_web::HttpResponse<Self::Body> {
HttpResponse::Ok().json(self)
}
}
impl<T, E> Into<Result<ApiResult<T>, E>> for ApiResult<T> {
fn into(self) -> Result<ApiResult<T>, E> {
Ok(self)
}
}
pub type DefaultResult<T> = Result<T, Box<dyn std::error::Error>>;
pub type AnyhowResult<T> = Result<T, anyhow::Error>;
pub type AnyResult = ApiResult<Any>;