aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/tutorial01/main.rs11
-rw-r--r--examples/tutorial01/polls/urls.rs8
-rw-r--r--src/contrib/admin/site/urls.rs9
-rw-r--r--src/urls.rs59
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()
+ }};
+}