use handlebars::Handlebars;
use serde::Serialize;
use std::sync::Arc;
use warp::{http::Uri, Filter, Rejection};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Build template registry
let mut hbs = Handlebars::new();
hbs.register_template_file("base", "templates/base.hbs")?;
hbs.register_template_file("index", "templates/index.hbs")?;
hbs.register_template_file("policies", "templates/policies.hbs")?;
hbs.register_template_file("about", "templates/about.hbs")?;
let hbs = Arc::new(hbs);
// Build routes
let routes = index_filter(hbs.clone())
.or(template_filter(hbs.clone()))
.or(redirect_static_ext())
.or(evals_list())
.or(warp::fs::dir("static"));
// Start server
warp::serve(routes).run(([127, 0, 0, 1], 8080)).await;
// Done
Ok(())
}
fn index_filter(
hbs: Arc<Handlebars<'static>>,
) -> impl Filter<Extract = (impl warp::Reply,), Error = Rejection> + Clone {
warp::get()
.and(warp::path::end())
.map(move || render("index", hbs.clone(), ""))
}
fn template_filter(
hbs: Arc<Handlebars<'static>>,
) -> impl Filter<Extract = (impl warp::Reply,), Error = Rejection> + Clone {
warp::path!(String).and_then(move |name: String| {
let hbs = hbs.clone();
async move {
if hbs.has_template(&name) {
Ok(render(&name, hbs, ""))
} else {
Err(warp::reject::not_found())
}
}
})
}
fn redirect_static_ext() -> impl Filter<Extract = (impl warp::Reply,), Error = Rejection> + Clone {
warp::path!(String).and_then(move |path: String| async move {
if let Some(prefix) = path.strip_suffix(".php") {
return Ok(warp::redirect(
prefix
.parse::<Uri>()
.unwrap_or_else(|_| Uri::from_static("/")),
));
}
if let Some(prefix) = path.strip_suffix(".html") {
return Ok(warp::redirect(
prefix
.parse::<Uri>()
.unwrap_or_else(|_| Uri::from_static("/")),
));
}
Err(warp::reject::not_found())
})
}
fn evals_list() -> impl Filter<Extract = (&'static str,), Error = Rejection> + Clone {
warp::get()
.and(warp::path("evals"))
.and(warp::path::end())
.map(|| "evals here")
}
fn render<T>(template: &str, hbs: Arc<Handlebars>, value: T) -> impl warp::Reply
where
T: Serialize,
{
let render = hbs
.render(template, &value)
.unwrap_or_else(|err| err.to_string());
warp::reply::html(render)
}