🏗️ Elegant & Highly Performant Async Gemini Server Framework for the Modern Age
async framework gemini-protocol protocol gemini rust
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(context): custom parameters format for easy lifetimes

Fuwn 873cef6f 7a51308c

+53 -38
+2 -2
examples/windmark.rs
··· 39 39 println!("clicker has been attached!"); 40 40 } 41 41 42 - async fn on_pre_route(&mut self, context: HookContext<'_>) { 42 + async fn on_pre_route(&mut self, context: HookContext) { 43 43 self.clicks += 1; 44 44 45 45 info!( ··· 49 49 ); 50 50 } 51 51 52 - async fn on_post_route(&mut self, context: HookContext<'_>) { 52 + async fn on_post_route(&mut self, context: HookContext) { 53 53 info!( 54 54 "clicker has been called post-route on {} with {} clicks!", 55 55 context.url.path(),
+8 -5
src/context/hook.rs
··· 16 16 // Copyright (C) 2022-2022 Fuwn <contact@fuwn.me> 17 17 // SPDX-License-Identifier: GPL-3.0-only 18 18 19 + use std::collections::HashMap; 20 + 19 21 use matchit::Params; 20 22 use openssl::x509::X509; 21 23 use url::Url; 22 24 23 25 #[allow(clippy::module_name_repetitions)] 24 26 #[derive(Clone)] 25 - pub struct HookContext<'a> { 27 + pub struct HookContext { 26 28 pub peer_address: Option<std::net::SocketAddr>, 27 29 pub url: Url, 28 - pub params: Option<Params<'a, 'a>>, 30 + pub params: Option<HashMap<String, String>>, 29 31 pub certificate: Option<X509>, 30 32 } 31 33 32 - impl<'a> HookContext<'a> { 34 + impl HookContext { 33 35 #[must_use] 34 36 pub fn new( 35 37 peer_address: std::io::Result<std::net::SocketAddr>, 36 38 url: Url, 37 - params: Option<Params<'a, 'a>>, 39 + params: Option<Params<'_, '_>>, 38 40 certificate: Option<X509>, 39 41 ) -> Self { 40 42 Self { 41 43 peer_address: peer_address.ok(), 42 44 url, 43 - params, 45 + params: params 46 + .map(|parameters| crate::utilities::params_to_hashmap(&parameters)), 44 47 certificate, 45 48 } 46 49 }
+7 -5
src/context/route.rs
··· 16 16 // Copyright (C) 2022-2022 Fuwn <contact@fuwn.me> 17 17 // SPDX-License-Identifier: GPL-3.0-only 18 18 19 + use std::collections::HashMap; 20 + 19 21 use matchit::Params; 20 22 use openssl::x509::X509; 21 23 use url::Url; 22 24 23 25 #[allow(clippy::module_name_repetitions)] 24 26 #[derive(Clone)] 25 - pub struct RouteContext<'a> { 27 + pub struct RouteContext { 26 28 pub peer_address: Option<std::net::SocketAddr>, 27 29 pub url: Url, 28 - pub params: Params<'a, 'a>, 30 + pub params: HashMap<String, String>, 29 31 pub certificate: Option<X509>, 30 32 } 31 33 32 - impl<'a> RouteContext<'a> { 34 + impl RouteContext { 33 35 #[must_use] 34 36 pub fn new( 35 37 peer_address: std::io::Result<std::net::SocketAddr>, 36 38 url: Url, 37 - params: Params<'a, 'a>, 39 + params: &Params<'_, '_>, 38 40 certificate: Option<X509>, 39 41 ) -> Self { 40 42 Self { 41 43 peer_address: peer_address.ok(), 42 44 url, 43 - params, 45 + params: crate::utilities::params_to_hashmap(params), 44 46 certificate, 45 47 } 46 48 }
+2 -2
src/handler/hooks/post_route.rs
··· 20 20 21 21 #[allow(clippy::module_name_repetitions)] 22 22 pub trait PostRouteHook: 23 - FnMut(HookContext<'_>, &mut Response) + Send + Sync 23 + FnMut(HookContext, &mut Response) + Send + Sync 24 24 { 25 25 } 26 26 27 - impl<T> PostRouteHook for T where T: FnMut(HookContext<'_>, &mut Response) + Send + Sync 27 + impl<T> PostRouteHook for T where T: FnMut(HookContext, &mut Response) + Send + Sync 28 28 {}
+2 -2
src/handler/hooks/pre_route.rs
··· 19 19 use crate::context::HookContext; 20 20 21 21 #[allow(clippy::module_name_repetitions)] 22 - pub trait PreRouteHook: FnMut(HookContext<'_>) + Send + Sync {} 22 + pub trait PreRouteHook: FnMut(HookContext) + Send + Sync {} 23 23 24 - impl<T> PreRouteHook for T where T: FnMut(HookContext<'_>) + Send + Sync {} 24 + impl<T> PreRouteHook for T where T: FnMut(HookContext) + Send + Sync {}
+2 -2
src/handler/partial.rs
··· 18 18 19 19 use crate::context::RouteContext; 20 20 21 - pub trait Partial: FnMut(RouteContext<'_>) -> String + Send + Sync {} 21 + pub trait Partial: FnMut(RouteContext) -> String + Send + Sync {} 22 22 23 - impl<T> Partial for T where T: FnMut(RouteContext<'_>) -> String + Send + Sync {} 23 + impl<T> Partial for T where T: FnMut(RouteContext) -> String + Send + Sync {}
+3 -3
src/handler/response/route.rs
··· 23 23 #[allow(clippy::module_name_repetitions)] 24 24 #[async_trait] 25 25 pub trait RouteResponse: Send + Sync { 26 - async fn call(&mut self, context: RouteContext<'_>) -> Response; 26 + async fn call(&mut self, context: RouteContext) -> Response; 27 27 } 28 28 29 29 #[async_trait] 30 30 impl<T, F> RouteResponse for T 31 31 where 32 - T: FnMut(RouteContext<'_>) -> F + Send + Sync, 32 + T: FnMut(RouteContext) -> F + Send + Sync, 33 33 F: std::future::Future<Output = Response> + Send + 'static, 34 34 { 35 - async fn call(&mut self, context: RouteContext<'_>) -> Response { 35 + async fn call(&mut self, context: RouteContext) -> Response { 36 36 (*self)(context).await 37 37 } 38 38 }
+2 -2
src/module/asynchronous.rs
··· 24 24 async fn on_attach(&mut self, _: &mut Router) {} 25 25 26 26 /// Called before a route is mounted. 27 - async fn on_pre_route(&mut self, _: HookContext<'_>) {} 27 + async fn on_pre_route(&mut self, _: HookContext) {} 28 28 29 29 /// Called after a route is mounted. 30 - async fn on_post_route(&mut self, _: HookContext<'_>) {} 30 + async fn on_post_route(&mut self, _: HookContext) {} 31 31 }
+2 -2
src/module/sync.rs
··· 23 23 fn on_attach(&mut self, _: &mut Router) {} 24 24 25 25 /// Called before a route is mounted. 26 - fn on_pre_route(&mut self, _: HookContext<'_>) {} 26 + fn on_pre_route(&mut self, _: HookContext) {} 27 27 28 28 /// Called after a route is mounted. 29 - fn on_post_route(&mut self, _: HookContext<'_>) {} 29 + fn on_post_route(&mut self, _: HookContext) {} 30 30 }
+8 -8
src/response/macros.rs
··· 23 23 #[macro_export] 24 24 macro_rules! $name { 25 25 ($body:expr /* $(,)? */) => { 26 - |_: ::windmark::context::RouteContext<'_>| ::windmark::Response::$name($body) 26 + |_: ::windmark::context::RouteContext| ::windmark::Response::$name($body) 27 27 }; 28 28 ($context:ident, $body:expr /* $(,)? */) => { 29 - |$context: ::windmark::context::RouteContext<'_>| ::windmark::Response::$name($body) 29 + |$context: ::windmark::context::RouteContext| ::windmark::Response::$name($body) 30 30 }; 31 31 } 32 32 )* ··· 40 40 #[macro_export] 41 41 macro_rules! [< $name _async >] { 42 42 ($body:expr /* $(,)? */) => { 43 - |_: ::windmark::context::RouteContext<'_>| async { ::windmark::Response::$name($body) } 43 + |_: ::windmark::context::RouteContext| async { ::windmark::Response::$name($body) } 44 44 }; 45 45 ($context:ident, $body:expr /* $(,)? */) => { 46 - |$context: ::windmark::context::RouteContext<'_>| async { ::windmark::Response::$name($body) } 46 + |$context: ::windmark::context::RouteContext| async { ::windmark::Response::$name($body) } 47 47 }; 48 48 } 49 49 })* ··· 86 86 #[macro_export] 87 87 macro_rules! binary_success { 88 88 ($body:expr, $mime:expr) => { 89 - |_: ::windmark::context::RouteContext<'_>| { 89 + |_: ::windmark::context::RouteContext| { 90 90 ::windmark::Response::binary_success($body, $mime) 91 91 } 92 92 }; ··· 97 97 feature to be enabled" 98 98 ); 99 99 100 - |_: ::windmark::context::RouteContext<'_>| { 100 + |_: ::windmark::context::RouteContext| { 101 101 #[cfg(feature = "auto-deduce-mime")] 102 102 return ::windmark::Response::binary_success_auto($body); 103 103 ··· 107 107 } 108 108 }}; 109 109 ($context:ident, $body:expr, $mime:expr) => { 110 - |$context: ::windmark::context::RouteContext<'_>| { 110 + |$context: ::windmark::context::RouteContext| { 111 111 ::windmark::Response::binary_success($body, $mime) 112 112 } 113 113 }; ··· 118 118 feature to be enabled" 119 119 ); 120 120 121 - |$context: ::windmark::context::RouteContext<'_>| { 121 + |$context: ::windmark::context::RouteContext| { 122 122 #[cfg(feature = "auto-deduce-mime")] 123 123 return ::windmark::Response::binary_success_auto($body); 124 124
+5 -5
src/router.rs
··· 162 162 pub fn mount<R>( 163 163 &mut self, 164 164 route: impl Into<String> + AsRef<str>, 165 - mut handler: impl FnMut(RouteContext<'_>) -> R + Send + Sync + 'static, 165 + mut handler: impl FnMut(RouteContext) -> R + Send + Sync + 'static, 166 166 ) -> &mut Self 167 167 where 168 168 R: IntoFuture<Output = Response> + Send + 'static, ··· 172 172 .routes 173 173 .insert( 174 174 route.into(), 175 - Arc::new(AsyncMutex::new(Box::new( 176 - move |context: RouteContext<'_>| handler(context).into_future(), 177 - ))), 175 + Arc::new(AsyncMutex::new(Box::new(move |context: RouteContext| { 176 + handler(context).into_future() 177 + }))), 178 178 ) 179 179 .unwrap(); 180 180 ··· 375 375 let route_context = RouteContext::new( 376 376 stream.get_ref().peer_addr(), 377 377 url.clone(), 378 - route.params.clone(), 378 + &route.params, 379 379 peer_certificate, 380 380 ); 381 381
+10
src/utilities.rs
··· 31 31 32 32 queries 33 33 } 34 + 35 + #[must_use] 36 + pub fn params_to_hashmap( 37 + params: &matchit::Params<'_, '_>, 38 + ) -> HashMap<String, String> { 39 + params 40 + .iter() 41 + .map(|(k, v)| (k.to_string(), v.to_string())) 42 + .collect() 43 + }