Build method to AppBuilder that returns a Router of all settings.
Updated router! to allow for generic types
This commit is contained in:
parent
eeab1257e3
commit
93fe1e0cda
@ -44,6 +44,13 @@ impl AppBuilder {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn from_router(router: Router) -> Self {
|
||||
Self {
|
||||
router,
|
||||
..Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn route(mut self, route: Router) -> Self {
|
||||
self.router = self.router.merge(route);
|
||||
self
|
||||
@ -106,6 +113,23 @@ impl AppBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Creates the app with the given options.
|
||||
/// This method is useful for testing purposes.
|
||||
/// Options used for configuring the listener will be lost.
|
||||
pub fn build(self) -> Router {
|
||||
let mut app = self.router;
|
||||
if let Some(cors) = self.cors {
|
||||
app = app.layer(cors);
|
||||
}
|
||||
app.layer(
|
||||
self.tracing.unwrap_or(
|
||||
TraceLayer::new_for_http()
|
||||
.make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO))
|
||||
.on_response(trace::DefaultOnResponse::new().level(Level::INFO)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
/// Build the app and start the server
|
||||
/// # Default Options
|
||||
/// - IP == 0.0.0.0
|
||||
@ -118,10 +142,10 @@ impl AppBuilder {
|
||||
let listener = self.listener().await?;
|
||||
|
||||
if self.normalize_path.unwrap_or(true) {
|
||||
let app = NormalizePathLayer::trim_trailing_slash().layer(self.create_app());
|
||||
let app = NormalizePathLayer::trim_trailing_slash().layer(self.build());
|
||||
axum::serve(listener, ServiceExt::<Request>::into_make_service(app)).await?;
|
||||
} else {
|
||||
let app = self.create_app();
|
||||
let app = self.build();
|
||||
axum::serve(listener, app.into_make_service()).await?;
|
||||
};
|
||||
Ok(())
|
||||
@ -132,20 +156,6 @@ impl AppBuilder {
|
||||
info!("Initializing server on: {addr}");
|
||||
TcpListener::bind(&addr).await
|
||||
}
|
||||
|
||||
fn create_app(self) -> Router {
|
||||
let mut app = self.router;
|
||||
if let Some(cors) = self.cors {
|
||||
app = app.layer(cors);
|
||||
}
|
||||
app.layer(
|
||||
self.tracing.unwrap_or(
|
||||
TraceLayer::new_for_http()
|
||||
.make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO))
|
||||
.on_response(trace::DefaultOnResponse::new().level(Level::INFO)),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt_trace() -> Result<(), String> {
|
||||
|
@ -29,12 +29,28 @@ macro_rules! router {
|
||||
$body
|
||||
}
|
||||
};
|
||||
($body:expr; $state:ident: $($bound:tt),*) => {
|
||||
pub fn router<$state: $($bound+)* 'static>() -> axum::Router<$state> {
|
||||
$body
|
||||
}
|
||||
};
|
||||
($body:expr; $generic:ident: $($bound:tt),* -> $state:ty) => {
|
||||
pub fn router<$generic: $($bound+)* 'static>() -> axum::Router<$state<$generic>> {
|
||||
$body
|
||||
}
|
||||
};
|
||||
($route:expr, $router:expr) => {
|
||||
router!(axum::Router::new().nest($route, $router));
|
||||
};
|
||||
($route:expr, $router:expr, $state:ty) => {
|
||||
router!(axum::Router::new().nest($route, $router); $state);
|
||||
};
|
||||
($route:expr, $router:expr, $state:ident: $($bound:tt),*) => {
|
||||
router!(axum::Router::new().nest($route, $router); $state: $($bound),*);
|
||||
};
|
||||
($route:expr, $router:expr, $generic:ident: $($bound:tt),* -> $state:ty) => {
|
||||
router!(axum::Router::new().nest($route, $router); $generic: $($bound),* -> $state);
|
||||
};
|
||||
($($method:ident $route:expr => $func:expr),* $(,)?) => {
|
||||
router!($crate::routes!($($method $route => $func),*));
|
||||
};
|
||||
@ -112,6 +128,18 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_router_with_generic_state() {
|
||||
router!(
|
||||
"/simplify",
|
||||
routes!(
|
||||
get "/:exp" => || async {},
|
||||
get "/table/:exp" => |_state: State<T>| async {}
|
||||
),
|
||||
T: Clone, Send, Sync
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_routes() {
|
||||
let _router: Router = routes!(
|
||||
|
Loading…
x
Reference in New Issue
Block a user