use axum::{response::{IntoResponse, Response}, http::{StatusCode, Request, HeaderValue}, body::Body, headers::HeaderName}; use tower::ServiceExt; use tower_http::services::ServeFile; #[derive(Debug)] pub enum ResponseCode { Success, Created, BadRequest, Unauthorized, Forbidden, NotFound, ImATeapot, InternalServerError } impl ResponseCode { pub fn code(self) -> StatusCode { match self { Self::Success => StatusCode::OK, Self::Created => StatusCode::CREATED, Self::BadRequest => StatusCode::BAD_REQUEST, Self::Unauthorized => StatusCode::UNAUTHORIZED, Self::Forbidden => StatusCode::FORBIDDEN, Self::NotFound => StatusCode::NOT_FOUND, Self::ImATeapot => StatusCode::IM_A_TEAPOT, Self::InternalServerError => StatusCode::INTERNAL_SERVER_ERROR } } pub fn text(self, msg: &str) -> Response { (self.code(), msg.to_owned()).into_response() } pub fn json(self, json: &str) -> Response { let mut res = (self.code(), json.to_owned()).into_response(); res.headers_mut().insert( HeaderName::from_static("content-type"), HeaderValue::from_static("application/json"), ); res } pub fn html(self, json: &str) -> Response { let mut res = (self.code(), json.to_owned()).into_response(); res.headers_mut().insert( HeaderName::from_static("content-type"), HeaderValue::from_static("text/html"), ); res } pub async fn file(self, path: &str) -> Result { if path.chars().position(|c| c == '.' ).is_none() { return Err(ResponseCode::BadRequest.text("Folders cannot be served")); } let path = format!("public{}", path); let svc = ServeFile::new(path); let Ok(mut res) = svc.oneshot(Request::new(Body::empty())).await else { return Err(ResponseCode::InternalServerError.text("Error wile fetching file")); }; if res.status() != StatusCode::OK { return Err(ResponseCode::NotFound.text("File not found")); } *res.status_mut() = self.code(); Ok(res.into_response()) } } pub type Result = std::result::Result;