diff options
-rw-r--r-- | examples/tutorial01/main.rs | 11 | ||||
-rw-r--r-- | examples/tutorial01/polls/urls.rs | 8 | ||||
-rw-r--r-- | src/contrib/admin/site/urls.rs | 9 | ||||
-rw-r--r-- | src/urls.rs | 59 |
4 files changed, 71 insertions, 16 deletions
diff --git a/examples/tutorial01/main.rs b/examples/tutorial01/main.rs index 4db9897..f99ae7f 100644 --- a/examples/tutorial01/main.rs +++ b/examples/tutorial01/main.rs @@ -1,15 +1,14 @@ use tosin::Settings; use tosin::contrib::admin; -use tosin::http::Filter; -use tosin::urls::{UrlMap, path}; +use tosin::urls::{UrlMap, url_map}; mod polls; fn urls() -> UrlMap { - path!("polls" / ..).and(polls::urls::urls()) - .or(path!("admin" / ..).and(admin::site::urls::urls())) - .unify() - .boxed() + url_map! { + "polls" / ..polls::urls::urls(), + "admin" / ..admin::site::urls::urls(), + } } fn settings() -> Settings { diff --git a/examples/tutorial01/polls/urls.rs b/examples/tutorial01/polls/urls.rs index 184c6f8..04d93cc 100644 --- a/examples/tutorial01/polls/urls.rs +++ b/examples/tutorial01/polls/urls.rs @@ -1,9 +1,9 @@ -use tosin::http::Filter; -use tosin::urls::{UrlMap, path}; +use tosin::urls::{UrlMap, url_map}; use super::views; pub fn urls() -> UrlMap { - path::end().map(views::index) // TODO name: "index" - .boxed() + url_map! { + => views::index, // TODO name: "index" + } } diff --git a/src/contrib/admin/site/urls.rs b/src/contrib/admin/site/urls.rs index ef23d55..d6537bc 100644 --- a/src/contrib/admin/site/urls.rs +++ b/src/contrib/admin/site/urls.rs @@ -1,7 +1,8 @@ -use crate::http::{Filter, Reply}; -use crate::urls::{UrlMap, path}; +use crate::http::Reply; +use crate::urls::{UrlMap, url_map}; pub fn urls() -> UrlMap { - path::end().map(|| Reply::into_response("bruh")) - .boxed() + url_map! { + => || Reply::into_response("bruh"), + } } diff --git a/src/urls.rs b/src/urls.rs index 45720b6..80eba9e 100644 --- a/src/urls.rs +++ b/src/urls.rs @@ -1,5 +1,60 @@ -pub use warp::path; - use crate::http::Response; +pub use crate::url_map; pub type UrlMap = warp::filters::BoxedFilter<(Response,)>; + +#[doc(hidden)] +#[macro_export] +macro_rules! __url_map_inner { + (@root => $view:expr, $($rest:tt)*) => {{ + let chain = $crate::__url_map_inner!(@one => $view); + $crate::__url_map_inner!(chain @rest $($rest)*) + }}; + (@root $head:tt $(/ $tail:tt)* => $view:expr, $($rest:tt)*) => {{ + let chain = $crate::__url_map_inner!(@one $head $(/ $tail)* => $view); + $crate::__url_map_inner!(chain @rest $($rest)*) + }}; + (@root $head:tt $(/ $tail:tt)* $child:expr, $($rest:tt)*) => {{ + let chain = $crate::__url_map_inner!(@one $head $(/ $tail)* $child); + $crate::__url_map_inner!(chain @rest $($rest)*) + }}; + + ($chain:ident @rest => $view:expr, $($rest:tt)*) => {{ + let chain = $chain + .or($crate::__url_map_inner!(@one => $view)) + .unify(); + $crate::__url_map_inner!(chain @rest $($rest)*) + }}; + ($chain:ident @rest $head:tt $(/ $tail:tt)* => $view:expr, $($rest:tt)*) => {{ + let chain = $chain + .or($crate::__url_map_inner!(@one $head $(/ $tail)* => $view)) + .unify(); + $crate::__url_map_inner!(chain @rest $($rest)*) + }}; + ($chain:ident @rest $head:tt $(/ $tail:tt)* $child:expr, $($rest:tt)*) => {{ + let chain = $chain + .or($crate::__url_map_inner!(@one $head $(/ $tail)* $child)) + .unify(); + $crate::__url_map_inner!(chain @rest $($rest)*) + }}; + ($chain:ident @rest) => { $chain }; + + (@one => $view:expr) => { + ::warp::path::end().map($view) + }; + (@one $head:tt $(/ $tail:tt)* => $view:expr) => { + ::warp::path!($head $(/ $tail)*).map($view) + }; + (@one $head:tt $(/ $tail:tt)* $child:expr) => { + ::warp::path!($head $(/ $tail)*).and($child) + }; +} + +#[macro_export] +macro_rules! url_map { + ($($body:tt)*) => {{ + use ::warp::Filter; + $crate::__url_map_inner!(@root $($body)*) + .boxed() + }}; +} |