rocketjson_data/api/response_err.rs
1//!# ApiResponseErr
2//! [`ApiResponseErr`] is returned by enpoints to achieve a Json response success or failure
3
4use crate::error;
5
6///Is returned by enpoints to achieve a Json response success or failure
7///Returned can be errors in [`ApiErrors`]. with `ApiResponseErr.err(...)`.
8///To forward Errors as [`ApiResponseErr`] [`rjtry`] can be used.
9///# Example
10///```
11///pub async fn db_get_users() -> Result<String, diesel::result::Error> {
12/// ...
13///}
14///
15///pub async fn is_admin() -> ApiResponseErr<bool> {
16/// let user = rjtry!(db_get_users().await);
17/// user == "admin"
18///}
19///```
20///```
21///#[derive(serde::Deserialize, validator::Validate, rocketjson::JsonBody)]
22///pub struct LoginRequest {
23/// #[validate(length(min = 1))]
24/// username: String,
25/// #[validate(length(min = 1))]
26/// password: String
27///}
28///
29///#[derive(serde::Serialize)]
30///pub struct LoginResponse {
31/// message: String
32///}
33///
34///#[post("/login", data="<data>")]
35///pub fn login(data: LoginRequest) -> rocketjson::ApiResponseErr<LoginResponse> {
36/// if data.username == "admin" && data.password == "admin" {
37/// return rocketjson::ApiResponseErr::ok(
38/// rocket::http::Status::Ok,
39/// LoginResponse{ message: "logged in" }
40/// );
41/// }
42///
43/// return rocketjson::ApiResponseErr::api_err(rocket::http::Status::InternalServerError, String::from("login failed"))
44///}
45///```
46///- Input
47///```
48///{
49/// "username": "admin",
50/// "password": "admin"
51///}
52///```
53///- Output (200 OK)
54///```
55///{
56/// "message": "logged in"
57///}
58///```
59///- Input
60///```
61///{
62/// "username": "test",
63/// "password": "test"
64///}
65///```
66///- Output (500 Internal Server Error)
67///```
68///{
69/// "error": "login failed"
70///}
71///```
72#[derive(Debug)]
73pub struct ApiResponseErr<T> {
74 /// This is the Json-data sent to the client
75 pub json: Result<rocket::serde::json::Json<T>, error::ApiErrors>,
76 /// This is the Statuscode sent to the client, it is not included in the Json
77 pub status: Option<rocket::http::Status>,
78}
79
80impl<T> ApiResponseErr<T> {
81 pub fn ok(status: rocket::http::Status, json_data: T) -> Self {
82 Self {
83 status: Some(status),
84 json: Ok(rocket::serde::json::Json::from(json_data))
85 }
86 }
87
88 pub fn api_err(status: rocket::http::Status, error: String) -> Self {
89 Self {
90 status: Some(status),
91 json: Err(error::ApiErrors::ApiError(error::ApiError::new(status, error)))
92 }
93 }
94
95 pub fn err(error: error::ApiErrors) -> Self {
96 Self {
97 status: None,
98 json: Err(error)
99 }
100 }
101
102 pub fn get_status(&self) -> rocket::http::Status {
103 if self.status.is_none() {
104 return rocket::http::Status::InternalServerError
105 }
106
107 return self.status.unwrap();
108 }
109}
110
111impl<'r, T> rocket::response::Responder<'r, 'static> for ApiResponseErr<T> where T: serde::Serialize {
112 fn respond_to(self, req: &'r rocket::request::Request<'_>) -> rocket::response::Result<'static> {
113 let status = self.get_status();
114 rocket::response::Response::build_from(self.json.respond_to(req).unwrap())
115 .status(status)
116 .header(rocket::http::ContentType::JSON)
117 .ok()
118 }
119}