Skip to content

Commit

Permalink
feat: support for async middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
elcharitas committed Sep 28, 2024
1 parent fa2a940 commit e31c545
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 31 deletions.
2 changes: 1 addition & 1 deletion crates/macros/src/common/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub(crate) fn controller_macro(args: TokenStream, input: TokenStream) -> TokenSt
quote! {
let mut middleware = #m::default();
middleware.inject(cx);
middleware.handle(cx, res);
middleware.handle(cx, res).await;
}
})
.collect();
Expand Down
8 changes: 4 additions & 4 deletions crates/shared/src/core/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::sync::Arc;
use super::RouteHandler;
use crate::{
server::{context::AppState, Method, Middlewares, NgynContext, NgynResponse, Routes},
traits::{NgynController, NgynInterpreter, NgynMiddleware, NgynModule},
traits::{Middleware, NgynController, NgynInterpreter, NgynMiddleware, NgynModule},
};

#[derive(Default)]
Expand Down Expand Up @@ -48,7 +48,7 @@ impl PlatformData {

// trigger global middlewares
for middleware in &self.middlewares {
middleware.handle(&mut cx, &mut res);
middleware.run(&mut cx, &mut res).await;
}

// execute controlled route if it is handled
Expand Down Expand Up @@ -96,7 +96,7 @@ impl PlatformData {
/// ### Arguments
///
/// * `middleware` - The middleware to add.
pub(self) fn add_middleware(&mut self, middleware: Box<dyn NgynMiddleware>) {
pub(self) fn add_middleware(&mut self, middleware: Box<dyn Middleware>) {
self.middlewares.push(middleware);
}

Expand Down Expand Up @@ -272,7 +272,7 @@ mod tests {
}

impl NgynMiddleware for MockMiddleware {
fn handle(&self, _cx: &mut NgynContext, _res: &mut NgynResponse) {}
async fn handle(&self, _cx: &mut NgynContext, _res: &mut NgynResponse) {}
}

struct MockInterpreter;
Expand Down
23 changes: 1 addition & 22 deletions crates/shared/src/core/handler.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use std::{future::Future, pin::Pin};

use crate::{
server::{NgynContext, NgynResponse, ToBytes},
traits::NgynMiddleware,
};
use crate::server::{NgynContext, NgynResponse, ToBytes};

/// Represents a handler function that takes in a mutable reference to `NgynContext` and `NgynResponse`.
pub type Handler = dyn Fn(&mut NgynContext, &mut NgynResponse) + Send + Sync + 'static;
Expand Down Expand Up @@ -76,21 +73,3 @@ pub fn async_handler<S: ToBytes + 'static, Fut: Future<Output = S> + Send + 'sta
})
})
}

pub fn middleware<M: NgynMiddleware + 'static>(middleware: M) -> Box<Handler> {
Box::new(move |ctx: &mut NgynContext, res: &mut NgynResponse| {
middleware.handle(ctx, res);
})
}

pub fn with_middlewares<M: NgynMiddleware + 'static>(
middleware: Vec<M>,
handler: Box<Handler>,
) -> impl Into<RouteHandler> {
Box::new(move |ctx: &mut NgynContext, res: &mut NgynResponse| {
for m in &middleware {
m.handle(ctx, res);
}
handler(ctx, res);
})
}
2 changes: 1 addition & 1 deletion crates/shared/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ pub type NgynRequest = http::Request<Vec<u8>>;
pub type NgynResponse = http::Response<Full<Bytes>>;

pub(crate) type Routes = Vec<(String, Option<Method>, Box<crate::core::RouteHandler>)>;
pub(crate) type Middlewares = Vec<Box<dyn crate::traits::NgynMiddleware>>;
pub(crate) type Middlewares = Vec<Box<dyn crate::traits::Middleware>>;
29 changes: 28 additions & 1 deletion crates/shared/src/traits/middleware_trait.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::{future::Future, pin::Pin};

use crate::{
server::{NgynContext, NgynResponse},
traits::NgynInjectable,
Expand Down Expand Up @@ -36,5 +38,30 @@ use crate::{
/// ```
pub trait NgynMiddleware: NgynInjectable + Sync {
/// Handles the request.
fn handle(&self, cx: &mut NgynContext, res: &mut NgynResponse);
#[allow(async_fn_in_trait)]
fn handle(
&self,
cx: &mut NgynContext,
res: &mut NgynResponse,
) -> impl std::future::Future<Output = ()> + Send;
}

pub(crate) trait Middleware: NgynInjectable + Sync {
fn run<'a>(
&'a self,
_cx: &'a mut NgynContext,
_res: &'a mut NgynResponse,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {})
}
}

impl<T: NgynMiddleware> Middleware for T {
fn run<'a>(
&'a self,
cx: &'a mut NgynContext,
res: &'a mut NgynResponse,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(self.handle(cx, res))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use serde_json::json;
pub struct NotFoundMiddleware;

impl NgynMiddleware for NotFoundMiddleware {
fn handle(&self, cx: &mut NgynContext, res: &mut NgynResponse) {
async fn handle(&self, cx: &mut NgynContext, res: &mut NgynResponse) {
if cx.is_valid_route() {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion examples/weather_app/src/middlewares/test_middleware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ngyn::prelude::*;
pub struct TestMiddleware;

impl NgynMiddleware for TestMiddleware {
fn handle(&self, _cx: &mut NgynContext, _response: &mut NgynResponse) {
async fn handle(&self, _cx: &mut NgynContext, _response: &mut NgynResponse) {
println!("middleware works");
}
}

0 comments on commit e31c545

Please sign in to comment.