#[macro_use] extern crate rocket; use core::panic; use rocket::fs::{FileServer, relative}; use rocket_dyn_templates::{context, Template}; use std::fs; use sass_rocket_fairing::SassFairing; mod challenge; use challenge::Challenge; #[get("/")] fn get_challenge(challenge: u32) -> Template { Template::render( "index", context! { challenge, content: { use comrak::{parse_document, Arena, ComrakOptions}; let options = { let mut options = ComrakOptions::default(); options.extension.front_matter_delimiter = Some("---".to_owned()); options }; let arena = Arena::new(); let root = parse_document( &arena, &fs::read_to_string(format!("content/challenges/{challenge}.md")).expect("Couldn't find challenge file"), &options, ); if let Some(node) = root.children().next() { if let comrak::nodes::NodeValue::FrontMatter(frontmatter) = &node.data.borrow().value { let frontmatter = { // Trim starting and ending fences let lines: Vec<&str> = frontmatter.trim().lines().collect(); lines[1..lines.len() - 1].join("\n") }; let challenge: Challenge = serde_yaml::from_str(&frontmatter).unwrap(); challenge } else { panic!("No frontmatter!") } } else { panic!("Empty document!") } } }, ) } #[launch] fn rocket() -> _ { let config = rocket::Config::figment().merge(("port", 1313)); rocket::custom(config) .mount("/", routes![get_challenge]) .mount("/css", FileServer::from(relative!("styles/css"))) .attach(Template::fairing()) .attach(SassFairing::default()) }