From 8bede900196104b73f8b9cff14cfdc92ed8f0ece Mon Sep 17 00:00:00 2001 From: soup Date: Sun, 2 Feb 2025 19:15:36 -0500 Subject: [PATCH] Bit of a better path param interface --- rs/src/router.rs | 16 +++++++++++++--- shelves/backend/main.rs | 26 +++++++++++++++++++------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/rs/src/router.rs b/rs/src/router.rs index 012675d..6d6c24b 100644 --- a/rs/src/router.rs +++ b/rs/src/router.rs @@ -3,7 +3,17 @@ use std::collections::HashMap; use url::Url; use urlpattern::{UrlPattern, UrlPatternInit, UrlPatternMatchInput}; -pub type PathParams = HashMap>; +pub struct PathParams(HashMap>); +impl PathParams { + pub fn get(&self, name: &str) -> &str { + let s = match self.0.get(name) { + None => return "", + Some(s) => s, + }; + + s.as_ref().map(|s| s.as_str()).unwrap_or("") + } +} struct UrlPatternWithInput { pathname: String, @@ -65,13 +75,13 @@ impl Router { for (upwi, methods) in self.patterns.iter() { let pattern = &upwi.pattern; let result = pattern.exec(UrlPatternMatchInput::Url(url.clone())); - let pathGroups = match result { + let path_groups = match result { Ok(Some(res)) => res.pathname.groups, _ => continue, }; if let Some(t) = methods.get(method) { - return Ok((t, pathGroups)); + return Ok((t, PathParams(path_groups))); } return Err(405); diff --git a/shelves/backend/main.rs b/shelves/backend/main.rs index f6d5609..a825387 100644 --- a/shelves/backend/main.rs +++ b/shelves/backend/main.rs @@ -11,6 +11,10 @@ pub type AnyError = Box; pub type Result = core::result::Result; pub type Dbs = atelier::rusqlite_thread_pool::PoolSender; +pub struct RequestCtx { + dbs: Dbs, + path_params: atelier::router::PathParams, +} fn migrate(connection: &mut rusqlite::Connection) -> Result<()> { Ok(()) @@ -23,7 +27,10 @@ fn init(connection: &mut rusqlite::Connection) -> rusqlite::Result<()> { type Request = axum::extract::Request; type Response = axum::response::Response; type Handler = Box< - dyn Fn(Request) -> Pin + Send + 'static>> + dyn Fn( + Request, + RequestCtx, + ) -> Pin + Send + 'static>> + Send + Sync + 'static, @@ -33,18 +40,22 @@ type Router = atelier::router::Router; fn make_handler(f: F) -> Handler where Fut: Future + Send + 'static, - F: FnMut(Request) -> Fut + Clone + Send + Sync + 'static, + F: FnMut(Request, RequestCtx) -> Fut + Clone + Send + Sync + 'static, { - Box::new(move |req| { + Box::new(move |req, ctx| { let mut f = f.clone(); - Box::pin(async move { f(req).await }) + Box::pin(async move { f(req, ctx).await }) }) } -async fn get_hello(req: Request) -> Response { +async fn get_hello(req: Request, ctx: RequestCtx) -> Response { "hello".into_response() } +async fn get_hello_name(req: Request, ctx: RequestCtx) -> Response { + format!("Hello, {}", ctx.path_params.get("name")).into_response() +} + fn make_router() -> Router { let mut router = atelier::router::Router::new(); @@ -55,6 +66,7 @@ fn make_router() -> Router { } r!("GET", "/hello", get_hello); + r!("GET", "/hello/:name", get_hello_name); router } @@ -67,7 +79,7 @@ async fn serve( let method = req.method().as_str(); let uri = format!("{}", req.uri()); - let (handler, pathParams) = match router.get(method, &uri) { + let (handler, path_params) = match router.get(method, &uri) { Ok(h) => h, Err(sc) => { return (http::status::StatusCode::from_u16(sc).unwrap(), "") @@ -75,7 +87,7 @@ async fn serve( }, }; - handler(req).await + handler(req, RequestCtx { dbs, path_params }).await } async fn go() -> Result<()> {