~starkingdoms/starkingdoms

ref: ccb7ac1036a620f213bb5d24a3332091074e3667 starkingdoms/starkingdoms-backplane/src/response.rs -rw-r--r-- 3.7 KiB
ccb7ac10 — ghostlyzsh Merge branch 'bevy_rewrite' of https://gitlab.com/starkingdoms.tk/starkingdoms.tk into bevy_rewrite 2 years ago
                                                                                
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// StarKingdoms.IO, a browser game about drifting through space
//     Copyright (C) 2023 ghostly_zsh, TerraMaster85, core
//
//     This program is free software: you can redistribute it and/or modify
//     it under the terms of the GNU Affero General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
//
//     This program is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU Affero General Public License for more details.
//
//     You should have received a copy of the GNU Affero General Public License
//     along with this program.  If not, see <https://www.gnu.org/licenses/>.
use crate::error::APIErrorsResponse;
use actix_web::body::BoxBody;
use actix_web::error::JsonPayloadError;
use actix_web::http::StatusCode;
use actix_web::{HttpRequest, HttpResponse, Responder};
use serde::Serialize;
use std::fmt::{Debug, Display, Formatter};

#[derive(Debug)]
pub enum JsonAPIResponse<T: Serialize + Debug> {
    Error(StatusCode, APIErrorsResponse),
    Success(StatusCode, T),
}

impl<T: Serialize + Debug> Display for JsonAPIResponse<T> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl<T: Serialize + Debug> Responder for JsonAPIResponse<T> {
    type Body = BoxBody;

    fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body> {
        match self {
            JsonAPIResponse::Error(c, r) => match serde_json::to_string(&r) {
                Ok(body) => HttpResponse::build(c).body(body),
                Err(err) => HttpResponse::from_error(JsonPayloadError::Serialize(err)),
            },
            JsonAPIResponse::Success(c, b) => match serde_json::to_string(&b) {
                Ok(body) => HttpResponse::build(c).body(body),
                Err(err) => HttpResponse::from_error(JsonPayloadError::Serialize(err)),
            },
        }
    }
}

#[macro_export]
macro_rules! err {
    ($c:expr,$e:expr) => {
        return $crate::response::JsonAPIResponse::Error($c, $e)
    };
}

#[macro_export]
macro_rules! ok {
    ($c:expr,$e:expr) => {
        return $crate::response::JsonAPIResponse::Success($c, $e)
    };
    ($e:expr) => {
        return $crate::response::JsonAPIResponse::Success(actix_web::http::StatusCode::OK, $e)
    };
}

#[macro_export]
macro_rules! internal_error {
    ($e:expr) => {{
        log::error!("internal error: {}", $e);
        $crate::err!(
            actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,
            $crate::make_err!("ERR_INTERNAL_ERROR", $e)
        );
    }};
}

#[macro_export]
macro_rules! handle_error {
    ($e:expr,$c:expr,$r:expr) => {
        match $e {
            Ok(r) => r,
            Err(e) => {
                log::error!("error: {}", e);
                $crate::err!($c, $r)
            }
        }
    };
    ($e:expr) => {
        match $e {
            Ok(r) => r,
            Err(e) => {
                $crate::internal_error!(e)
            }
        }
    };
}

#[macro_export]
macro_rules! make_err {
    ($c:expr,$m:expr,$p:expr) => {
        $crate::error::APIErrorsResponse {
            errors: vec![$crate::error::APIErrorResponse {
                code: $c.to_string(),
                message: $m.to_string(),
                path: Some($p.to_string()),
            }],
        }
    };
    ($c:expr,$m:expr) => {
        $crate::error::APIErrorsResponse {
            errors: vec![$crate::error::APIErrorResponse {
                code: $c.to_string(),
                message: $m.to_string(),
                path: None,
            }],
        }
    };
}