aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2022-03-27 11:03:29 +0000
committerFuwn <[email protected]>2022-03-27 11:03:29 +0000
commit0b297db77fc297ff3a65d15ced67e2f9b2630c1d (patch)
treeb97c12c015f8fb76a278161680ddeedeb36899bd
parentdocs: add missing dependency (diff)
downloadwindmark-0b297db77fc297ff3a65d15ced67e2f9b2630c1d.tar.xz
windmark-0b297db77fc297ff3a65d15ced67e2f9b2630c1d.zip
feat(error_handle): fnmut closure
-rw-r--r--examples/windmark.rs10
-rw-r--r--src/handler.rs5
-rw-r--r--src/lib.rs25
3 files changed, 28 insertions, 12 deletions
diff --git a/examples/windmark.rs b/examples/windmark.rs
index 6ceeaf7..a5bfc9a 100644
--- a/examples/windmark.rs
+++ b/examples/windmark.rs
@@ -25,11 +25,19 @@ use windmark::Response;
#[windmark::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
+ let mut error_count = 0;
+
windmark::Router::new()
.set_private_key_file("windmark_private.pem")
.set_certificate_chain_file("windmark_pair.pem")
.enable_default_logger(true)
- .set_error_handler(|_| Response::PermanentFailure("error...".to_string()))
+ .set_error_handler(Box::new(move |_| {
+ error_count += 1;
+
+ println!("{} errors so far", error_count);
+
+ Response::PermanentFailure("e".into())
+ }))
.attach(|r| {
r.mount("/module", |_| Response::Success("This is a module!".into()));
})
diff --git a/src/handler.rs b/src/handler.rs
index 071926c..f854aea 100644
--- a/src/handler.rs
+++ b/src/handler.rs
@@ -19,8 +19,9 @@
use crate::{returnable::RouteContext, Response};
pub type RouteResponse = fn(RouteContext<'_>) -> Response<'_>;
-pub type ErrorResponse =
- fn(crate::returnable::ErrorContext<'_>) -> Response<'_>;
+pub type ErrorResponse = Box<
+ dyn FnMut(crate::returnable::ErrorContext<'_>) -> Response<'_> + Send + Sync,
+>;
pub type Callback =
fn(&tokio::net::TcpStream, &url::Url, Option<&matchit::Params<'_, '_>>);
pub type Partial = fn(RouteContext<'_>) -> String;
diff --git a/src/lib.rs b/src/lib.rs
index 0d2b229..68e6ffe 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -70,7 +70,7 @@
//! This project is licensed with the
//! [GNU General Public License v3.0](https://github.com/gemrest/windmark/blob/main/LICENSE).
-#![feature(once_cell)]
+#![feature(once_cell, fn_traits)]
#![deny(
warnings,
nonstandard_style,
@@ -90,7 +90,10 @@ pub mod utilities;
#[macro_use]
extern crate log;
-use std::{error::Error, sync::Arc};
+use std::{
+ error::Error,
+ sync::{Arc, Mutex},
+};
use openssl::ssl::{self, SslAcceptor, SslMethod};
pub use response::Response;
@@ -112,7 +115,7 @@ use crate::{
#[derive(Clone)]
pub struct Router {
routes: matchit::Router<RouteResponse>,
- error_handler: ErrorResponse,
+ error_handler: Arc<Mutex<ErrorResponse>>,
private_key_file_name: String,
certificate_chain_file_name: String,
header: Partial,
@@ -205,7 +208,7 @@ impl Router {
/// });
/// ```
pub fn set_error_handler(&mut self, handler: ErrorResponse) -> &mut Self {
- self.error_handler = handler;
+ self.error_handler = Arc::new(Mutex::new(handler));
self
}
@@ -273,7 +276,7 @@ impl Router {
match stream {
Ok(stream) => {
let acceptor = acceptor.clone();
- let self_clone = self.clone();
+ let mut self_clone = self.clone();
tokio::spawn(async move {
match tokio_openssl::accept(&acceptor, stream).await {
@@ -293,8 +296,9 @@ impl Router {
Ok(())
}
+ #[allow(clippy::too_many_lines)]
async fn handle(
- &self,
+ &mut self,
stream: &mut tokio_openssl::SslStream<tokio::net::TcpStream>,
) -> Result<(), Box<dyn std::error::Error>> {
let mut buffer = [0u8; 1024];
@@ -363,7 +367,10 @@ impl Router {
};
} else {
content = to_value_set_status(
- (self.error_handler)(ErrorContext::new(stream.get_ref(), &url)),
+ (*self.error_handler)
+ .lock()
+ .unwrap()
+ .call_mut((ErrorContext::new(stream.get_ref(), &url),)),
&mut response_status,
);
}
@@ -600,11 +607,11 @@ impl Default for Router {
fn default() -> Self {
Self {
routes: matchit::Router::new(),
- error_handler: |_| {
+ error_handler: Arc::new(Mutex::new(Box::new(|_| {
Response::NotFound(
"This capsule has not implemented an error handler...".to_string(),
)
- },
+ }))),
private_key_file_name: "".to_string(),
certificate_chain_file_name: "".to_string(),
header: |_| "".to_string(),