use std::io::Cursor; use rust_embed::RustEmbed; use rocket::{Data, Request, Response, Route}; use rocket::http::{ContentType, Method}; use rocket::http::uri::{Segments}; use rocket::http::uri::fmt::Path; use rocket::route::{Handler, Outcome}; #[cfg(feature = "static")] #[derive(RustEmbed)] #[folder = "webroot/"] struct Asset; #[cfg(feature = "static")] #[derive(Clone)] pub struct CustomHandler { } #[cfg(feature = "static")] impl Into> for CustomHandler { fn into(self) -> Vec { vec![ Route::ranked(-2, Method::Get, "/", self), ] } } #[cfg(feature = "static")] #[rocket::async_trait] impl Handler for CustomHandler { async fn handle<'r>(&self, request: &'r Request<'_>, _: Data<'r>) -> Outcome<'r> { let path = request.segments::>(0..).ok() .and_then(|segments| segments.to_path_buf(true).ok()).unwrap(); let path = if path.is_dir() || path.to_str() == Some("") { path.join("index.html") } else { path }; let file_content = ::get(path.to_string_lossy().as_ref()).unwrap(); let content_type: ContentType = path .extension() .map(|x| x.to_string_lossy()) .and_then(|x| ContentType::from_extension(&x)) .unwrap_or(ContentType::Plain); let rsp = Response::build().header(content_type).sized_body(file_content.data.len(), Cursor::new(file_content.data)).finalize(); Outcome::Success(rsp) } }