routerify/router/
builder.rs

1use crate::constants;
2use crate::data_map::{DataMap, ScopedDataMap};
3use crate::middleware::{Middleware, PostMiddleware, PreMiddleware};
4use crate::route::Route;
5use crate::router::Router;
6use crate::router::{ErrHandler, ErrHandlerWithInfo, ErrHandlerWithoutInfo};
7use crate::types::RequestInfo;
8use hyper::{body::HttpBody, Method, Request, Response};
9use std::collections::HashMap;
10use std::future::Future;
11use std::sync::Arc;
12
13/// Builder for the [Router](./struct.Router.html) type.
14///
15/// This `RouterBuilder<B, E>` type accepts two type parameters: `B` and `E`.
16///
17/// * The `B` represents the response body type which will be used by route handlers and the middlewares and this body type must implement
18///   the [HttpBody](https://docs.rs/hyper/0.14.4/hyper/body/trait.HttpBody.html) trait. For an instance, `B` could be [hyper::Body](https://docs.rs/hyper/0.14.4/hyper/body/struct.Body.html)
19///   type.
20/// * The `E` represents any error type which will be used by route handlers and the middlewares. This error type must implement the [std::error::Error](https://doc.rust-lang.org/std/error/trait.Error.html).
21///
22/// # Examples
23///
24/// ```no_run
25/// use routerify::{Router, Middleware};
26/// use hyper::{Response, Request, Body};
27///
28/// async fn home_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
29///     Ok(Response::new(Body::from("home")))
30/// }
31///
32/// async fn upload_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
33///     Ok(Response::new(Body::from("upload")))
34/// }
35///
36/// async fn some_pre_middleware_handler(req: Request<Body>) -> Result<Request<Body>, hyper::Error> {
37///     Ok(req)
38/// }
39///
40/// # fn run() -> Router<Body, hyper::Error> {
41/// // Use Router::builder() method to create a new RouterBuilder instance.
42/// // We will use hyper::Body as response body type and hyper::Error as error type.
43/// let router: Router<Body, hyper::Error> = Router::builder()
44///     .get("/", home_handler)
45///     .post("/upload", upload_handler)
46///     .middleware(Middleware::pre(some_pre_middleware_handler))
47///     .build()
48///     .unwrap();
49/// # router
50/// # }
51/// # run();
52/// ```
53pub struct RouterBuilder<B, E> {
54    inner: crate::Result<BuilderInner<B, E>>,
55}
56
57struct BuilderInner<B, E> {
58    pre_middlewares: Vec<PreMiddleware<E>>,
59    routes: Vec<Route<B, E>>,
60    post_middlewares: Vec<PostMiddleware<B, E>>,
61    data_maps: HashMap<String, Vec<DataMap>>,
62    err_handler: Option<ErrHandler<B>>,
63}
64
65impl<B: HttpBody + Send + Sync + 'static, E: Into<Box<dyn std::error::Error + Send + Sync>> + 'static>
66    RouterBuilder<B, E>
67{
68    /// Creates a new `RouterBuilder` instance with default options.
69    pub fn new() -> RouterBuilder<B, E> {
70        RouterBuilder::default()
71    }
72
73    /// Creates a new [Router](./struct.Router.html) instance from the added configuration.
74    pub fn build(self) -> crate::Result<Router<B, E>> {
75        self.inner.and_then(|inner| {
76            let scoped_data_maps = inner
77                .data_maps
78                .into_iter()
79                .map(|(path, data_map_arr)| {
80                    data_map_arr
81                        .into_iter()
82                        .map(|data_map| ScopedDataMap::new(path.clone(), Arc::new(data_map)))
83                        .collect::<Vec<crate::Result<ScopedDataMap>>>()
84                })
85                .flatten()
86                .collect::<Result<Vec<ScopedDataMap>, crate::RouteError>>()?;
87
88            Ok(Router::new(
89                inner.pre_middlewares,
90                inner.routes,
91                inner.post_middlewares,
92                scoped_data_maps,
93                inner.err_handler,
94            ))
95        })
96    }
97
98    fn and_then<F>(self, func: F) -> Self
99    where
100        F: FnOnce(BuilderInner<B, E>) -> crate::Result<BuilderInner<B, E>>,
101    {
102        RouterBuilder {
103            inner: self.inner.and_then(func),
104        }
105    }
106}
107
108impl<B: HttpBody + Send + Sync + 'static, E: Into<Box<dyn std::error::Error + Send + Sync>> + 'static>
109    RouterBuilder<B, E>
110{
111    /// Adds a new route with `GET` method and the handler at the specified path.
112    ///
113    /// # Examples
114    ///
115    /// ```
116    /// use routerify::Router;
117    /// use hyper::{Response, Request, Body};
118    ///
119    /// async fn home_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
120    ///     Ok(Response::new(Body::from("home")))
121    /// }
122    ///
123    /// # fn run() -> Router<Body, hyper::Error> {
124    /// let router = Router::builder()
125    ///     .get("/", home_handler)
126    ///     .build()
127    ///     .unwrap();
128    /// # router
129    /// # }
130    /// # run();
131    /// ```
132    pub fn get<P, H, R>(self, path: P, handler: H) -> Self
133    where
134        P: Into<String>,
135        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
136        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
137    {
138        self.add(path, vec![Method::GET], handler)
139    }
140
141    /// Adds a new route with `GET` and `HEAD` methods and the handler at the specified path.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// use routerify::Router;
147    /// use hyper::{Response, Request, Body};
148    ///
149    /// async fn home_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
150    ///     Ok(Response::new(Body::from("home")))
151    /// }
152    ///
153    /// # fn run() -> Router<Body, hyper::Error> {
154    /// let router = Router::builder()
155    ///     .get_or_head("/", home_handler)
156    ///     .build()
157    ///     .unwrap();
158    /// # router
159    /// # }
160    /// # run();
161    /// ```
162    pub fn get_or_head<P, H, R>(self, path: P, handler: H) -> Self
163    where
164        P: Into<String>,
165        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
166        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
167    {
168        self.add(path, vec![Method::GET, Method::HEAD], handler)
169    }
170
171    /// Adds a new route with `POST` method and the handler at the specified path.
172    ///
173    /// # Examples
174    ///
175    /// ```
176    /// use routerify::Router;
177    /// use hyper::{Response, Request, Body};
178    ///
179    /// async fn file_upload_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
180    ///     Ok(Response::new(Body::from("File uploader")))
181    /// }
182    ///
183    /// # fn run() -> Router<Body, hyper::Error> {
184    /// let router = Router::builder()
185    ///     .post("/upload", file_upload_handler)
186    ///     .build()
187    ///     .unwrap();
188    /// # router
189    /// # }
190    /// # run();
191    /// ```
192    pub fn post<P, H, R>(self, path: P, handler: H) -> Self
193    where
194        P: Into<String>,
195        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
196        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
197    {
198        self.add(path, vec![Method::POST], handler)
199    }
200
201    /// Adds a new route with `PUT` method and the handler at the specified path.
202    ///
203    /// # Examples
204    ///
205    /// ```
206    /// use routerify::Router;
207    /// use hyper::{Response, Request, Body};
208    ///
209    /// async fn file_upload_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
210    ///     Ok(Response::new(Body::from("File uploader")))
211    /// }
212    ///
213    /// # fn run() -> Router<Body, hyper::Error> {
214    /// let router = Router::builder()
215    ///     .put("/upload", file_upload_handler)
216    ///     .build()
217    ///     .unwrap();
218    /// # router
219    /// # }
220    /// # run();
221    /// ```
222    pub fn put<P, H, R>(self, path: P, handler: H) -> Self
223    where
224        P: Into<String>,
225        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
226        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
227    {
228        self.add(path, vec![Method::PUT], handler)
229    }
230
231    /// Adds a new route with `DELETE` method and the handler at the specified path.
232    ///
233    /// # Examples
234    ///
235    /// ```
236    /// use routerify::Router;
237    /// use hyper::{Response, Request, Body};
238    ///
239    /// async fn delete_file_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
240    ///     Ok(Response::new(Body::from("Delete file")))
241    /// }
242    ///
243    /// # fn run() -> Router<Body, hyper::Error> {
244    /// let router = Router::builder()
245    ///     .delete("/delete-file", delete_file_handler)
246    ///     .build()
247    ///     .unwrap();
248    /// # router
249    /// # }
250    /// # run();
251    /// ```
252    pub fn delete<P, H, R>(self, path: P, handler: H) -> Self
253    where
254        P: Into<String>,
255        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
256        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
257    {
258        self.add(path, vec![Method::DELETE], handler)
259    }
260
261    /// Adds a new route with `HEAD` method and the handler at the specified path.
262    ///
263    /// # Examples
264    ///
265    /// ```
266    /// use routerify::Router;
267    /// use hyper::{Response, Request, Body};
268    ///
269    /// async fn a_head_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
270    ///     Ok(Response::new(Body::empty()))
271    /// }
272    ///
273    /// # fn run() -> Router<Body, hyper::Error> {
274    /// let router = Router::builder()
275    ///     .head("/fetch-data", a_head_handler)
276    ///     .build()
277    ///     .unwrap();
278    /// # router
279    /// # }
280    /// # run();
281    /// ```
282    pub fn head<P, H, R>(self, path: P, handler: H) -> Self
283    where
284        P: Into<String>,
285        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
286        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
287    {
288        self.add(path, vec![Method::HEAD], handler)
289    }
290
291    /// Adds a new route with `TRACE` method and the handler at the specified path.
292    ///
293    /// # Examples
294    ///
295    /// ```
296    /// use routerify::Router;
297    /// use hyper::{Response, Request, Body};
298    ///
299    /// async fn trace_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
300    ///     Ok(Response::new(Body::empty()))
301    /// }
302    ///
303    /// # fn run() -> Router<Body, hyper::Error> {
304    /// let router = Router::builder()
305    ///     .trace("/abc", trace_handler)
306    ///     .build()
307    ///     .unwrap();
308    /// # router
309    /// # }
310    /// # run();
311    /// ```
312    pub fn trace<P, H, R>(self, path: P, handler: H) -> Self
313    where
314        P: Into<String>,
315        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
316        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
317    {
318        self.add(path, vec![Method::TRACE], handler)
319    }
320
321    /// Adds a new route with `CONNECT` method and the handler at the specified path.
322    ///
323    /// # Examples
324    ///
325    /// ```
326    /// use routerify::Router;
327    /// use hyper::{Response, Request, Body};
328    ///
329    /// async fn connect_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
330    ///     Ok(Response::new(Body::empty()))
331    /// }
332    ///
333    /// # fn run() -> Router<Body, hyper::Error> {
334    /// let router = Router::builder()
335    ///     .connect("/abc", connect_handler)
336    ///     .build()
337    ///     .unwrap();
338    /// # router
339    /// # }
340    /// # run();
341    /// ```
342    pub fn connect<P, H, R>(self, path: P, handler: H) -> Self
343    where
344        P: Into<String>,
345        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
346        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
347    {
348        self.add(path, vec![Method::CONNECT], handler)
349    }
350
351    /// Adds a new route with `PATCH` method and the handler at the specified path.
352    ///
353    /// # Examples
354    ///
355    /// ```
356    /// use routerify::Router;
357    /// use hyper::{Response, Request, Body};
358    ///
359    /// async fn update_data_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
360    ///     Ok(Response::new(Body::from("Data updater")))
361    /// }
362    ///
363    /// # fn run() -> Router<Body, hyper::Error> {
364    /// let router = Router::builder()
365    ///     .patch("/update-data", update_data_handler)
366    ///     .build()
367    ///     .unwrap();
368    /// # router
369    /// # }
370    /// # run();
371    /// ```
372    pub fn patch<P, H, R>(self, path: P, handler: H) -> Self
373    where
374        P: Into<String>,
375        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
376        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
377    {
378        self.add(path, vec![Method::PATCH], handler)
379    }
380
381    /// Adds a new route with `OPTIONS` method and the handler at the specified path.
382    ///
383    /// # Examples
384    ///
385    /// ```
386    /// use routerify::Router;
387    /// use hyper::{Response, Request, Body};
388    ///
389    /// async fn options_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
390    ///     Ok(Response::new(Body::empty()))
391    /// }
392    ///
393    /// # fn run() -> Router<Body, hyper::Error> {
394    /// let router = Router::builder()
395    ///     .options("/abc", options_handler)
396    ///     .build()
397    ///     .unwrap();
398    /// # router
399    /// # }
400    /// # run();
401    /// ```
402    pub fn options<P, H, R>(self, path: P, handler: H) -> Self
403    where
404        P: Into<String>,
405        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
406        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
407    {
408        self.add(path, vec![Method::OPTIONS], handler)
409    }
410
411    /// Adds a new route with any method type and the handler at the `/*` path. It will accept any kind of request. It can be used to send
412    /// response for any non-existing routes i.e. for `404` pages.
413    ///
414    /// # Examples
415    ///
416    /// ```
417    /// use routerify::Router;
418    /// use hyper::{Response, Request, Body, StatusCode};
419    ///
420    /// async fn home_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
421    ///     Ok(Response::new(Body::from("home")))
422    /// }
423    ///
424    /// async fn handler_404(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
425    ///     Ok(
426    ///         Response::builder()
427    ///          .status(StatusCode::NOT_FOUND)
428    ///          .body(Body::from("NOT FOUND"))
429    ///          .unwrap()
430    ///      )
431    /// }
432    ///
433    /// # fn run() -> Router<Body, hyper::Error> {
434    /// let router = Router::builder()
435    ///     .get("/home", home_handler)
436    ///     .any(handler_404)
437    ///     .build()
438    ///     .unwrap();
439    /// # router
440    /// # }
441    /// # run();
442    /// ```
443    pub fn any<H, R>(self, handler: H) -> Self
444    where
445        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
446        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
447    {
448        self.add("/*", constants::ALL_POSSIBLE_HTTP_METHODS.to_vec(), handler)
449    }
450
451    /// Adds a new route with any method type and the handler at the specified path.
452    ///
453    /// # Examples
454    ///
455    /// ```
456    /// use routerify::Router;
457    /// use hyper::{Response, Request, Body};
458    ///
459    /// async fn home_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
460    ///     Ok(Response::new(Body::from("home")))
461    /// }
462    ///
463    /// # fn run() -> Router<Body, hyper::Error> {
464    /// let router = Router::builder()
465    ///     // It will accept requests at any method type at the specified path.
466    ///     .any_method("/", home_handler)
467    ///     .build()
468    ///     .unwrap();
469    /// # router
470    /// # }
471    /// # run();
472    /// ```
473    pub fn any_method<H, R, P>(self, path: P, handler: H) -> Self
474    where
475        P: Into<String>,
476        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
477        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
478    {
479        self.add(path, constants::ALL_POSSIBLE_HTTP_METHODS.to_vec(), handler)
480    }
481
482    /// Adds a new route with the specified method(s) and the handler at the specified path. It can be used to define routes with multiple method types.
483    ///
484    /// # Examples
485    ///
486    /// ```
487    /// use routerify::Router;
488    /// use hyper::{Response, Request, Body, StatusCode, Method};
489    ///
490    /// async fn cart_checkout_handler(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
491    ///     Ok(Response::new(Body::from("You shopping cart is being checking out")))
492    /// }
493    ///
494    /// # fn run() -> Router<Body, hyper::Error> {
495    /// let router = Router::builder()
496    ///     .add("/checkout", vec![Method::GET, Method::POST], cart_checkout_handler)
497    ///     .build()
498    ///     .unwrap();
499    /// # router
500    /// # }
501    /// # run();
502    /// ```
503    pub fn add<P, H, R>(self, path: P, methods: Vec<Method>, handler: H) -> Self
504    where
505        P: Into<String>,
506        H: Fn(Request<hyper::Body>) -> R + Send + Sync + 'static,
507        R: Future<Output = Result<Response<B>, E>> + Send + 'static,
508    {
509        self.and_then(move |mut inner| {
510            let mut path = path.into();
511
512            if !path.ends_with('/') && !path.ends_with('*') {
513                path.push('/');
514            }
515
516            let route = Route::new(path, methods, handler)?;
517            inner.routes.push(route);
518
519            crate::Result::Ok(inner)
520        })
521    }
522
523    /// It mounts a router onto another router. It can be very useful when you want to write modular routing logic.
524    ///
525    /// # Examples
526    ///
527    /// ```
528    /// use routerify::Router;
529    /// use hyper::{Response, Request, Body};
530    ///
531    /// mod api {
532    ///     use routerify::Router;
533    ///     use hyper::{Response, Request, Body};
534    ///
535    ///     pub fn router() -> Router<Body, hyper::Error> {
536    ///         Router::builder()
537    ///          .get("/users", |req| async move { Ok(Response::new(Body::from("User list"))) })
538    ///          .get("/books", |req| async move { Ok(Response::new(Body::from("Book list"))) })
539    ///          .build()
540    ///          .unwrap()
541    ///     }
542    /// }
543    ///
544    /// # fn run() -> Router<Body, hyper::Error> {
545    /// let router = Router::builder()
546    ///     // Now, mount the api router at `/api` path.
547    ///     .scope("/api", api::router())
548    ///     .build()
549    ///     .unwrap();
550    /// # router
551    /// # }
552    /// # run();
553    /// ```
554    ///
555    /// Now, the app can handle requests on: `/api/users` and `/api/books` paths.
556    pub fn scope<P>(self, path: P, mut router: Router<B, E>) -> Self
557    where
558        P: Into<String>,
559    {
560        let mut path = path.into();
561
562        if path.ends_with('/') {
563            path = (&path[..path.len() - 1]).to_string();
564        }
565
566        let mut builder = self;
567
568        for pre_middleware in router.pre_middlewares.iter_mut() {
569            let new_pre_middleware = PreMiddleware::new_with_boxed_handler(
570                format!("{}{}", path.as_str(), pre_middleware.path.as_str()),
571                pre_middleware
572                    .handler
573                    .take()
574                    .expect("No handler found in one of the pre-middlewares"),
575                pre_middleware.scope_depth + 1,
576            );
577            builder = builder.and_then(move |mut inner| {
578                inner.pre_middlewares.push(new_pre_middleware?);
579                crate::Result::Ok(inner)
580            });
581        }
582
583        for route in router.routes.iter_mut() {
584            let new_route = Route::new_with_boxed_handler(
585                format!("{}{}", path.as_str(), route.path.as_str()),
586                route.methods.clone(),
587                route.handler.take().expect("No handler found in one of the routes"),
588                route.scope_depth + 1,
589            );
590            builder = builder.and_then(move |mut inner| {
591                inner.routes.push(new_route?);
592                crate::Result::Ok(inner)
593            });
594        }
595
596        for post_middleware in router.post_middlewares.iter_mut() {
597            let new_post_middleware = PostMiddleware::new_with_boxed_handler(
598                format!("{}{}", path.as_str(), post_middleware.path.as_str()),
599                post_middleware
600                    .handler
601                    .take()
602                    .expect("No handler found in one of the post-middlewares"),
603                post_middleware.scope_depth + 1,
604            );
605            builder = builder.and_then(move |mut inner| {
606                inner.post_middlewares.push(new_post_middleware?);
607                crate::Result::Ok(inner)
608            });
609        }
610
611        for scoped_data_map in router.scoped_data_maps.iter_mut() {
612            let new_path = format!("{}{}", path.as_str(), scoped_data_map.path.as_str());
613            let data_map = Arc::try_unwrap(
614                scoped_data_map
615                    .data_map
616                    .take()
617                    .expect("No data map found in one of the scoped data maps"),
618            )
619            .expect("Non-zero owner of the shared data map in one of the scoped data maps");
620
621            builder = builder.and_then(move |mut inner| {
622                let data_maps = &mut inner.data_maps;
623
624                let data_map_arr = data_maps.get_mut(&new_path);
625                if let Some(data_map_arr) = data_map_arr {
626                    data_map_arr.push(data_map);
627                } else {
628                    data_maps.insert(new_path, vec![data_map]);
629                }
630
631                crate::Result::Ok(inner)
632            });
633        }
634
635        builder
636    }
637}
638
639impl<B: HttpBody + Send + Sync + 'static, E: Into<Box<dyn std::error::Error + Send + Sync>> + 'static>
640    RouterBuilder<B, E>
641{
642    /// Adds a single middleware. A pre middleware can be created by [`Middleware::pre`](./enum.Middleware.html#method.pre) method and a post
643    /// middleware can be created by [`Middleware::post`](./enum.Middleware.html#method.post) method.
644    ///
645    /// # Examples
646    ///
647    /// ```
648    /// use routerify::{Router, Middleware};
649    /// use hyper::{Response, Request, Body};
650    /// use std::convert::Infallible;
651    ///
652    /// # fn run() -> Router<Body, Infallible> {
653    /// let router = Router::builder()
654    ///      // Create and attach a pre middleware.
655    ///      .middleware(Middleware::pre(|req| async move { /* Do some operations */ Ok(req) }))
656    ///      // Create and attach a post middleware.
657    ///      .middleware(Middleware::post(|res| async move { /* Do some operations */ Ok(res) }))
658    ///      .build()
659    ///      .unwrap();
660    /// # router
661    /// # }
662    /// # run();
663    /// ```
664    pub fn middleware(self, m: Middleware<B, E>) -> Self {
665        self.and_then(move |mut inner| {
666            match m {
667                Middleware::Pre(middleware) => {
668                    inner.pre_middlewares.push(middleware);
669                }
670                Middleware::Post(middleware) => {
671                    inner.post_middlewares.push(middleware);
672                }
673            }
674            crate::Result::Ok(inner)
675        })
676    }
677
678    /// Specify app data to be shared across route handlers, middlewares and the error handler.
679    ///
680    /// Please refer to the [Data and State Sharing](./index.html#data-and-state-sharing) for more info.
681    pub fn data<T: Send + Sync + 'static>(self, data: T) -> Self {
682        self.and_then(move |mut inner| {
683            let data_maps = &mut inner.data_maps;
684
685            let data_map_arr = data_maps.get_mut(&"/*".to_owned());
686            if let Some(data_map_arr) = data_map_arr {
687                let first_data_map = data_map_arr.get_mut(0).unwrap();
688                first_data_map.insert(data);
689            } else {
690                let mut data_map = DataMap::new();
691                data_map.insert(data);
692                data_maps.insert("/*".to_owned(), vec![data_map]);
693            }
694
695            crate::Result::Ok(inner)
696        })
697    }
698
699    /// Adds a handler to handle any error raised by the routes or any middlewares. Please refer to [Error Handling](./index.html#error-handling) section
700    /// for more info.
701    pub fn err_handler<H, R>(self, handler: H) -> Self
702    where
703        H: Fn(crate::RouteError) -> R + Send + Sync + 'static,
704        R: Future<Output = Response<B>> + Send + 'static,
705    {
706        let handler: ErrHandlerWithoutInfo<B> = Box::new(move |err: crate::RouteError| Box::new(handler(err)));
707
708        self.and_then(move |mut inner| {
709            inner.err_handler = Some(ErrHandler::WithoutInfo(handler));
710            crate::Result::Ok(inner)
711        })
712    }
713
714    /// Adds a handler to handle any error raised by the routes or any middlewares.
715    ///
716    /// Here, the handler also access [request info](./struct.RequestInfo.html) e.g. headers, method, uri etc to generate response based on the request information.
717    ///
718    /// Please refer to [Error Handling](./index.html#error-handling) section
719    /// for more info.
720    pub fn err_handler_with_info<H, R>(self, handler: H) -> Self
721    where
722        H: Fn(crate::RouteError, RequestInfo) -> R + Send + Sync + 'static,
723        R: Future<Output = Response<B>> + Send + 'static,
724    {
725        let handler: ErrHandlerWithInfo<B> =
726            Box::new(move |err: crate::RouteError, req_info: RequestInfo| Box::new(handler(err, req_info)));
727
728        self.and_then(move |mut inner| {
729            inner.err_handler = Some(ErrHandler::WithInfo(handler));
730            crate::Result::Ok(inner)
731        })
732    }
733}
734
735impl<B: HttpBody + Send + Sync + 'static, E: Into<Box<dyn std::error::Error + Send + Sync>> + 'static> Default
736    for RouterBuilder<B, E>
737{
738    fn default() -> RouterBuilder<B, E> {
739        RouterBuilder {
740            inner: Ok(BuilderInner {
741                pre_middlewares: Vec::new(),
742                routes: Vec::new(),
743                post_middlewares: Vec::new(),
744                data_maps: HashMap::new(),
745                err_handler: None,
746            }),
747        }
748    }
749}