meowy-webring/src/routes.rs

97 lines
2.4 KiB
Rust

use crate::{
links::{next_name, next_url, previous_name, previous_url},
responders::CorsResponse,
sites::get_global_names,
};
use meowy_assets::{
files::{get_file_wrapper, FileMetadata},
templates::{BaseTemplate, ErrorTemplate, IndexTemplate},
};
use rocket::{
http::Status,
response::Redirect,
serde::{json::Json, Serialize},
};
fn get_hash_filename(metadata: &FileMetadata) -> Result<String, Status> {
Ok(metadata.get_hash_filename())
}
fn get_base_template() -> Result<BaseTemplate, Status> {
let files = get_file_wrapper()?;
let hyperlegible_filename = get_hash_filename(&files.hyperlegible.metadata)?;
let style_filename = get_hash_filename(&files.style.metadata)?;
let template = BaseTemplate {
hyperlegible_filename,
style_filename,
};
Ok(template)
}
fn not_found_error() -> Result<ErrorTemplate<'static>, 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<String>,
next_site_name: Option<String>,
}
#[get("/")]
pub async fn index() -> Result<IndexTemplate, Status> {
let base_template = get_base_template()?;
let template = IndexTemplate {
sites: get_global_names().await,
base_template,
};
Ok(template)
}
#[get("/previous?<source_url>")]
pub async fn previous(source_url: String) -> Result<Redirect, Status> {
match previous_url(&source_url, &get_global_names().await) {
Some(url) => Ok(Redirect::to(format!("https://{}", url))),
None => Err(Status::NotFound),
}
}
#[get("/next?<source_url>")]
pub async fn next(source_url: String) -> Result<Redirect, Status> {
match next_url(&source_url, &get_global_names().await) {
Some(url) => Ok(Redirect::to(format!("https://{}", url))),
None => Err(Status::NotFound),
}
}
#[get("/name?<source_url>")]
pub async fn name(source_url: String) -> Result<CorsResponse<Json<JsonResponse>>, 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 Err(Status::NotFound);
}
Ok(Json(JsonResponse {
previous_site_name,
next_site_name,
})
.into())
}
#[catch(404)]
pub fn not_found() -> Result<ErrorTemplate<'static>, Status> {
not_found_error()
}