use actix_web::{HttpRequest, HttpResponse, http::header, web};
use include_dir::{Dir, include_dir};
static SITE: Dir<'_> = include_dir!("$OUT_DIR/docs_site");
const DUCKDB_VENDOR_PREFIX: &str = "assets/vendor/duckdb/";
pub fn configure(mount: &str, cfg: &mut web::ServiceConfig) {
let redirect_target = format!("{mount}/");
cfg.service(
web::resource(mount.to_string()).route(web::get().to(move || {
let to = redirect_target.clone();
async move {
HttpResponse::MovedPermanently()
.insert_header((header::LOCATION, to))
.finish()
}
})),
)
.service(
web::scope(mount)
.route("/", web::get().to(serve_index))
.route("/{tail:.*}", web::get().to(serve)),
);
}
async fn serve_index() -> HttpResponse {
serve_path("index.html")
}
async fn serve(req: HttpRequest) -> HttpResponse {
let tail: String = req.match_info().query("tail").into();
let path = if tail.is_empty() || tail.ends_with('/') {
format!("{tail}index.html")
} else {
tail
};
serve_path(&path)
}
fn serve_path(p: &str) -> HttpResponse {
if let Some(f) = SITE.get_file(p) {
return HttpResponse::Ok()
.content_type(mime_guess::from_path(p).first_or_octet_stream().as_ref())
.body(f.contents());
}
if let Some(name) = p.strip_prefix(DUCKDB_VENDOR_PREFIX)
&& let Some(resp) = crate::duckdb_vendor::serve(name)
{
return resp;
}
HttpResponse::NotFound()
.content_type("text/plain; charset=utf-8")
.body("Not Found")
}