use crate::{ assets::{ files::{get_file_wrapper, FileMetadata}, templates::{BaseTemplate, ErrorTemplate, IndexTemplate}, }, links::{next_name, next_url, previous_name, previous_url}, sites::get_global_names, }; use rocket::{ http::Status, response::Redirect, serde::{json::Json, Serialize}, }; use rocket_cors::{Guard, Responder}; fn get_hash_filename(metadata: &FileMetadata) -> Result { Ok(metadata.get_hash_filename()) } fn get_base_template() -> Result { let files = get_file_wrapper()?; let style_filename = get_hash_filename(&files.style.metadata)?; let atkinson_latin_woff2_filename = get_hash_filename(&files.atkinson_latin_woff2.metadata)?; let atkinson_latin_ext_woff2_filename = get_hash_filename(&files.atkinson_latin_ext_woff2.metadata)?; let atkinson_all_woff_filename = get_hash_filename(&files.atkinson_all_woff.metadata)?; let template = BaseTemplate { style_filename, atkinson_latin_woff2_filename, atkinson_latin_ext_woff2_filename, atkinson_all_woff_filename, }; Ok(template) } fn not_found_error() -> Result, Status> { let base_template = get_base_template()?; let template = ErrorTemplate { error: "Not Found", error_description: "this URL could not be found on the webring.", base_template, }; Ok(template) } #[derive(Serialize)] #[serde(crate = "rocket::serde")] pub struct JsonResponse { previous_site_name: Option, next_site_name: Option, } #[get("/")] pub async fn index() -> Result { let base_template = get_base_template()?; let template = IndexTemplate { sites: get_global_names().await, base_template, }; Ok(template) } #[get("/previous?")] pub async fn previous(source_url: String) -> Result { match previous_url(&source_url, &get_global_names().await) { Some(url) => Ok(Redirect::to(format!("https://{}", url))), None => Err(Status::NotFound), } } #[get("/next?")] pub async fn next(source_url: String) -> Result { match next_url(&source_url, &get_global_names().await) { Some(url) => Ok(Redirect::to(format!("https://{}", url))), None => Err(Status::NotFound), } } #[get("/name?")] pub async fn name( source_url: String, cors: Guard<'_>, ) -> Responder, Status>> { let previous_site_name = previous_name(&source_url, &get_global_names().await); let next_site_name = next_name(&source_url, &get_global_names().await); if previous_site_name.is_none() && next_site_name.is_none() { return cors.responder(Err(Status::NotFound)); } let response = Ok(Json(JsonResponse { previous_site_name, next_site_name, })); cors.responder(response) } #[catch(404)] pub fn not_found() -> Result, Status> { not_found_error() }