1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use salvo::prelude::*;

use serde_json::Value;

pub type HttpResult<T> = Result<T, AnyHttpError>;

#[allow(dead_code)]
pub enum HttpErrorKind {
    Json(Value),
    Html(String),
}

pub struct AnyHttpError(pub(crate) Option<StatusCode>, pub(crate) HttpErrorKind);

impl AnyHttpError {
    #[allow(dead_code)]
    pub fn new(code: u16, msg: HttpErrorKind) -> Self {
        Self(
            Some(StatusCode::from_u16(code).unwrap_or(StatusCode::BAD_REQUEST)),
            msg,
        )
    }
    pub fn new_msg(msg: HttpErrorKind) -> Self {
        Self(None, msg)
    }
}

#[async_trait]
impl Writer for AnyHttpError {
    async fn write(mut self, _req: &mut Request, _depot: &mut Depot, res: &mut Response) {
        res.status_code(self.0.unwrap_or(StatusCode::BAD_REQUEST));
        match self.1 {
            HttpErrorKind::Json(v) => res.render(Text::Json(v.to_string())),
            HttpErrorKind::Html(v) => res.render(Text::Html(v)),
        }
    }
}

#[macro_export]
macro_rules! json_err {
	($status:expr, {$($t:tt)*}) => {
		{
			use $crate::web_core::http_error;
			http_error::AnyHttpError::new($status,http_error::HttpErrorKind::Json(::serde_json::json!({$($t)*})))
		}
	};
	({$($t:tt)*}) => {
		{
			use $crate::web_core::http_error;
			http_error::AnyHttpError::new_msg(http_error::HttpErrorKind::Json(::serde_json::json!({$($t)*})))
		}
	};
}

#[macro_export]
macro_rules! html_err {
    ($status:expr, $text:expr) => {{
        use $crate::web_core::http_error;
        http_error::AnyHttpError::new($status, http_error::HttpErrorKind::Html($text.into()))
    }};
    ($text:expr) => {{
        use $crate::web_core::http_error;
        http_error::AnyHttpError::new_msg(http_error::HttpErrorKind::Html($text.into()))
    }};
}