aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-07-08 04:26:23 +0000
committerFuwn <[email protected]>2025-07-08 04:26:23 +0000
commit215d8529e35231f341d8384dd1eb810f0f07bdb1 (patch)
tree138e4bcafc79e3c2718ec908d82c9332450739f3
parentrefactor(router): Manually implement trailing slash clipper (diff)
downloadwindmark-215d8529e35231f341d8384dd1eb810f0f07bdb1.tar.xz
windmark-215d8529e35231f341d8384dd1eb810f0f07bdb1.zip
feat(router): Add options system
-rw-r--r--examples/fix_path.rs2
-rw-r--r--src/lib.rs1
-rw-r--r--src/router.rs71
-rw-r--r--src/router_option.rs6
4 files changed, 67 insertions, 13 deletions
diff --git a/examples/fix_path.rs b/examples/fix_path.rs
index fe8fb2c..e92376c 100644
--- a/examples/fix_path.rs
+++ b/examples/fix_path.rs
@@ -22,7 +22,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
windmark::router::Router::new()
.set_private_key_file("windmark_private.pem")
.set_certificate_file("windmark_public.pem")
- .set_fix_path(true)
+ .add_options(&[windmark::router_option::RouterOption::TrimTrailingSlashes])
.mount(
"/close",
windmark::success!("Visit '/close/'; you should be close enough!"),
diff --git a/src/lib.rs b/src/lib.rs
index 968c9a9..66232c8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -36,6 +36,7 @@ pub mod module;
pub mod prelude;
pub mod response;
pub mod router;
+pub mod router_option;
pub mod utilities;
#[macro_use]
diff --git a/src/router.rs b/src/router.rs
index a5c0833..7584401 100644
--- a/src/router.rs
+++ b/src/router.rs
@@ -18,6 +18,7 @@
#![allow(clippy::significant_drop_tightening)]
use std::{
+ collections::HashSet,
error::Error,
fmt::Write,
future::IntoFuture,
@@ -49,6 +50,7 @@ use crate::{
},
module::{AsyncModule, Module},
response::Response,
+ router_option::RouterOption,
utilities,
};
@@ -107,7 +109,7 @@ pub struct Router {
port: i32,
async_modules: Arc<AsyncMutex<Vec<Box<dyn AsyncModule + Send>>>>,
modules: Arc<Mutex<Vec<Box<dyn Module + Send>>>>,
- fix_path: bool,
+ options: HashSet<RouterOption>,
listener_address: String,
}
@@ -419,11 +421,12 @@ impl Router {
url.set_path("/");
}
- let fixed_path = if self.fix_path {
- utilities::normalize_path_slashes(url.path())
- } else {
- url.path().to_string()
- };
+ let fixed_path =
+ if self.options.contains(&RouterOption::TrimTrailingSlashes) {
+ utilities::normalize_path_slashes(url.path())
+ } else {
+ url.path().to_string()
+ };
let route = &mut self.routes.at(&fixed_path);
let peer_certificate = stream.ssl().peer_certificate();
let hook_context = HookContext::new(
@@ -967,16 +970,60 @@ impl Router {
self
}
- /// Performs a case-insensitive lookup of routes, using the case corrected
- /// path if successful. Missing/ extra trailing slashes are also corrected.
+ /// Add optional features to the router
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use windmark::router_option::RouterOption;
+ ///
+ /// windmark::router::Router::new()
+ /// .add_options(&[RouterOption::TrimTrailingSlashes]);
+ /// ```
+ pub fn add_options(&mut self, options: &[RouterOption]) -> &mut Self {
+ for option in options {
+ self.options.insert(*option);
+ }
+
+ self
+ }
+
+ /// Toggle optional features for the router
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use windmark::router_option::RouterOption;
+ ///
+ /// windmark::router::Router::new()
+ /// .toggle_options(&[RouterOption::TrimTrailingSlashes]);
+ /// ```
+ pub fn toggle_options(&mut self, options: &[RouterOption]) -> &mut Self {
+ for option in options {
+ if self.options.contains(option) {
+ self.options.remove(option);
+ } else {
+ self.options.insert(*option);
+ }
+ }
+
+ self
+ }
+
+ /// Remove optional features from the router
///
/// # Examples
///
/// ```rust
- /// windmark::router::Router::new().set_fix_path(true);
+ /// use windmark::router_option::RouterOption;
+ ///
+ /// windmark::router::Router::new()
+ /// .remove_options(&[RouterOption::TrimTrailingSlashes]);
/// ```
- pub const fn set_fix_path(&mut self, fix_path: bool) -> &mut Self {
- self.fix_path = fix_path;
+ pub fn remove_options(&mut self, options: &[RouterOption]) -> &mut Self {
+ for option in options {
+ self.options.remove(option);
+ }
self
}
@@ -1031,7 +1078,7 @@ impl Default for Router {
port: 1965,
modules: Arc::new(Mutex::new(vec![])),
async_modules: Arc::new(AsyncMutex::new(vec![])),
- fix_path: false,
+ options: HashSet::new(),
private_key_content: None,
certificate_content: None,
listener_address: "0.0.0.0".to_string(),
diff --git a/src/router_option.rs b/src/router_option.rs
new file mode 100644
index 0000000..c99f3ab
--- /dev/null
+++ b/src/router_option.rs
@@ -0,0 +1,6 @@
+/// Options that can be set for the `Router`
+#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
+pub enum RouterOption {
+ /// Trim trailing slashes from the URL path
+ TrimTrailingSlashes,
+}