add a not found template and reorgainze the code
this commit does quite a bit as it adds a not found html template and it reorganized the code entirely by splitting stuff into modules.
This commit is contained in:
parent
8581bc5f65
commit
9c3002a8d0
11 changed files with 1048 additions and 81 deletions
822
Cargo.lock
generated
822
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
13
Cargo.toml
13
Cargo.toml
|
@ -5,5 +5,14 @@ edition = "2021"
|
|||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rocket = { version = "=0.5.0-rc.3", features = ["json"] }
|
||||
[dependencies.rocket]
|
||||
version = "=0.5.0-rc.3"
|
||||
features = ["json"]
|
||||
|
||||
[dependencies.rocket_dyn_templates]
|
||||
version = "=0.1.0-rc.3"
|
||||
features = ["tera"]
|
||||
|
||||
[dependencies.rust-embed]
|
||||
version = "6.7.0"
|
||||
features = ["debug-embed"]
|
||||
|
|
BIN
public/atkinson-hyperlegible-all-400-normal.woff
Normal file
BIN
public/atkinson-hyperlegible-all-400-normal.woff
Normal file
Binary file not shown.
BIN
public/atkinson-hyperlegible-latin-400-normal.woff2
Normal file
BIN
public/atkinson-hyperlegible-latin-400-normal.woff2
Normal file
Binary file not shown.
BIN
public/atkinson-hyperlegible-latin-ext-400-normal.woff2
Normal file
BIN
public/atkinson-hyperlegible-latin-ext-400-normal.woff2
Normal file
Binary file not shown.
72
public/style.css
Normal file
72
public/style.css
Normal file
|
@ -0,0 +1,72 @@
|
|||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--background-color: #f6f5f4;
|
||||
--text-color: black;
|
||||
--link-color: darkblue;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background-color: #191919;
|
||||
--text-color: #E9E9E9;
|
||||
--link-color: cyan;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Atkinson Hyperlegible", sans-serif;
|
||||
text-align: center;
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
background-color: var(--background-color);
|
||||
color: var(--text-color)
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Atkinson Hyperlegible;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 400;
|
||||
src: url(/public/woff2/atkinson-hyperlegible-latin-ext-400-normal.woff2) format("woff2"),
|
||||
url(/public/woff/atkinson-hyperlegible-all-400-normal.woff) format("woff");
|
||||
unicode-range: U+0100-024F,
|
||||
U+0259,
|
||||
U+1E00-1EFF,
|
||||
U+2020,
|
||||
U+20A0-20AB,
|
||||
U+20AD-20CF,
|
||||
U+2113,
|
||||
U+2C60-2C7F,
|
||||
U+A720-A7FF
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Atkinson Hyperlegible;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 400;
|
||||
src: url(/public/woff2/atkinson-hyperlegible-latin-400-normal.woff2) format("woff2"),
|
||||
url(/public/woff/atkinson-hyperlegible-all-400-normal.woff) format("woff");
|
||||
unicode-range: U+0000-00FF,
|
||||
U+0131,
|
||||
U+0152-0153,
|
||||
U+02BB-02BC,
|
||||
U+02C6,
|
||||
U+02DA,
|
||||
U+02DC,
|
||||
U+2000-206F,
|
||||
U+2074,
|
||||
U+20AC,
|
||||
U+2122,
|
||||
U+2191,
|
||||
U+2193,
|
||||
U+2212,
|
||||
U+2215,
|
||||
U+FEFF,
|
||||
U+FFFD
|
||||
}
|
50
src/assets.rs
Normal file
50
src/assets.rs
Normal file
|
@ -0,0 +1,50 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use rocket::http::Status;
|
||||
use rust_embed::RustEmbed;
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "public/"]
|
||||
pub struct PublicAssets;
|
||||
|
||||
#[derive(Responder)]
|
||||
#[response(status = 200, content_type = "font/woff2")]
|
||||
pub struct RawWoff2Font(pub Cow<'static, [u8]>);
|
||||
|
||||
#[derive(Responder)]
|
||||
#[response(status = 200, content_type = "font/woff")]
|
||||
pub struct RawWoffFont(pub Cow<'static, [u8]>);
|
||||
|
||||
#[get("/style.css")]
|
||||
pub fn style() -> Result<rocket::response::content::RawCss<String>, Status> {
|
||||
let style = PublicAssets::get("style.css").unwrap();
|
||||
match std::str::from_utf8(&style.data) {
|
||||
Ok(style) => Ok(rocket::response::content::RawCss::<String>(style.to_string())),
|
||||
Err(_) => Err(Status::InternalServerError),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/woff2/<font>")]
|
||||
pub fn woff2_font(font: &str) -> Result<RawWoff2Font, Status> {
|
||||
let latin = "atkinson-hyperlegible-latin-400-normal.woff2";
|
||||
let latin_ext = "atkinson-hyperlegible-latin-ext-400-normal.woff2";
|
||||
|
||||
if font == latin {
|
||||
Ok(RawWoff2Font(PublicAssets::get(latin).unwrap().data))
|
||||
} else if font == latin_ext {
|
||||
Ok(RawWoff2Font(PublicAssets::get(latin_ext).unwrap().data))
|
||||
} else {
|
||||
Err(Status::NotFound)
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/woff/<font>")]
|
||||
pub fn woff_font(font: &str) -> Result<RawWoffFont, Status> {
|
||||
let all = "atkinson-hyperlegible-all-400-normal.woff";
|
||||
|
||||
if font == all {
|
||||
Ok(RawWoffFont(PublicAssets::get(all).unwrap().data))
|
||||
} else {
|
||||
Err(Status::NotFound)
|
||||
}
|
||||
}
|
18
src/links.rs
Normal file
18
src/links.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
static NAMES: [&str; 3] = ["mossfet.xyz", "fries.gay", "ta-kev.digital"];
|
||||
|
||||
pub fn previous_url(source_url: &String) -> Option<String> {
|
||||
match NAMES.iter().position(|&r| r == source_url) {
|
||||
Some(index) if index == 0 => Some(NAMES[NAMES.len() - 1].to_string()),
|
||||
Some(index) => Some(NAMES[index - 1].to_string()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_url(source_url: &String) -> Option<String> {
|
||||
// this is gay
|
||||
match NAMES.iter().position(|&r| r == source_url) {
|
||||
Some(index) if index == NAMES.len() - 1 => Some(NAMES[0].to_string()),
|
||||
Some(index) => Some(NAMES[index + 1].to_string()),
|
||||
None => None,
|
||||
}
|
||||
}
|
72
src/main.rs
72
src/main.rs
|
@ -1,64 +1,22 @@
|
|||
#[macro_use]
|
||||
extern crate rocket;
|
||||
use rocket::response::Redirect;
|
||||
use rocket::serde::{json::Json, Serialize};
|
||||
use rocket_dyn_templates::Template;
|
||||
|
||||
static NAMES: [&str; 3] = ["mossfet.xyz", "fries.gay", "ta-kev.digital"];
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
struct JsonResponse {
|
||||
previous_site_name: Option<String>,
|
||||
next_site_name: Option<String>,
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
fn index() -> &'static str {
|
||||
"Like, this is a webring, meow!"
|
||||
}
|
||||
|
||||
fn previous_url(source_url: &String) -> Option<String> {
|
||||
match NAMES.iter().position(|&r| r == source_url) {
|
||||
Some(index) if index == 0 => Some(NAMES[NAMES.len() - 1].to_string()),
|
||||
Some(index) => Some(NAMES[index - 1].to_string()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn next_url(source_url: &String) -> Option<String> {
|
||||
// this is gay
|
||||
match NAMES.iter().position(|&r| r == source_url) {
|
||||
Some(index) if index == NAMES.len() - 1 => Some(NAMES[0].to_string()),
|
||||
Some(index) => Some(NAMES[index + 1].to_string()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/previous?<source_url>")]
|
||||
fn previous(source_url: String) -> Redirect {
|
||||
match previous_url(&source_url) {
|
||||
Some(url) => Redirect::to(format!("https://{}", url)),
|
||||
None => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/next?<source_url>")]
|
||||
fn next(source_url: String) -> Redirect {
|
||||
match next_url(&source_url) {
|
||||
Some(url) => Redirect::to(format!("https://{}", url)),
|
||||
None => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/name?<source_url>")]
|
||||
fn name(source_url: String) -> Json<JsonResponse> {
|
||||
Json(JsonResponse {
|
||||
previous_site_name: previous_url(&source_url),
|
||||
next_site_name: next_url(&source_url),
|
||||
})
|
||||
}
|
||||
mod assets;
|
||||
mod links;
|
||||
mod routes;
|
||||
|
||||
#[launch]
|
||||
fn rocket() -> _ {
|
||||
rocket::build().mount("/", routes![index, previous, next, name])
|
||||
rocket::build()
|
||||
.attach(Template::fairing())
|
||||
.mount(
|
||||
"/",
|
||||
routes![routes::index, routes::previous, routes::next, routes::name],
|
||||
)
|
||||
.register("/", catchers![routes::not_found])
|
||||
.mount(
|
||||
"/public",
|
||||
routes![assets::style, assets::woff2_font, assets::woff_font],
|
||||
)
|
||||
}
|
||||
|
|
67
src/routes.rs
Normal file
67
src/routes.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
use crate::links::{next_url, previous_url};
|
||||
use rocket::{
|
||||
http::Status,
|
||||
response::Redirect,
|
||||
serde::{json::Json, Serialize},
|
||||
};
|
||||
use rocket_dyn_templates::Template;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
struct ErrorTemplate<'a> {
|
||||
error: &'a str,
|
||||
error_description: &'a str,
|
||||
}
|
||||
|
||||
const NOT_FOUND_ERROR: ErrorTemplate = ErrorTemplate {
|
||||
error: "Not Found",
|
||||
error_description: "this URL could not be found on the webring.",
|
||||
};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct JsonResponse {
|
||||
previous_site_name: Option<String>,
|
||||
next_site_name: Option<String>,
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
pub fn index() -> &'static str {
|
||||
"Like, this is a webring, meow!"
|
||||
}
|
||||
|
||||
#[get("/previous?<source_url>")]
|
||||
pub fn previous(source_url: String) -> Result<Redirect, Status> {
|
||||
match previous_url(&source_url) {
|
||||
Some(url) => Ok(Redirect::to(format!("https://{}", url))),
|
||||
None => Err(Status::NotFound),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/next?<source_url>")]
|
||||
pub fn next(source_url: String) -> Result<Redirect, Status> {
|
||||
match next_url(&source_url) {
|
||||
Some(url) => Ok(Redirect::to(format!("https://{}", url))),
|
||||
None => Err(Status::NotFound),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/name?<source_url>")]
|
||||
pub fn name(source_url: String) -> Result<Json<JsonResponse>, Status> {
|
||||
let previous_site_name = previous_url(&source_url);
|
||||
let next_site_name = next_url(&source_url);
|
||||
|
||||
if previous_site_name.is_none() && next_site_name.is_none() {
|
||||
return Err(Status::NotFound);
|
||||
}
|
||||
|
||||
Ok(Json(JsonResponse {
|
||||
previous_site_name,
|
||||
next_site_name,
|
||||
}))
|
||||
}
|
||||
|
||||
#[catch(404)]
|
||||
pub fn not_found() -> Template {
|
||||
Template::render("error", NOT_FOUND_ERROR)
|
||||
}
|
15
templates/error.html.tera
Normal file
15
templates/error.html.tera
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Meowy Webring - {{ error }}</title>
|
||||
<link rel="stylesheet" href="/public/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>{{ error }}</h1>
|
||||
<p>{{ error_description }}</p>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue