Use typed paths for all endpoints

This commit is contained in:
Joscha 2023-08-13 16:40:00 +02:00
parent 058ed2e85c
commit 4ccf06db8b
5 changed files with 37 additions and 25 deletions

View file

@ -19,6 +19,10 @@ use self::{
get_api_worker_bench_repo_by_hash_tree_tar_gz, get_api_worker_repo_by_hash_tree_tar_gz, get_api_worker_bench_repo_by_hash_tree_tar_gz, get_api_worker_repo_by_hash_tree_tar_gz,
post_api_worker_status, post_api_worker_status,
}, },
commit::get_commit_by_hash,
index::get_index,
queue::{get_queue, get_queue_inner},
worker::get_worker_by_name,
}; };
use super::Server; use super::Server;
@ -55,13 +59,13 @@ pub async fn run(server: Server) -> somehow::Result<()> {
// TODO Add text body to body-less status codes // TODO Add text body to body-less status codes
let app = Router::new() let app = Router::new()
.route("/", get(index::get))
.route("/commit/:hash", get(commit::get))
.route("/queue/", get(queue::get))
.route("/queue/inner", get(queue::get_inner))
.route("/worker/:name", get(worker::get))
.typed_get(get_api_worker_bench_repo_by_hash_tree_tar_gz) .typed_get(get_api_worker_bench_repo_by_hash_tree_tar_gz)
.typed_get(get_api_worker_repo_by_hash_tree_tar_gz) .typed_get(get_api_worker_repo_by_hash_tree_tar_gz)
.typed_get(get_commit_by_hash)
.typed_get(get_index)
.typed_get(get_queue)
.typed_get(get_queue_inner)
.typed_get(get_worker_by_name)
.typed_post(post_admin_queue_add) .typed_post(post_admin_queue_add)
.typed_post(post_api_worker_status) .typed_post(post_api_worker_status)
.fallback(get(r#static::static_handler)) .fallback(get(r#static::static_handler))

View file

@ -1,6 +1,6 @@
use askama::Template; use askama::Template;
use axum::{ use axum::{
extract::{Path, State}, extract::State,
http::StatusCode, http::StatusCode,
response::{IntoResponse, Response}, response::{IntoResponse, Response},
}; };
@ -9,7 +9,11 @@ use sqlx::SqlitePool;
use crate::{config::Config, server::util, somehow}; use crate::{config::Config, server::util, somehow};
use super::{link::CommitLink, paths::PathAdminQueueAdd, Base, Tab}; use super::{
link::CommitLink,
paths::{PathAdminQueueAdd, PathCommitByHash},
Base, Tab,
};
#[derive(Template)] #[derive(Template)]
#[template(path = "commit.html")] #[template(path = "commit.html")]
@ -28,8 +32,8 @@ struct CommitTemplate {
link_admin_queue_add: PathAdminQueueAdd, link_admin_queue_add: PathAdminQueueAdd,
} }
pub async fn get( pub async fn get_commit_by_hash(
Path(hash): Path<String>, path: PathCommitByHash,
State(config): State<&'static Config>, State(config): State<&'static Config>,
State(db): State<SqlitePool>, State(db): State<SqlitePool>,
) -> somehow::Result<Response> { ) -> somehow::Result<Response> {
@ -48,7 +52,7 @@ pub async fn get(
FROM commits \ FROM commits \
WHERE hash = ? \ WHERE hash = ? \
", ",
hash path.hash,
) )
.fetch_optional(&db) .fetch_optional(&db)
.await? .await?
@ -63,7 +67,7 @@ pub async fn get(
WHERE child = ? \ WHERE child = ? \
ORDER BY reachable DESC, unixepoch(committer_date) ASC \ ORDER BY reachable DESC, unixepoch(committer_date) ASC \
", ",
hash path.hash,
) )
.fetch(&db) .fetch(&db)
.map_ok(|r| CommitLink::new(&base, r.hash, &r.message, r.reachable)) .map_ok(|r| CommitLink::new(&base, r.hash, &r.message, r.reachable))
@ -77,7 +81,7 @@ pub async fn get(
WHERE parent = ? \ WHERE parent = ? \
ORDER BY reachable DESC, unixepoch(committer_date) ASC \ ORDER BY reachable DESC, unixepoch(committer_date) ASC \
", ",
hash path.hash,
) )
.fetch(&db) .fetch(&db)
.map_ok(|r| CommitLink::new(&base, r.hash, &r.message, r.reachable)) .map_ok(|r| CommitLink::new(&base, r.hash, &r.message, r.reachable))

View file

@ -5,7 +5,7 @@ use sqlx::SqlitePool;
use crate::{config::Config, somehow}; use crate::{config::Config, somehow};
use super::{link::CommitLink, Base, Tab}; use super::{link::CommitLink, paths::PathIndex, Base, Tab};
struct Ref { struct Ref {
name: String, name: String,
@ -21,7 +21,8 @@ struct IndexTemplate {
untracked_refs: Vec<Ref>, untracked_refs: Vec<Ref>,
} }
pub async fn get( pub async fn get_index(
_path: PathIndex,
State(config): State<&'static Config>, State(config): State<&'static Config>,
State(db): State<SqlitePool>, State(db): State<SqlitePool>,
) -> somehow::Result<impl IntoResponse> { ) -> somehow::Result<impl IntoResponse> {

View file

@ -20,6 +20,7 @@ use crate::{
use super::{ use super::{
link::{CommitLink, RunLink, WorkerLink}, link::{CommitLink, RunLink, WorkerLink},
paths::{PathQueue, PathQueueInner},
Base, Tab, Base, Tab,
}; };
@ -88,7 +89,7 @@ async fn get_workers(
Ok(result) Ok(result)
} }
async fn get_queue( async fn get_queue_data(
db: &SqlitePool, db: &SqlitePool,
workers: &[(String, WorkerInfo)], workers: &[(String, WorkerInfo)],
base: &Base, base: &Base,
@ -148,7 +149,8 @@ struct QueueInnerTemplate {
tasks: Vec<Task>, tasks: Vec<Task>,
} }
pub async fn get_inner( pub async fn get_queue_inner(
_path: PathQueueInner,
State(config): State<&'static Config>, State(config): State<&'static Config>,
State(db): State<SqlitePool>, State(db): State<SqlitePool>,
State(workers): State<Arc<Mutex<Workers>>>, State(workers): State<Arc<Mutex<Workers>>>,
@ -156,7 +158,7 @@ pub async fn get_inner(
let base = Base::new(config, Tab::Queue); let base = Base::new(config, Tab::Queue);
let sorted_workers = sorted_workers(&workers); let sorted_workers = sorted_workers(&workers);
let workers = get_workers(&db, &sorted_workers, &base).await?; let workers = get_workers(&db, &sorted_workers, &base).await?;
let tasks = get_queue(&db, &sorted_workers, &base).await?; let tasks = get_queue_data(&db, &sorted_workers, &base).await?;
Ok(QueueInnerTemplate { workers, tasks }) Ok(QueueInnerTemplate { workers, tasks })
} }
#[derive(Template)] #[derive(Template)]
@ -166,7 +168,8 @@ struct QueueTemplate {
inner: QueueInnerTemplate, inner: QueueInnerTemplate,
} }
pub async fn get( pub async fn get_queue(
_path: PathQueue,
State(config): State<&'static Config>, State(config): State<&'static Config>,
State(db): State<SqlitePool>, State(db): State<SqlitePool>,
State(workers): State<Arc<Mutex<Workers>>>, State(workers): State<Arc<Mutex<Workers>>>,
@ -174,7 +177,7 @@ pub async fn get(
let base = Base::new(config, Tab::Queue); let base = Base::new(config, Tab::Queue);
let sorted_workers = sorted_workers(&workers); let sorted_workers = sorted_workers(&workers);
let workers = get_workers(&db, &sorted_workers, &base).await?; let workers = get_workers(&db, &sorted_workers, &base).await?;
let tasks = get_queue(&db, &sorted_workers, &base).await?; let tasks = get_queue_data(&db, &sorted_workers, &base).await?;
Ok(QueueTemplate { Ok(QueueTemplate {
base, base,
inner: QueueInnerTemplate { workers, tasks }, inner: QueueInnerTemplate { workers, tasks },

View file

@ -2,7 +2,7 @@ use std::sync::{Arc, Mutex};
use askama::Template; use askama::Template;
use axum::{ use axum::{
extract::{Path, State}, extract::State,
http::StatusCode, http::StatusCode,
response::{IntoResponse, Response}, response::{IntoResponse, Response},
}; };
@ -13,7 +13,7 @@ use crate::{
somehow, somehow,
}; };
use super::{Base, Tab}; use super::{paths::PathWorkerByName, Base, Tab};
#[derive(Template)] #[derive(Template)]
#[template(path = "worker.html")] #[template(path = "worker.html")]
@ -24,19 +24,19 @@ struct WorkerTemplate {
// TODO Status // TODO Status
} }
pub async fn get( pub async fn get_worker_by_name(
Path(name): Path<String>, path: PathWorkerByName,
State(config): State<&'static Config>, State(config): State<&'static Config>,
State(workers): State<Arc<Mutex<Workers>>>, State(workers): State<Arc<Mutex<Workers>>>,
) -> somehow::Result<Response> { ) -> somehow::Result<Response> {
let info = workers.lock().unwrap().clean().get(&name); let info = workers.lock().unwrap().clean().get(&path.name);
let Some(info) = info else { let Some(info) = info else {
return Ok(StatusCode::NOT_FOUND.into_response()); return Ok(StatusCode::NOT_FOUND.into_response());
}; };
Ok(WorkerTemplate { Ok(WorkerTemplate {
base: Base::new(config, Tab::None), base: Base::new(config, Tab::None),
name, name: path.name,
last_seen: util::format_time(info.last_seen), last_seen: util::format_time(info.last_seen),
} }
.into_response()) .into_response())