use std::sync::Arc;
use axum::Router;
use axum::extract::Path as AxumPath;
use axum::http::StatusCode;
use axum::response::IntoResponse;
use rust_embed::Embed;
use crate::api::AppState;
#[derive(Embed)]
#[folder = "dashboard/static"]
struct DashboardAssets;
pub fn routes() -> Router<Arc<AppState>> {
Router::new()
.merge(landing_routes())
.merge(dashboard_routes())
}
pub fn landing_routes() -> Router<Arc<AppState>> {
Router::new()
.route("/", axum::routing::get(landing))
.route("/blog/background-jobs-without-redis", axum::routing::get(blog_post_1))
.route("/examples", axum::routing::get(examples_page))
}
pub fn dashboard_routes() -> Router<Arc<AppState>> {
Router::new()
.route("/dashboard", axum::routing::get(index))
.route("/dashboard/{*path}", axum::routing::get(serve_asset))
}
async fn landing() -> impl IntoResponse {
serve_embedded("landing.html")
}
async fn blog_post_1() -> impl IntoResponse {
serve_embedded("blog-background-jobs-without-redis.html")
}
async fn examples_page() -> impl IntoResponse {
serve_embedded("examples.html")
}
async fn index() -> impl IntoResponse {
serve_embedded("index.html")
}
async fn serve_asset(AxumPath(path): AxumPath<String>) -> impl IntoResponse {
serve_embedded(&path)
}
fn serve_embedded(path: &str) -> axum::response::Response {
match DashboardAssets::get(path) {
Some(file) => {
let ct = content_type(path);
(
StatusCode::OK,
[(axum::http::header::CONTENT_TYPE, ct)],
file.data.to_vec(),
)
.into_response()
}
None => StatusCode::NOT_FOUND.into_response(),
}
}
fn content_type(path: &str) -> &'static str {
if path.ends_with(".html") {
"text/html; charset=utf-8"
} else if path.ends_with(".css") {
"text/css; charset=utf-8"
} else if path.ends_with(".js") {
"application/javascript; charset=utf-8"
} else if path.ends_with(".json") {
"application/json"
} else if path.ends_with(".svg") {
"image/svg+xml"
} else if path.ends_with(".png") {
"image/png"
} else if path.ends_with(".ico") {
"image/x-icon"
} else {
"application/octet-stream"
}
}