#![allow(dead_code)] use duplicate::duplicate; use log::{info, warn}; use rocket::http::Status; use rocket::response::{Responder, Response}; use rocket::Request; use rocket_contrib::json; use rocket_contrib::json::Json; // macro /// 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(status: Status, description: S) -> Self { StatusJson { status, description: description.to_string(), } } pub fn describe(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, 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 for StatusJson { fn from(e: T) -> StatusJson { StatusJson { status: status_code, description: e.to_string(), } } } impl From for StatusJson { fn from(status: Status) -> StatusJson { StatusJson { description: status.reason.to_string(), status, } } }