summaryrefslogtreecommitdiff
path: root/src/ui.rs
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2024-10-09 22:52:42 -0400
committerOwen Jacobson <owen@grimoire.ca>2024-10-09 23:49:40 -0400
commite55565cb3841bf17cf7b8a5e5cf84e59e4372e11 (patch)
tree31fdbf7d8fbd6b1783c599347642592e4b44ea13 /src/ui.rs
parent66c99389e4725d96ef68298a9c608654b9517d4b (diff)
Normalize `not found` errors a bit.
Diffstat (limited to 'src/ui.rs')
-rw-r--r--src/ui.rs46
1 files changed, 34 insertions, 12 deletions
diff --git a/src/ui.rs b/src/ui.rs
index bba01cc..18dd049 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -1,38 +1,60 @@
use axum::{
extract::Path,
http::{header, StatusCode},
- response::IntoResponse,
+ response::{IntoResponse, Response},
routing::get,
Router,
};
+use mime_guess::Mime;
+use rust_embed::EmbeddedFile;
#[derive(rust_embed::Embed)]
#[folder = "hi-ui/build"]
struct Assets;
+pub fn router<S>() -> Router<S>
+where
+ S: Clone + Send + Sync + 'static,
+{
+ Router::new()
+ .route("/*path", get(asset))
+ .route("/", get(root))
+}
+
+async fn asset(Path(path): Path<String>) -> Result<Asset, NotFound<String>> {
+ let mime = mime_guess::from_path(&path).first_or_octet_stream();
+
+ Assets::get(&path)
+ .map(|file| Asset(mime, file))
+ .ok_or(NotFound(format!("not found: {path}")))
+}
+
async fn root() -> impl IntoResponse {
asset(Path(String::from("index.html"))).await
}
-async fn asset(Path(path): Path<String>) -> impl IntoResponse {
- let mime = mime_guess::from_path(&path).first_or_octet_stream();
+struct Asset(Mime, EmbeddedFile);
- match Assets::get(&path) {
- Some(file) => (
+impl IntoResponse for Asset {
+ fn into_response(self) -> Response {
+ let Self(mime, file) = self;
+ (
StatusCode::OK,
[(header::CONTENT_TYPE, mime.as_ref())],
file.data,
)
- .into_response(),
- None => (StatusCode::NOT_FOUND, "").into_response(),
+ .into_response()
}
}
-pub fn router<S>() -> Router<S>
+struct NotFound<E>(pub E);
+
+impl<E> IntoResponse for NotFound<E>
where
- S: Clone + Send + Sync + 'static,
+ E: IntoResponse,
{
- Router::new()
- .route("/*path", get(asset))
- .route("/", get(root))
+ fn into_response(self) -> Response {
+ let Self(response) = self;
+ (StatusCode::NOT_FOUND, response).into_response()
+ }
}