use std::path::PathBuf;
use std::sync::Arc;
use axum::{
extract::{OriginalUri, State},
http::{StatusCode, Uri},
response::{IntoResponse, Response},
};
use crate::http::state::AppState;
use crate::serve::file::{serve_file, ContentType, ServeError};
pub async fn library_serve_components(
OriginalUri(uri): OriginalUri,
State(state): State<Arc<AppState>>,
) -> Response {
library_dispatch(state, uri).await
}
pub async fn library_serve_scripts(
OriginalUri(uri): OriginalUri,
State(state): State<Arc<AppState>>,
) -> Response {
library_dispatch(state, uri).await
}
pub async fn library_serve_tokens(
OriginalUri(uri): OriginalUri,
State(state): State<Arc<AppState>>,
) -> Response {
library_dispatch(state, uri).await
}
async fn library_dispatch(state: Arc<AppState>, uri: Uri) -> Response {
let Some(library_root) = state.library_root.as_ref() else {
return (StatusCode::NOT_FOUND, "library routes disabled").into_response();
};
let suffix: PathBuf = uri
.path()
.trim_start_matches('/')
.to_owned()
.into();
match serve_file(library_root, &suffix) {
Ok(served) => {
let mime = match served.content_type {
ContentType::Html => "text/html; charset=utf-8",
ContentType::Css => "text/css; charset=utf-8",
ContentType::Js => "application/javascript; charset=utf-8",
ContentType::Json => "application/json; charset=utf-8",
ContentType::Png => "image/png",
ContentType::Jpeg => "image/jpeg",
ContentType::Svg => "image/svg+xml",
ContentType::PlainText => "text/plain; charset=utf-8",
ContentType::OctetStream => "application/octet-stream",
};
(
StatusCode::OK,
[(axum::http::header::CONTENT_TYPE, mime)],
served.body,
)
.into_response()
}
Err(ServeError::NotFound | ServeError::NotAFile | ServeError::EscapedRoot) => {
(StatusCode::NOT_FOUND, "not found").into_response()
}
Err(ServeError::Io(e)) => {
eprintln!(
"DBG library_serve Io error: {e:?} root={:?} suffix={:?}",
library_root, suffix
);
(StatusCode::INTERNAL_SERVER_ERROR, format!("io: {e}")).into_response()
}
}
}