From cad5494d42b36882143e9c3344632de994f12952 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Fri, 4 Jun 2021 18:45:40 -0700 Subject: [PATCH] Document ignored segments. --- core/codegen/src/lib.rs | 14 +++++++---- site/guide/4-requests.md | 53 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/core/codegen/src/lib.rs b/core/codegen/src/lib.rs index 296bd85b..2d09f2bc 100644 --- a/core/codegen/src/lib.rs +++ b/core/codegen/src/lib.rs @@ -165,7 +165,7 @@ macro_rules! route_attribute { /// MEDIA_TYPE := valid HTTP media type or known shorthand /// /// INTEGER := unsigned integer, as defined by Rust - /// IDENT := valid identifier, as defined by Rust, except `_` + /// IDENT := valid identifier, as defined by Rust /// ``` /// /// The generic route attribute is defined as: @@ -176,10 +176,11 @@ macro_rules! route_attribute { /// /// # Typing Requirements /// - /// Every identifier that appears in a dynamic parameter (`SINGLE_PARAM` - /// or `TRAILING_PARAM`) must appear as an argument to the function. For - /// example, the following route requires the decorated function to have - /// the arguments `foo`, `baz`, `msg`, `rest`, and `form`: + /// Every identifier, except for `_`, that appears in a dynamic + /// parameter (`SINGLE_PARAM` or `TRAILING_PARAM`) must appear as an + /// argument to the function. For example, the following route requires + /// the decorated function to have the arguments `foo`, `baz`, `msg`, + /// `rest`, and `form`: /// /// ```rust /// # #[macro_use] extern crate rocket; @@ -209,6 +210,9 @@ macro_rules! route_attribute { /// corresponding dynamic parameter is required to implement the /// [`FromRequest`] trait. /// + /// A route argument declared a `_` must _not_ appear in the function + /// argument list and has no typing requirements. + /// /// The return type of the decorated function must implement the /// [`Responder`] trait. /// diff --git a/site/guide/4-requests.md b/site/guide/4-requests.md index c943d5b0..7ef171f4 100644 --- a/site/guide/4-requests.md +++ b/site/guide/4-requests.md @@ -161,9 +161,39 @@ async fn files(file: PathBuf) -> Option { [`FileServer`]: @api/rocket/fs/struct.FileServer.html [`FromSegments`]: @api/rocket/request/trait.FromSegments.html +### Ignored Segments + +A component of a route can be fully ignored by using `<_>`, and multiple +components can be ignored by using `<_..>`. In other words, the wildcard name +`_` is a dynamic parameter name that ignores that dynamic parameter. An ignored +parameter must not appear in the function argument list. A segment declared as +`<_>` matches anything in a single segment while segments declared as `<_..>` +match any number of segments with no conditions. + +As an example, the `foo_bar` route below matches any `GET` request with a +3-segment URI that starts with `/foo/` and ends with `/bar`. The `everything` +route below matches _every_ GET request. + +```rust +# #[macro_use] extern crate rocket; + +#[get("/foo/<_>/bar")] +fn foo_bar() -> &'static str { + "Foo _____ bar!" +} + +#[get("/<_..>")] +fn everything() -> &'static str { + "Hey, you're here." +} + +# // Ensure there are no collisions. +# rocket_guide_tests::client(routes![foo_bar, everything]); +``` + ## Forwarding -Let's take a closer look at the route attribute and signature pair from a +Let's take a closer look at this route attribute and signature pair from a previous example: ```rust @@ -247,6 +277,7 @@ queries: the _more_ static a route's path and query are, the higher its precedence. There are three "colors" to paths and queries: + 1. `static`, meaning all components are static 2. `partial`, meaning at least one component is dynamic 3. `wild`, meaning all components are dynamic @@ -269,7 +300,25 @@ and wild paths. This results in the following default ranking table: | wild | wild | -2 | | wild | none | -1 | -Recall that _lower_ ranks have _higher_ precedence. +Recall that _lower_ ranks have _higher_ precedence. As an example, consider this +application from before: + +```rust +# #[macro_use] extern crate rocket; + +#[get("/foo/<_>/bar")] +fn foo_bar() { } + +#[get("/<_..>")] +fn everything() { } + +# // Ensure there are no collisions. +# rocket_guide_tests::client(routes![foo_bar, everything]); +``` + +Default ranking ensures that `foo_bar`, with a "partial" path color, has higher +precedence than `everything` with a "wild" path color. This default ranking +prevents what would have otherwise been a routing collision. ## Request Guards