use std::sync::Arc;
use axum::Router;
use axum::extract::State;
use axum::http::{StatusCode, header};
use axum::response::{IntoResponse, Response};
use axum::routing::get;
use crate::assets::{AssetReply, ClientAssets};
use super::config::refusal_text;
pub fn bundle_routes<S>(client: Arc<ClientAssets>) -> Router<S>
where
S: Clone + Send + Sync + 'static,
{
Router::new()
.route("/", get(serve_index))
.route("/{*asset}", get(serve_asset))
.with_state(client)
}
async fn serve_index(State(client): State<Arc<ClientAssets>>) -> Response {
asset_response(client.lookup("index.html"))
}
async fn serve_asset(
State(client): State<Arc<ClientAssets>>,
axum::extract::Path(asset): axum::extract::Path<String>,
) -> Response {
asset_response(client.lookup(&asset))
}
fn asset_response(reply: AssetReply) -> Response {
match reply {
AssetReply::Found {
bytes,
content_type,
gzipped: true,
} => (
StatusCode::OK,
[
(header::CONTENT_TYPE, content_type),
(header::CONTENT_ENCODING, "gzip"),
],
bytes,
)
.into_response(),
AssetReply::Found {
bytes,
content_type,
gzipped: false,
} => (
StatusCode::OK,
[(header::CONTENT_TYPE, content_type)],
bytes,
)
.into_response(),
AssetReply::Miss(err) => (StatusCode::NOT_FOUND, refusal_text(&err)).into_response(),
}
}