Files
stl/server/src/status_json.rs
2021-10-22 13:00:29 +02:00

88 lines
2.2 KiB
Rust

#![allow(dead_code)]
use duplicate::duplicate;
use log::{info, warn};
use rocket::http::Status;
use rocket::response::{Responder, Response};
use rocket::serde::json::{json, Json};
use rocket::Request;
/// An error message which can be serialized as JSON.
///
/// #### Example JSON
/// ```json
/// {
/// "status": 404,
/// "description": "Not Found"
/// }
/// ```
#[derive(Debug, Clone)]
pub struct StatusJson {
pub status: Status,
pub description: String,
}
impl StatusJson {
pub fn new<S: ToString>(status: Status, description: S) -> Self {
StatusJson {
status,
description: description.to_string(),
}
}
pub fn describe<S: ToString>(mut self, description: S) -> Self {
self.description = description.to_string();
self
}
}
impl<'r> Responder<'r, 'static> for StatusJson {
fn respond_to(self, req: &Request) -> Result<Response<'static>, Status> {
if self.status.code >= 400 {
warn!(
"Responding with status {}.\n\
Description: {}",
self.status, self.description,
);
} else {
info!("Responding with status {}", self.status);
}
let mut response = Json(json!({
"status": self.status.code,
"description": self.description,
}))
.respond_to(req)?;
response.set_status(self.status);
Ok(response)
}
}
#[duplicate(
status_code T;
[ Status::InternalServerError ] [ sled::Error ];
[ Status::InternalServerError ] [ sled::transaction::TransactionError ];
[ Status::InternalServerError ] [ bincode::Error ];
[ Status::BadRequest ] [ uuid::Error ];
[ Status::BadRequest ] [ chrono::ParseError ];
)]
impl From<T> for StatusJson {
fn from(e: T) -> StatusJson {
StatusJson {
status: status_code,
description: e.to_string(),
}
}
}
impl From<Status> for StatusJson {
fn from(status: Status) -> StatusJson {
StatusJson {
description: status.reason().map(|r| r.to_string()).unwrap_or_default(),
status,
}
}
}