Skip to content

Commit

Permalink
feat: grouped roputes and router (#215)
Browse files Browse the repository at this point in the history
  • Loading branch information
elcharitas authored Dec 14, 2024
1 parent 3134da9 commit c332952
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 34 deletions.
2 changes: 1 addition & 1 deletion crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub mod prelude {
pub use ngyn_hyper::HyperApplication;
pub use ngyn_shared::{
core::{
engine::{NgynEngine, NgynHttpEngine},
engine::{NgynEngine, NgynHttpEngine, RouteInstance},
handler::*,
},
server::{
Expand Down
84 changes: 53 additions & 31 deletions crates/shared/src/core/engine.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bytes::Bytes;
use http::Request;
use matchit::{Match, Router};
use matchit::{Match, MergeError, Router};
use std::sync::Arc;

use super::handler::{handler, RouteHandler};
Expand All @@ -9,6 +9,17 @@ use crate::{
Middleware, NgynMiddleware,
};

#[derive(Default)]
pub struct GroupRouter {
router: Router<RouteHandler>,
}

impl RouteInstance for GroupRouter {
fn router_mut(&mut self) -> &mut Router<RouteHandler> {
&mut self.router
}
}

#[derive(Default)]
pub struct PlatformData {
router: Router<RouteHandler>,
Expand Down Expand Up @@ -69,14 +80,30 @@ impl PlatformData {
cx.response
}

/// Adds a middleware to the platform data.
///
/// ### Arguments
///
/// * `middleware` - The middleware to add.
pub(self) fn add_middleware(&mut self, middleware: Box<dyn Middleware>) {
self.middlewares.push(middleware);
}
}

pub trait NgynPlatform: Default {
fn data_mut(&mut self) -> &mut PlatformData;
}

pub trait RouteInstance {
fn router_mut(&mut self) -> &mut Router<RouteHandler>;
/// Adds a route to the platform data.
///
/// ### Arguments
///
/// * `path` - The path of the route.
/// * `method` - The HTTP method of the route.
/// * `handler` - The handler function for the route.
pub fn add_route(&mut self, path: &str, method: Option<Method>, handler: RouteHandler) {
fn add_route(&mut self, path: &str, method: Option<Method>, handler: RouteHandler) {
let method = method
.map(|method| method.to_string())
.unwrap_or_else(|| "{METHOD}".to_string());
Expand All @@ -87,28 +114,9 @@ impl PlatformData {
method + "/" + path
};

self.router.insert(route, handler).unwrap();
}

/// Adds a middleware to the platform data.
///
/// ### Arguments
///
/// * `middleware` - The middleware to add.
pub(self) fn add_middleware(&mut self, middleware: Box<dyn Middleware>) {
self.middlewares.push(middleware);
self.router_mut().insert(route, handler).unwrap();
}
}

pub trait NgynPlatform: Default {
fn data_mut(&mut self) -> &mut PlatformData;
}

pub trait NgynHttpPlatform: Default {
fn data_mut(&mut self) -> &mut PlatformData;
}

pub trait NgynHttpEngine: NgynEngine {
/// Adds a route to the application.
///
/// ### Arguments
Expand All @@ -128,8 +136,7 @@ pub trait NgynHttpEngine: NgynEngine {
/// engine.route('/', Method::GET, Box::new(|_, _| {}));
/// ```
fn route(&mut self, path: &str, method: Method, handler: impl Into<RouteHandler>) {
self.data_mut()
.add_route(path, Some(method), handler.into());
self.add_route(path, Some(method), handler.into());
}

/// Adds a new route to the `NgynApplication` with the `Method::Get`.
Expand Down Expand Up @@ -161,7 +168,13 @@ pub trait NgynHttpEngine: NgynEngine {
fn head(&mut self, path: &str, handler: impl Into<RouteHandler>) {
self.route(path, Method::HEAD, handler.into())
}
}

pub trait NgynHttpPlatform: Default {
fn data_mut(&mut self) -> &mut PlatformData;
}

pub trait NgynHttpEngine: NgynPlatform {
/// Sets up static file routes.
///
/// This is great for apps tha would want to output files in a specific folder.
Expand Down Expand Up @@ -192,7 +205,15 @@ pub trait NgynHttpEngine: NgynEngine {

pub trait NgynEngine: NgynPlatform {
fn any(&mut self, path: &str, handler: impl Into<RouteHandler>) {
self.data_mut().add_route(path, None, handler.into());
self.add_route(path, None, handler.into());
}

fn group(&mut self, registry: impl Fn(&mut GroupRouter)) -> Result<(), MergeError> {
let mut group = GroupRouter {
router: Router::<RouteHandler>::new(),
};
registry(&mut group);
self.data_mut().router.merge(group.router)
}

/// Adds a middleware to the application.
Expand Down Expand Up @@ -221,6 +242,11 @@ impl<T: NgynHttpPlatform> NgynPlatform for T {
}

impl<T: NgynPlatform> NgynEngine for T {}
impl<T: NgynPlatform> RouteInstance for T {
fn router_mut(&mut self) -> &mut Router<RouteHandler> {
&mut self.data_mut().router
}
}
impl<T: NgynHttpPlatform> NgynHttpEngine for T {}

#[cfg(test)]
Expand Down Expand Up @@ -316,9 +342,7 @@ mod tests {
async fn test_respond_with_route_handler() {
let mut engine = MockEngine::default();
let handler: Box<Handler> = Box::new(|_| {});
engine
.data_mut()
.add_route("/test", Some(Method::GET), RouteHandler::Sync(handler));
engine.add_route("/test", Some(Method::GET), RouteHandler::Sync(handler));

let req = Request::builder()
.method(Method::GET)
Expand Down Expand Up @@ -369,9 +393,7 @@ mod tests {
async fn test_add_route() {
let mut engine = MockEngine::default();
let handler: Box<Handler> = Box::new(|_| {});
engine
.data_mut()
.add_route("/test", Some(Method::GET), RouteHandler::Sync(handler));
engine.add_route("/test", Some(Method::GET), RouteHandler::Sync(handler));

assert!(engine.data.router.at("GET/test").is_ok());
}
Expand Down
1 change: 1 addition & 0 deletions crates/swagger/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use ngyn::shared::core::engine::RouteInstance;
use ngyn::shared::{
core::{
engine::{NgynHttpEngine, PlatformData},
Expand Down
4 changes: 2 additions & 2 deletions crates/ws/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::fmt;
use ngyn_shared::core::engine::{NgynPlatform, PlatformData};
use ngyn_shared::core::engine::{NgynPlatform, PlatformData, RouteInstance};
use ngyn_shared::core::handler::RouteHandler;
use ngyn_shared::server::response::ReadBytes;
use ngyn_shared::server::NgynRequest;
Expand All @@ -25,7 +25,7 @@ impl NgynPlatform for WebsocketApplication {
impl WebsocketApplication {
/// add a route to handle
pub fn route(&mut self, path: &str, handler: impl Into<RouteHandler>) {
self.data_mut().add_route(path, None, handler.into());
self.add_route(path, None, handler.into());
}

// Broadcast message to all connected clients
Expand Down

0 comments on commit c332952

Please sign in to comment.