aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2023-04-03 02:44:25 +0000
committerFuwn <[email protected]>2023-04-03 02:44:25 +0000
commited52d304178d5d37a0af710f06e8fe8eb65b2c24 (patch)
treea1ce35c6a54d576361a6378c3cf59ea60ebc15e1
parentfeat(response): allow multiple languages (diff)
downloadwindmark-ed52d304178d5d37a0af710f06e8fe8eb65b2c24.tar.xz
windmark-ed52d304178d5d37a0af710f06e8fe8eb65b2c24.zip
feat(router): GET RID OF DIRTY BOXES
-rw-r--r--examples/windmark.rs86
-rw-r--r--rust-toolchain.toml2
-rw-r--r--src/handler.rs10
-rw-r--r--src/response/macros.rs20
-rw-r--r--src/router.rs20
5 files changed, 63 insertions, 75 deletions
diff --git a/examples/windmark.rs b/examples/windmark.rs
index 50914f4..c139b55 100644
--- a/examples/windmark.rs
+++ b/examples/windmark.rs
@@ -23,7 +23,7 @@ extern crate log;
use windmark::{
response::Response,
- returnable::CallbackContext,
+ returnable::{CallbackContext, RouteContext},
success,
Router,
};
@@ -102,14 +102,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
"/",
success!("# INDEX\n\nWelcome!\n\n=> /test Test Page\n=> /time Unix Epoch"),
);
- router.mount(
- "/specific-mime",
- Box::new(|_| {
- Response::success("hi".to_string())
- .with_mime("text/plain")
- .clone()
- }),
- );
+ router.mount("/specific-mime", |_| {
+ Response::success("hi".to_string())
+ .with_mime("text/plain")
+ .clone()
+ });
router.mount(
"/ip",
success!(
@@ -154,26 +151,20 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
)
),
);
- router.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?")
- }
- }),
- );
- router.mount(
- "/sensitive-input",
- Box::new(|context| {
- if let Some(password) = context.url.query() {
- Response::success(format!("Your password is {}!", password))
- } else {
- Response::sensitive_input("What is your password?")
- }
- }),
- );
+ router.mount("/input", |context: RouteContext| {
+ if let Some(name) = context.url.query() {
+ Response::success(format!("Your name is {}!", name))
+ } else {
+ Response::input("What is your name?")
+ }
+ });
+ router.mount("/sensitive-input", |context: RouteContext| {
+ if let Some(password) = context.url.query() {
+ Response::success(format!("Your password is {}!", password))
+ } else {
+ Response::sensitive_input("What is your password?")
+ }
+ });
router.mount("/error", windmark::certificate_not_valid!("no"));
router.mount(
"/redirect",
@@ -189,26 +180,23 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
router.mount("/string-file", {
windmark::binary_success!("hi", "text/plain")
});
- router.mount(
- "/secret",
- Box::new(|context| {
- if let Some(certificate) = context.certificate {
- Response::success(format!("Your public key: {}.", {
- (|| -> Result<String, openssl::error::ErrorStack> {
- Ok(format!(
- "{:?}",
- certificate.public_key()?.rsa()?.public_key_to_pem()?
- ))
- })()
- .unwrap_or_else(|_| "Unknown".to_string())
- },))
- } else {
- Response::client_certificate_required(
- "This is a secret route! Identify yourself!",
- )
- }
- }),
- );
+ router.mount("/secret", |context: RouteContext| {
+ if let Some(certificate) = context.certificate {
+ Response::success(format!("Your public key: {}.", {
+ (|| -> Result<String, openssl::error::ErrorStack> {
+ Ok(format!(
+ "{:?}",
+ certificate.public_key()?.rsa()?.public_key_to_pem()?
+ ))
+ })()
+ .unwrap_or_else(|_| "Unknown".to_string())
+ },))
+ } else {
+ Response::client_certificate_required(
+ "This is a secret route! Identify yourself!",
+ )
+ }
+ });
router.run().await
}
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index 292fe49..776ddcd 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -1,2 +1,2 @@
[toolchain]
-channel = "stable"
+channel = "nightly-2023-03-27"
diff --git a/src/handler.rs b/src/handler.rs
index 3429f3b..f22e3b3 100644
--- a/src/handler.rs
+++ b/src/handler.rs
@@ -22,8 +22,14 @@ use crate::{
returnable::{CallbackContext, RouteContext},
};
-pub type RouteResponse =
- Box<dyn FnMut(RouteContext<'_>) -> Response + Send + Sync>;
+pub trait RouteResponse:
+ FnMut(RouteContext<'_>) -> Response + Send + Sync
+{
+}
+
+impl<T> RouteResponse for T where T: FnMut(RouteContext<'_>) -> Response + Send + Sync
+{}
+
pub type ErrorResponse =
Box<dyn FnMut(returnable::ErrorContext<'_>) -> Response + Send + Sync>;
pub type Callback = Box<dyn FnMut(CallbackContext<'_>) + Send + Sync>;
diff --git a/src/response/macros.rs b/src/response/macros.rs
index f49da2d..54e6a8b 100644
--- a/src/response/macros.rs
+++ b/src/response/macros.rs
@@ -23,10 +23,10 @@ macro_rules! response {
#[macro_export]
macro_rules! $name {
($body:expr /* $(,)? */) => {
- ::std::boxed::Box::new(|_| windmark::Response::$name($body))
+ |_: ::windmark::returnable::RouteContext<'_>| ::windmark::Response::$name($body)
};
($context:ident, $body:expr /* $(,)? */) => {
- ::std::boxed::Box::new(|$context| windmark::Response::$name($body))
+ |$context: ::windmark::returnable::RouteContext<'_>| ::windmark::Response::$name($body)
};
}
)*
@@ -57,9 +57,9 @@ response!(certificate_not_valid);
#[macro_export]
macro_rules! binary_success {
($body:expr, $mime:expr) => {
- ::std::boxed::Box::new(|_| {
+ |_: ::windmark::returnable::RouteContext<'_>| {
::windmark::Response::binary_success($body, $mime)
- })
+ }
};
($body:expr) => {{
#[cfg(not(feature = "auto-deduce-mime"))]
@@ -68,19 +68,19 @@ macro_rules! binary_success {
feature to be enabled"
);
- ::std::boxed::Box::new(|_| {
+ |_: ::windmark::returnable::RouteContext<'_>| {
#[cfg(feature = "auto-deduce-mime")]
return ::windmark::Response::binary_success_auto($body);
// Suppress item not found warning
#[cfg(not(feature = "auto-deduce-mime"))]
::windmark::Response::binary_success($body, "application/octet-stream")
- })
+ }
}};
($context:ident, $body:expr, $mime:expr) => {
- ::std::boxed::Box::new(|$context| {
+ |$context: ::windmark::returnable::RouteContext<'_>| {
::windmark::Response::binary_success($body, $mime)
- })
+ }
};
($context:ident, $body:expr) => {{
#[cfg(not(feature = "auto-deduce-mime"))]
@@ -89,13 +89,13 @@ macro_rules! binary_success {
feature to be enabled"
);
- ::std::boxed::Box::new(|$context| {
+ |$context: ::windmark::returnable::RouteContext<'_>| {
#[cfg(feature = "auto-deduce-mime")]
return ::windmark::Response::binary_success_auto($body);
// Suppress item not found warning
#[cfg(not(feature = "auto-deduce-mime"))]
::windmark::Response::binary_success($body, "application/octet-stream")
- })
+ }
}};
}
diff --git a/src/router.rs b/src/router.rs
index b245722..9917923 100644
--- a/src/router.rs
+++ b/src/router.rs
@@ -16,6 +16,8 @@
// Copyright (C) 2022-2022 Fuwn <[email protected]>
// SPDX-License-Identifier: GPL-3.0-only
+#![allow(clippy::significant_drop_tightening)]
+
use std::{
error::Error,
sync::{Arc, Mutex},
@@ -54,7 +56,7 @@ macro_rules! or_error {
/// response generation, panics, logging, and more.
#[derive(Clone)]
pub struct Router {
- routes: matchit::Router<Arc<Mutex<RouteResponse>>>,
+ routes: matchit::Router<Arc<Mutex<Box<dyn RouteResponse>>>>,
error_handler: Arc<Mutex<ErrorResponse>>,
private_key_file_name: String,
ca_file_name: String,
@@ -123,17 +125,9 @@ impl Router {
/// # Examples
///
/// ```rust
- /// use windmark::Response;
- ///
/// windmark::Router::new()
- /// .mount(
- /// "/",
- /// Box::new(|_| Response::success("This is the index page!")),
- /// )
- /// .mount(
- /// "/test",
- /// Box::new(|_| Response::success("This is a test page!")),
- /// );
+ /// .mount("/", |_| windmark::success!("This is the index page!"))
+ /// .mount("/test", |_| windmark::success!("This is a test page!"));
/// ```
///
/// # Panics
@@ -142,11 +136,11 @@ impl Router {
pub fn mount(
&mut self,
route: impl Into<String> + AsRef<str>,
- handler: RouteResponse,
+ handler: impl RouteResponse + 'static,
) -> &mut Self {
self
.routes
- .insert(route.into(), Arc::new(Mutex::new(handler)))
+ .insert(route.into(), Arc::new(Mutex::new(Box::new(handler))))
.unwrap();
self