use handlebars::Handlebars;
use serde::Serialize;
use serde_json::json;
use std::sync::Arc;
use std::time::SystemTime;
use warp::{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")?;
let hbs = Arc::new(hbs);
// Build routes
let routes = index_filter(hbs.clone())
.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(), json!({"year", year().unwrap()})))
}
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)
}
const UNIX_YEAR: u64 = 31556926;
fn year() -> Result<u64, Box<dyn std::error::Error>> {
let date = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)?
.as_secs();
Ok(date / UNIX_YEAR)
}