use actix_web::body::BoxBody;
use actix_web::http::header::ContentType;
use actix_web::http::StatusCode;
use actix_web::{error, HttpRequest, HttpResponse, Responder};
use serde::Serialize;
use std::fmt::{Debug, Display, Formatter};
pub fn success<T: Sized + Serialize + Default>(data: Option<T>) -> Response<T> {
Response{
data,
msg: String::from("成功"),
code: 200 }
}
pub fn success_respond_to<T: Sized + Serialize + Default>(req: &HttpRequest, data: Option<T>) -> HttpResponse<<Response<T> as Responder>::Body> {
success(data).respond_to(req)
}
pub fn error<T: Sized + Serialize + Default>(data: Option<T>) -> Response<T> {
Response{
data,
msg: String::from("失败"),
..Default::default() }
}
pub fn error_respond_to<T: Sized + Serialize + Default>(req: &HttpRequest, data: Option<T>) -> HttpResponse<<Response<T> as Responder>::Body> {
error(data).respond_to(req)
}
pub fn throw(req: &HttpRequest, ec: ErrorCode) -> HttpResponse<<Response<ErrorCode> as Responder>::Body> {
Response::<ErrorCode>{
data: None,
msg: ec.message().parse().unwrap(),
code: ec.code() as i32
}.respond_to(req)
}
pub fn throw_tips(req: &HttpRequest, ec: ErrorCode, tips: &'static str) -> HttpResponse<<Response<ErrorCode> as Responder>::Body> {
Response::<ErrorCode>{
data: None,
msg: ec.message().replace("%s", tips).parse().unwrap(),
code: ec.code() as i32
}.respond_to(req)
}
pub fn unauthorized<T: Sized + Serialize + Default>(req: &HttpRequest) -> HttpResponse<<Response<T> as Responder>::Body> {
let r: Response<String> = Response{
data: None,
msg: String::from("无权限访问"),
..Default::default() };
r.respond_to(req)
}
#[derive(Serialize, Default)]
pub struct Response<T>
where
T: Sized + Serialize,
{
pub code: i32,
pub data: Option<T>,
pub msg: String,
}
impl<T> Responder for Response<T>
where
T: Sized + Serialize,
{
type Body = BoxBody;
fn respond_to(self, _req: &HttpRequest) -> HttpResponse<Self::Body> {
let body = serde_json::to_string(&self).unwrap();
HttpResponse::Ok()
.content_type(ContentType::json())
.body(body)
}
}
impl<T: Serialize> Display for Response<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let serialized = serde_json::to_string(&self).unwrap();
write!(f, "{}", serialized)
}
}
impl<T: Serialize> Debug for Response<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let serialized = serde_json::to_string(&self).unwrap();
write!(f, "{}", serialized)
}
}
impl<T: Serialize> error::ResponseError for Response<T> {
fn error_response(&self) -> HttpResponse {
HttpResponse::build(self.status_code())
.insert_header(ContentType::json())
.body(self.to_string())
}
fn status_code(&self) -> StatusCode {
StatusCode::OK
}
}
#[derive(Serialize, Default, Debug)]
pub struct ErrorCode {
pub code: i64,
pub message: &'static str,
}
impl ErrorCode {
#[allow(dead_code)]
pub fn code(&self) -> i64 {
self.code
}
#[allow(dead_code)]
pub fn code_string(&self) -> Option<String> {
Some(format!("{}", self.code))
}
#[allow(dead_code)]
pub fn message(&self) -> &'static str {
&self.message
}
#[allow(dead_code)]
pub fn throw_tips(&self, req: &HttpRequest, tips: &'static str) -> HttpResponse<<Response<ErrorCode> as Responder>::Body> {
Response::<ErrorCode>{
data: None,
msg: self.message().replace("%s", tips).parse().unwrap(),
code: self.code() as i32
}.respond_to(req)
}
#[allow(dead_code)]
pub fn throw(&self, req: &HttpRequest) -> HttpResponse<<Response<ErrorCode> as Responder>::Body> {
Response::<ErrorCode>{
data: None,
msg: self.message().parse().unwrap(),
code: self.code() as i32
}.respond_to(req)
}
}
impl Display for ErrorCode {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "({}, {})", self.code, self.message)
}
}
impl error::ResponseError for ErrorCode {
fn error_response(&self) -> HttpResponse {
HttpResponse::build(self.status_code())
.insert_header(ContentType::html())
.body(self.to_string())
}
fn status_code(&self) -> StatusCode {
StatusCode::BAD_REQUEST
}
}
#[allow(dead_code)]
pub trait Auth {
fn response(&self) -> Response<Vec<i32>>;
fn ok(&self) -> bool;
}
#[allow(dead_code)]
pub fn interceptor<A: Auth>(a: A) -> Option<Response<Vec<i32>>> {
if !a.ok() {
return Some(a.response())
}
None
}