From cf96b72dfb86afffe00e4f08e1fde8a180c81027 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 12 May 2024 14:52:23 +0200 Subject: [PATCH] Use extension trait for resolving paths --- src/server/web.rs | 1 + src/server/web/admin/queue.rs | 17 +++------ src/server/web/admin/refs.rs | 11 ++---- src/server/web/base.rs | 59 ++++++++--------------------- src/server/web/link.rs | 19 +++++----- src/server/web/pages/commit.rs | 3 +- src/server/web/pages/graph.rs | 5 ++- src/server/web/pages/index.rs | 7 ++-- src/server/web/pages/queue.rs | 21 +++++----- src/server/web/server_config_ext.rs | 31 +++++++++++++++ 10 files changed, 88 insertions(+), 86 deletions(-) create mode 100644 src/server/web/server_config_ext.rs diff --git a/src/server/web.rs b/src/server/web.rs index 4563ae3..2c510f0 100644 --- a/src/server/web.rs +++ b/src/server/web.rs @@ -4,6 +4,7 @@ mod base; mod link; mod pages; pub mod paths; +mod server_config_ext; mod r#static; use axum::{extract::DefaultBodyLimit, routing::get, Router}; diff --git a/src/server/web/admin/queue.rs b/src/server/web/admin/queue.rs index 30b8d9a..e9fb703 100644 --- a/src/server/web/admin/queue.rs +++ b/src/server/web/admin/queue.rs @@ -11,11 +11,11 @@ use time::OffsetDateTime; use crate::{ config::ServerConfig, server::web::{ - base::Base, paths::{ PathAdminQueueAdd, PathAdminQueueAddBatch, PathAdminQueueDecrease, PathAdminQueueDelete, PathAdminQueueIncrease, PathQueue, }, + server_config_ext::ServerConfigExt, }, somehow, }; @@ -52,8 +52,7 @@ pub async fn post_admin_queue_add( form.hash, form.priority, ); - let link = Base::link_with_config(config, PathQueue {}); - Ok(Redirect::to(&format!("{link}"))) + Ok(Redirect::to(config.path(PathQueue {}).as_ref())) } #[derive(Deserialize)] @@ -95,8 +94,7 @@ pub async fn post_admin_queue_add_batch( ); } - let link = Base::link_with_config(config, PathQueue {}); - Ok(Redirect::to(&format!("{link}"))) + Ok(Redirect::to(config.path(PathQueue {}).as_ref())) } #[derive(Deserialize)] @@ -116,8 +114,7 @@ pub async fn post_admin_queue_delete( info!("Admin deleted {} from queue", form.hash); - let link = Base::link_with_config(config, PathQueue {}); - Ok(Redirect::to(&format!("{link}"))) + Ok(Redirect::to(config.path(PathQueue {}).as_ref())) } #[derive(Deserialize)] @@ -140,8 +137,7 @@ pub async fn post_admin_queue_increase( info!("Admin increased queue priority of {} by one", form.hash); - let link = Base::link_with_config(config, PathQueue {}); - Ok(Redirect::to(&format!("{link}"))) + Ok(Redirect::to(config.path(PathQueue {}).as_ref())) } #[derive(Deserialize)] @@ -164,6 +160,5 @@ pub async fn post_admin_queue_decrease( info!("Admin decreased queue priority of {} by one", form.hash); - let link = Base::link_with_config(config, PathQueue {}); - Ok(Redirect::to(&format!("{link}"))) + Ok(Redirect::to(config.path(PathQueue {}).as_ref())) } diff --git a/src/server/web/admin/refs.rs b/src/server/web/admin/refs.rs index cfe4bee..f578ef5 100644 --- a/src/server/web/admin/refs.rs +++ b/src/server/web/admin/refs.rs @@ -13,8 +13,8 @@ use tokio::sync::mpsc; use crate::{ config::ServerConfig, server::web::{ - base::Base, paths::{PathAdminRefsTrack, PathAdminRefsUntrack, PathAdminRefsUpdate, PathIndex}, + server_config_ext::ServerConfigExt, }, somehow, }; @@ -38,8 +38,7 @@ pub async fn post_admin_refs_track( info!("Admin tracked {}", form.r#ref); } - let link = Base::link_with_config(config, PathIndex {}); - Ok(Redirect::to(&link.to_string())) + Ok(Redirect::to(config.path(PathIndex {}).as_ref())) } pub async fn post_admin_refs_untrack( @@ -56,8 +55,7 @@ pub async fn post_admin_refs_untrack( info!("Admin untracked {}", form.r#ref); } - let link = Base::link_with_config(config, PathIndex {}); - Ok(Redirect::to(&link.to_string())) + Ok(Redirect::to(config.path(PathIndex {}).as_ref())) } pub async fn post_admin_repo_update( @@ -68,6 +66,5 @@ pub async fn post_admin_repo_update( let _ = recurring_tx.send(()); info!("Admin updated repo"); - let link = Base::link_with_config(config, PathIndex {}); - Ok(Redirect::to(&link.to_string())) + Ok(Redirect::to(config.path(PathIndex {}).as_ref())) } diff --git a/src/server/web/base.rs b/src/server/web/base.rs index af8a581..d75b384 100644 --- a/src/server/web/base.rs +++ b/src/server/web/base.rs @@ -1,5 +1,3 @@ -use std::fmt; - use maud::{html, Markup, DOCTYPE}; use crate::config::ServerConfig; @@ -7,6 +5,7 @@ use crate::config::ServerConfig; use super::{ paths::{PathGraph, PathIndex, PathQueue}, r#static::{BASE_CSS, LOGO_SVG}, + server_config_ext::{AbsPath, ServerConfigExt}, }; pub enum Tab { @@ -18,18 +17,17 @@ pub enum Tab { #[derive(Clone)] pub struct Base { - pub link_logo_svg: Link, - pub link_base_css: Link, - pub link_index: Link, - pub link_graph: Link, - pub link_queue: Link, - pub web_base: String, - pub repo_name: String, + pub link_logo_svg: AbsPath, + pub link_base_css: AbsPath, + pub link_index: AbsPath, + pub link_graph: AbsPath, + pub link_queue: AbsPath, + pub config: &'static ServerConfig, pub tab: &'static str, } impl Base { - pub fn new(config: &ServerConfig, tab: Tab) -> Self { + pub fn new(config: &'static ServerConfig, tab: Tab) -> Self { let tab = match tab { Tab::None => "", Tab::Index => "index", @@ -37,32 +35,16 @@ impl Base { Tab::Queue => "queue", }; Self { - link_logo_svg: Self::link_with_config(config, LOGO_SVG), - link_base_css: Self::link_with_config(config, BASE_CSS), - link_index: Self::link_with_config(config, PathIndex {}), - link_graph: Self::link_with_config(config, PathGraph {}), - link_queue: Self::link_with_config(config, PathQueue {}), - web_base: config.web_base.clone(), - repo_name: config.repo_name.clone(), + link_logo_svg: config.path(LOGO_SVG), + link_base_css: config.path(BASE_CSS), + link_index: config.path(PathIndex {}), + link_graph: config.path(PathGraph {}), + link_queue: config.path(PathQueue {}), + config, tab, } } - fn link_with_base(base: &str, to: P) -> Link { - let to = format!("{to}"); - assert!(!base.ends_with('/')); - assert!(to.starts_with('/')); - Link(format!("{base}{to}")) - } - - pub fn link_with_config(config: &ServerConfig, to: P) -> Link { - Self::link_with_base(&config.web_base, to) - } - - pub fn link(&self, to: P) -> Link { - Self::link_with_base(&self.web_base, to) - } - pub fn html(&self, title: &str, head: Markup, body: Markup) -> Markup { html!( (DOCTYPE) @@ -70,7 +52,7 @@ impl Base { head { meta charset="utf-8"; meta name="viewport" content="width=device-width"; - title { (title) " - " (self.repo_name) } + title { (title) " - " (self.config.repo_name) } link rel="icon" href=(self.link_logo_svg); link rel="stylesheet" href=(self.link_base_css); (head) @@ -79,7 +61,7 @@ impl Base { nav { a .current[self.tab == "index"] href=(self.link_index) { img src=(self.link_logo_svg) alt=""; - (self.repo_name) + (self.config.repo_name) } a .current[self.tab == "graph"] href=(self.link_graph) { "graph" } a .current[self.tab == "queue"] href=(self.link_queue) { "queue" } @@ -90,12 +72,3 @@ impl Base { ) } } - -#[derive(Clone)] -pub struct Link(String); - -impl fmt::Display for Link { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} diff --git a/src/server/web/link.rs b/src/server/web/link.rs index 3e232bb..a92157e 100644 --- a/src/server/web/link.rs +++ b/src/server/web/link.rs @@ -4,12 +4,13 @@ use time::OffsetDateTime; use crate::server::util; use super::{ - base::{Base, Link}, + base::Base, paths::{PathCommitByHash, PathRunById, PathWorkerByName}, + server_config_ext::{AbsPath, ServerConfigExt}, }; pub struct LinkCommit { - link: Link, + link: AbsPath, short: String, reachable: i64, } @@ -18,7 +19,7 @@ impl LinkCommit { pub fn new(base: &Base, hash: String, message: &str, reachable: i64) -> Self { Self { short: util::format_commit_short(&hash, message), - link: base.link(PathCommitByHash { hash }), + link: base.config.path(PathCommitByHash { hash }), reachable, } } @@ -53,14 +54,14 @@ impl LinkCommit { } pub struct LinkRunShort { - link: Link, + link: AbsPath, short: String, } impl LinkRunShort { pub fn new(base: &Base, id: String, hash: &str, message: &str) -> Self { Self { - link: base.link(PathRunById { id }), + link: base.config.path(PathRunById { id }), short: util::format_commit_short(hash, message), } } @@ -73,14 +74,14 @@ impl LinkRunShort { } pub struct LinkRunDate { - link: Link, + link: AbsPath, date: String, // TODO base.date(...)? } impl LinkRunDate { pub fn new(base: &Base, id: String, start: OffsetDateTime) -> Self { Self { - link: base.link(PathRunById { id }), + link: base.config.path(PathRunById { id }), date: util::format_time(start), } } @@ -93,14 +94,14 @@ impl LinkRunDate { } pub struct LinkWorker { - link: Link, + link: AbsPath, name: String, } impl LinkWorker { pub fn new(base: &Base, name: String) -> Self { Self { - link: base.link(PathWorkerByName { name: name.clone() }), + link: base.config.path(PathWorkerByName { name: name.clone() }), name, } } diff --git a/src/server/web/pages/commit.rs b/src/server/web/pages/commit.rs index bf61f42..eb6560e 100644 --- a/src/server/web/pages/commit.rs +++ b/src/server/web/pages/commit.rs @@ -15,6 +15,7 @@ use crate::{ base::{Base, Tab}, link::{LinkCommit, LinkRunDate}, paths::{PathAdminQueueAdd, PathCommitByHash}, + server_config_ext::ServerConfigExt, }, }, somehow, @@ -145,7 +146,7 @@ pub async fn get_commit_by_hash( } } } - form method="post" action=(base.link(PathAdminQueueAdd {})) { + form method="post" action=(config.path(PathAdminQueueAdd {})) { input type="hidden" name="hash" value=(commit.hash); button { "Add to queue" } " with a " label for="priority" { "priority" } " of " diff --git a/src/server/web/pages/graph.rs b/src/server/web/pages/graph.rs index a046c88..7c07886 100644 --- a/src/server/web/pages/graph.rs +++ b/src/server/web/pages/graph.rs @@ -15,6 +15,7 @@ use crate::{ base::{Base, Tab}, paths::{PathGraph, PathGraphCommits, PathGraphMeasurements, PathGraphMetrics}, r#static::{GRAPH_JS, UPLOT_CSS}, + server_config_ext::ServerConfigExt, }, }, somehow, @@ -29,8 +30,8 @@ pub async fn get_graph( Ok(base.html( "graph", html! { - link rel="stylesheet" href=(base.link(UPLOT_CSS)); - script type="module" src=(base.link(GRAPH_JS)) {} + link rel="stylesheet" href=(config.path(UPLOT_CSS)); + script type="module" src=(config.path(GRAPH_JS)) {} }, html! { h2 { "Graph" } diff --git a/src/server/web/pages/index.rs b/src/server/web/pages/index.rs index 32ddf01..c50ee34 100644 --- a/src/server/web/pages/index.rs +++ b/src/server/web/pages/index.rs @@ -9,6 +9,7 @@ use crate::{ base::{Base, Tab}, link::LinkCommit, paths::{PathAdminRefsTrack, PathAdminRefsUntrack, PathAdminRefsUpdate, PathIndex}, + server_config_ext::ServerConfigExt, }, somehow, }; @@ -60,7 +61,7 @@ pub async fn get_index( h2 { "Refs" } details .refs-list open { summary { "Tracked (" (tracked_refs.len()) ")" } - form method="post" action=(base.link(PathAdminRefsUntrack {})) { + form method="post" action=(config.path(PathAdminRefsUntrack {})) { dl { @for r#ref in tracked_refs { dt { @@ -75,7 +76,7 @@ pub async fn get_index( } details .refs-list { summary { "Untracked (" (untracked_refs.len()) ")" } - form method="post" action=(base.link(PathAdminRefsTrack {})) { + form method="post" action=(config.path(PathAdminRefsTrack {})) { dl { @for r#ref in untracked_refs { dt { @@ -88,7 +89,7 @@ pub async fn get_index( } } } - form method="post" action=(base.link(PathAdminRefsUpdate {})) { + form method="post" action=(config.path(PathAdminRefsUpdate {})) { button { "Update" } } }, diff --git a/src/server/web/pages/queue.rs b/src/server/web/pages/queue.rs index 0199946..a11cf29 100644 --- a/src/server/web/pages/queue.rs +++ b/src/server/web/pages/queue.rs @@ -17,13 +17,14 @@ use crate::{ server::{ util, web::{ - base::{Base, Link, Tab}, + base::{Base, Tab}, link::{LinkCommit, LinkRunShort, LinkWorker}, paths::{ PathAdminQueueAddBatch, PathAdminQueueDecrease, PathAdminQueueDelete, PathAdminQueueIncrease, PathQueue, PathQueueDelete, PathQueueInner, }, r#static::QUEUE_JS, + server_config_ext::{AbsPath, ServerConfigExt}, }, workers::{WorkerInfo, Workers}, }, @@ -43,9 +44,9 @@ struct Worker { } struct Task { - link_delete: Link, - link_increase: Link, - link_decrease: Link, + link_delete: AbsPath, + link_increase: AbsPath, + link_decrease: AbsPath, hash: String, commit: LinkCommit, since: String, @@ -125,11 +126,11 @@ async fn get_queue_data( .fetch(db) .map_ok(|r| Task { workers: workers_by_commit.remove(&r.hash).unwrap_or_default(), - link_delete: base.link(PathQueueDelete { + link_delete: base.config.path(PathQueueDelete { hash: r.hash.clone(), }), - link_increase: base.link(PathAdminQueueIncrease {}), - link_decrease: base.link(PathAdminQueueDecrease {}), + link_increase: base.config.path(PathAdminQueueIncrease {}), + link_decrease: base.config.path(PathAdminQueueDecrease {}), hash: r.hash.clone(), commit: LinkCommit::new(base, r.hash, &r.message, r.reachable), since: util::format_delta_from_now(r.date), @@ -246,11 +247,11 @@ pub async fn get_queue( Ok(base.html( &format!("queue ({})", tasks.len()), html! { - script type="module" src=(base.link(QUEUE_JS)) {} + script type="module" src=(config.path(QUEUE_JS)) {} }, html! { div #inner { (page_inner(workers, tasks)) } - form method="post" action=(base.link(PathAdminQueueAddBatch {})) { + form method="post" action=(config.path(PathAdminQueueAddBatch {})) { label { "Batch size: " input name="amount" type="number" value="10" min="1"; @@ -299,7 +300,7 @@ pub async fn get_queue_delete( p { "You are about to delete this commit from the queue:" } p { (commit.html()) } p { "All runs of this commit currently in progress will be aborted!" } - form method="post" action=(base.link(PathAdminQueueDelete {})) { + form method="post" action=(config.path(PathAdminQueueDelete {})) { input name="hash" type="hidden" value=(r.hash); button { "Delete commit and abort runs" } } diff --git a/src/server/web/server_config_ext.rs b/src/server/web/server_config_ext.rs new file mode 100644 index 0000000..ae5fb8b --- /dev/null +++ b/src/server/web/server_config_ext.rs @@ -0,0 +1,31 @@ +use std::fmt; + +use crate::config::ServerConfig; + +pub trait ServerConfigExt { + fn path(&self, to: T) -> AbsPath; +} + +impl ServerConfigExt for ServerConfig { + fn path(&self, to: T) -> AbsPath { + let to = to.to_string(); + assert!(to.starts_with('/')); + AbsPath(format!("{}{to}", self.web_base)) + } +} + +/// An absolute path to a resource on the web server. +#[derive(Clone)] +pub struct AbsPath(String); + +impl fmt::Display for AbsPath { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl AsRef for AbsPath { + fn as_ref(&self) -> &str { + &self.0 + } +}