diff options
| author | Fuwn <[email protected]> | 2022-03-27 11:38:41 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2022-03-27 11:38:41 +0000 |
| commit | c60dd3ceda6b818271a48765f676bf3505dcbbeb (patch) | |
| tree | d4a9a8caa94f259c2fef30e9cafea3d0533451de | |
| parent | feat(handler): fnmut partial (diff) | |
| download | windmark-c60dd3ceda6b818271a48765f676bf3505dcbbeb.tar.xz windmark-c60dd3ceda6b818271a48765f676bf3505dcbbeb.zip | |
feat(handler): more fnmut
| -rw-r--r-- | README.md | 6 | ||||
| -rw-r--r-- | examples/windmark.rs | 52 | ||||
| -rw-r--r-- | src/handler.rs | 3 | ||||
| -rw-r--r-- | src/lib.rs | 78 |
4 files changed, 77 insertions, 62 deletions
@@ -33,10 +33,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { windmark::Router::new() .set_private_key_file("windmark_private.pem") .set_certificate_chain_file("windmark_pair.pem") - .mount("/", |_| Response::Success("Hello, World!".into())) - .set_error_handler(|_| { + .mount("/", Box::new(|_| Response::Success("Hello, World!".into()))) + .set_error_handler(Box::new(|_| { Response::PermanentFailure("This route does not exist!".into()) - }) + })) .run() .await } diff --git a/examples/windmark.rs b/examples/windmark.rs index 29376a8..7cbf60d 100644 --- a/examples/windmark.rs +++ b/examples/windmark.rs @@ -39,7 +39,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { Response::PermanentFailure("e".into()) })) .attach(|r| { - r.mount("/module", |_| Response::Success("This is a module!".into())); + r.mount("/module", Box::new(|_| Response::Success("This is a module!".into()))); }) .set_pre_route_callback(Box::new(|stream, url, _| { info!( @@ -56,24 +56,24 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { })) .set_header(Box::new(|_| "```\nART IS COOL\n```".to_string())) .set_footer(Box::new(|_| "Copyright 2022".to_string())) - .mount("/", |_| { + .mount("/", Box::new(|_| { Response::Success( "# INDEX\n\nWelcome!\n\n=> /test Test Page\n=> /time Unix Epoch\n" .to_string(), ) - }) - .mount("/ip", |context| { + })) + .mount("/ip", Box::new(|context| { Response::Success( { format!("Hello, {}", context.tcp.peer_addr().unwrap().ip()) }.into(), ) - }) - .mount("/test", |_| { + })) + .mount("/test", Box::new(|_| { Response::Success("hi there\n=> / back".to_string()) - }) - .mount("/temporary-failure", |_| { + })) + .mount("/temporary-failure", Box::new(|_| { Response::TemporaryFailure("Woops, temporarily...".into()) - }) - .mount("/time", |_| { + })) + .mount("/time", Box::new(|_| { Response::Success( std::time::UNIX_EPOCH .elapsed() @@ -81,47 +81,47 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { .as_nanos() .to_string(), ) - }) - .mount("/query", |context| { + })) + .mount("/query", Box::new(|context| { Response::Success(format!( "queries: {:?}", windmark::utilities::queries_from_url(&context.url) )) - }) - .mount("/param/:lang", |context| { + })) + .mount("/param/:lang", Box::new(|context| { Response::Success(format!( "Parameter lang is {}", context.params.get("lang").unwrap() )) - }) - .mount("/names/:first/:last", |context| { + })) + .mount("/names/:first/:last", Box::new(|context| { Response::Success(format!( "{} {}", context.params.get("first").unwrap(), context.params.get("last").unwrap() )) - }) - .mount("/input", |context| { + })) + .mount("/input", Box::new(|context| { if let Some(name) = context.url.query() { Response::Success(format!("Your name is {}!", name)) } else { Response::Input("What is your name?".into()) } - }) - .mount("/sensitive-input", |context| { + })) + .mount("/sensitive-input", Box::new(|context| { if let Some(password) = context.url.query() { Response::Success(format!("Your password is {}!", password)) } else { Response::SensitiveInput("What is your password?".into()) } - }) - .mount("/error", |_| Response::CertificateNotValid("no".into())) - .mount("/redirect", |_| { + })) + .mount("/error", Box::new(|_| Response::CertificateNotValid("no".into()))) + .mount("/redirect", Box::new(|_| { Response::PermanentRedirect("gemini://localhost/test".into()) - }) - .mount("/file", |_| { + })) + .mount("/file", Box::new(|_| { Response::SuccessFile(include_bytes!("../LICENSE")) - }) + })) .run() .await } diff --git a/src/handler.rs b/src/handler.rs index 7e297f8..5377703 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -18,7 +18,8 @@ use crate::{returnable::RouteContext, Response}; -pub type RouteResponse = fn(RouteContext<'_>) -> Response<'_>; +pub type RouteResponse = + Box<dyn FnMut(RouteContext<'_>) -> Response<'_> + Send + Sync>; pub type ErrorResponse = Box< dyn FnMut(crate::returnable::ErrorContext<'_>) -> Response<'_> + Send + Sync, >; @@ -51,10 +51,10 @@ //! windmark::Router::new() //! .set_private_key_file("windmark_private.pem") //! .set_certificate_chain_file("windmark_pair.pem") -//! .mount("/", |_| Response::Success("Hello, World!".into())) -//! .set_error_handler(|_| { +//! .mount("/", Box::new(|_| Response::Success("Hello, World!".into()))) +//! .set_error_handler(Box::new(|_| { //! Response::PermanentFailure("This route does not exist!".into()) -//! }) +//! })) //! .run() //! .await //! } @@ -114,7 +114,7 @@ use crate::{ /// response generation, panics, logging, and more. #[derive(Clone)] pub struct Router { - routes: matchit::Router<RouteResponse>, + routes: matchit::Router<Arc<Mutex<RouteResponse>>>, error_handler: Arc<Mutex<ErrorResponse>>, private_key_file_name: String, certificate_chain_file_name: String, @@ -183,17 +183,24 @@ impl Router { /// use windmark::Response; /// /// windmark::Router::new() - /// .mount("/", |_| Response::Success("This is the index page!".into())) - /// .mount("/test", |_| { - /// Response::Success("This is a test page!".into()) - /// }); + /// .mount( + /// "/", + /// Box::new(|_| Response::Success("This is the index page!".into())), + /// ) + /// .mount( + /// "/test", + /// Box::new(|_| Response::Success("This is a test page!".into())), + /// ); /// ``` /// /// # Panics /// /// if the route cannot be mounted. pub fn mount(&mut self, route: &str, handler: RouteResponse) -> &mut Self { - self.routes.insert(route, handler).unwrap(); + self + .routes + .insert(route, Arc::new(Mutex::new(handler))) + .unwrap(); self } @@ -203,9 +210,9 @@ impl Router { /// # Examples /// /// ```rust - /// windmark::Router::new().set_error_handler(|_| { + /// windmark::Router::new().set_error_handler(Box::new(|_| { /// windmark::Response::Success("You have encountered an error!".into()) - /// }); + /// })); /// ``` pub fn set_error_handler(&mut self, handler: ErrorResponse) -> &mut Self { self.error_handler = Arc::new(Mutex::new(handler)); @@ -218,9 +225,9 @@ impl Router { /// # Examples /// /// ```rust - /// windmark::Router::new().set_header(|context| { + /// windmark::Router::new().set_header(Box::new(|context| { /// format!("This is displayed at the top of {}!", context.url.path()) - /// }); + /// })); /// ``` pub fn set_header(&mut self, handler: Partial) -> &mut Self { self.header = Arc::new(Mutex::new(handler)); @@ -233,9 +240,9 @@ impl Router { /// # Examples /// /// ```rust - /// windmark::Router::new().set_footer(|context| { + /// windmark::Router::new().set_footer(Box::new(|context| { /// format!("This is displayed at the bottom of {}!", context.url.path()) - /// }); + /// })); /// ``` pub fn set_footer(&mut self, handler: Partial) -> &mut Self { self.footer = Arc::new(Mutex::new(handler)); @@ -357,11 +364,11 @@ impl Router { }; content = { to_value_set_status( - (route.value)(RouteContext::new( + (*route.value).lock().unwrap().call_mut((RouteContext::new( stream.get_ref(), &url, &route.params, - )), + ),)), &mut response_status, ) }; @@ -518,12 +525,14 @@ impl Router { /// ```rust /// use log::info; /// - /// windmark::Router::new().set_pre_route_callback(|stream, _url, _| { - /// info!( - /// "accepted connection from {}", - /// stream.peer_addr().unwrap().ip(), - /// ) - /// }); + /// windmark::Router::new().set_pre_route_callback(Box::new( + /// |stream, _url, _| { + /// info!( + /// "accepted connection from {}", + /// stream.peer_addr().unwrap().ip(), + /// ) + /// }, + /// )); /// ``` pub fn set_pre_route_callback(&mut self, callback: Callback) -> &mut Self { self.pre_route_callback = Arc::new(Mutex::new(callback)); @@ -538,12 +547,14 @@ impl Router { /// ```rust /// use log::info; /// - /// windmark::Router::new().set_post_route_callback(|stream, _url, _| { - /// info!( - /// "closed connection from {}", - /// stream.peer_addr().unwrap().ip(), - /// ) - /// }); + /// windmark::Router::new().set_post_route_callback(Box::new( + /// |stream, _url, _| { + /// info!( + /// "closed connection from {}", + /// stream.peer_addr().unwrap().ip(), + /// ) + /// }, + /// )); /// ``` pub fn set_post_route_callback(&mut self, callback: Callback) -> &mut Self { self.post_route_callback = Arc::new(Mutex::new(callback)); @@ -562,12 +573,15 @@ impl Router { /// use windmark::Response; /// /// windmark::Router::new().attach(|r| { - /// r.mount("/module", |_| Response::Success("This is a module!".into())); - /// r.set_error_handler(|_| { + /// r.mount( + /// "/module", + /// Box::new(|_| Response::Success("This is a module!".into())), + /// ); + /// r.set_error_handler(Box::new(|_| { /// Response::NotFound( /// "This error handler has been implemented by a module!".into(), /// ) - /// }); + /// })); /// }); /// ``` pub fn attach<F>(&mut self, mut module: F) -> &mut Self |