🏗️ 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.

feat(response): async error handler

Fuwn fff207d3 50601e32

+43 -20
+16 -3
src/handler/response/error.rs
··· 16 16 // Copyright (C) 2022-2022 Fuwn <contact@fuwn.me> 17 17 // SPDX-License-Identifier: GPL-3.0-only 18 18 19 + use async_trait::async_trait; 20 + 19 21 use crate::{context::ErrorContext, Response}; 20 22 21 23 #[allow(clippy::module_name_repetitions)] 22 - pub trait ErrorResponse: FnMut(ErrorContext) -> Response + Send + Sync {} 24 + #[async_trait] 25 + pub trait ErrorResponse: Send + Sync { 26 + async fn call(&mut self, context: ErrorContext) -> Response; 27 + } 23 28 24 - impl<T> ErrorResponse for T where T: FnMut(ErrorContext) -> Response + Send + Sync 25 - {} 29 + #[async_trait] 30 + impl<T, F> ErrorResponse for T 31 + where 32 + T: FnMut(ErrorContext) -> F + Send + Sync, 33 + F: std::future::Future<Output = Response> + Send + 'static, 34 + { 35 + async fn call(&mut self, context: ErrorContext) -> Response { 36 + (*self)(context).await 37 + } 38 + }
+1 -3
src/handler/response/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::future::Future; 20 - 21 19 use async_trait::async_trait; 22 20 23 21 use crate::{context::RouteContext, Response}; ··· 32 30 impl<T, F> RouteResponse for T 33 31 where 34 32 T: FnMut(RouteContext<'_>) -> F + Send + Sync, 35 - F: Future<Output = Response> + Send + 'static, 33 + F: std::future::Future<Output = Response> + Send + 'static, 36 34 { 37 35 async fn call(&mut self, context: RouteContext<'_>) -> Response { 38 36 (*self)(context).await
+26 -14
src/router.rs
··· 75 75 #[derive(Clone)] 76 76 pub struct Router { 77 77 routes: matchit::Router<Arc<AsyncMutex<Box<dyn RouteResponse>>>>, 78 - error_handler: Arc<Mutex<Box<dyn ErrorResponse<Output = Response>>>>, 78 + error_handler: Arc<AsyncMutex<Box<dyn ErrorResponse>>>, 79 79 private_key_file_name: String, 80 80 ca_file_name: String, 81 81 headers: Arc<Mutex<Vec<Box<dyn Partial<Output = String>>>>>, ··· 190 190 /// windmark::success!("You have encountered an error!") 191 191 /// }); 192 192 /// ``` 193 - pub fn set_error_handler( 193 + pub fn set_error_handler<R>( 194 194 &mut self, 195 - handler: impl ErrorResponse + 'static, 196 - ) -> &mut Self { 197 - self.error_handler = Arc::new(Mutex::new(Box::new(handler))); 195 + mut handler: impl FnMut(ErrorContext) -> R + Send + Sync + 'static, 196 + ) -> &mut Self 197 + where 198 + R: IntoFuture<Output = Response> + Send + 'static, 199 + <R as IntoFuture>::IntoFuture: Send, 200 + { 201 + self.error_handler = Arc::new(AsyncMutex::new(Box::new(move |context| { 202 + handler(context).into_future() 203 + }))); 198 204 199 205 self 200 206 } ··· 398 404 399 405 handler.await 400 406 } else { 401 - (*self.error_handler).lock().unwrap()(ErrorContext::new( 402 - stream.get_ref().peer_addr(), 403 - url.clone(), 404 - peer_certificate, 405 - )) 407 + (*self.error_handler) 408 + .lock() 409 + .await 410 + .call(ErrorContext::new( 411 + stream.get_ref().peer_addr(), 412 + url.clone(), 413 + peer_certificate, 414 + )) 415 + .await 406 416 }; 407 417 408 418 for module in &mut *self.async_modules.lock().await { ··· 855 865 fn default() -> Self { 856 866 Self { 857 867 routes: matchit::Router::new(), 858 - error_handler: Arc::new(Mutex::new(Box::new(|_| { 859 - Response::not_found( 860 - "This capsule has not implemented an error handler...", 861 - ) 868 + error_handler: Arc::new(AsyncMutex::new(Box::new(|_| { 869 + async { 870 + Response::not_found( 871 + "This capsule has not implemented an error handler...", 872 + ) 873 + } 862 874 }))), 863 875 private_key_file_name: String::new(), 864 876 ca_file_name: String::new(),