aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2022-03-27 11:38:41 +0000
committerFuwn <[email protected]>2022-03-27 11:38:41 +0000
commitc60dd3ceda6b818271a48765f676bf3505dcbbeb (patch)
treed4a9a8caa94f259c2fef30e9cafea3d0533451de
parentfeat(handler): fnmut partial (diff)
downloadwindmark-c60dd3ceda6b818271a48765f676bf3505dcbbeb.tar.xz
windmark-c60dd3ceda6b818271a48765f676bf3505dcbbeb.zip
feat(handler): more fnmut
-rw-r--r--README.md6
-rw-r--r--examples/windmark.rs52
-rw-r--r--src/handler.rs3
-rw-r--r--src/lib.rs78
4 files changed, 77 insertions, 62 deletions
diff --git a/README.md b/README.md
index 5d993d9..0472030 100644
--- a/README.md
+++ b/README.md
@@ -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,
>;
diff --git a/src/lib.rs b/src/lib.rs
index 09baf20..4e8592a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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