diff options
Diffstat (limited to 'src/types/http.rs')
-rw-r--r-- | src/types/http.rs | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/types/http.rs b/src/types/http.rs new file mode 100644 index 0000000..0e7b703 --- /dev/null +++ b/src/types/http.rs @@ -0,0 +1,75 @@ +use axum::{response::{IntoResponse, Response}, http::{StatusCode, Request, HeaderValue}, body::Body, headers::HeaderName}; +use tower::ServiceExt; +use tower_http::services::ServeFile; +use tracing::instrument; + +#[derive(Debug)] +pub enum ResponseCode { + Success, + Created, + BadRequest, + Unauthorized, + Forbidden, + NotFound, + ImATeapot, + InternalServerError +} + +impl ResponseCode { + + const 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 + } + } + + #[instrument()] + pub fn text(self, msg: &str) -> Response { + (self.code(), msg.to_owned()).into_response() + } + + #[instrument()] + 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 + } + + #[instrument()] + 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 + } + + #[instrument()] + pub async fn file(self, path: &str) -> Response { + if !path.chars().any(|c| c == '.' ) { + return Self::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 { + tracing::error!("Error while fetching file"); + return Self::InternalServerError.text("Error while fetching file"); + }; + if res.status() != StatusCode::OK { + return Self::NotFound.text("File not found"); + } + *res.status_mut() = self.code(); + res.into_response() + } +} + +pub type Result<T> = std::result::Result<T, Response>;
\ No newline at end of file |