), suffix.clone());
/// assert_eq!(bob.to_string(), "/person/Bob?woo#bam");
/// ```
///
/// ## Grammar
///
/// The grammar for this variant of the `uri!` macro is:
///
/// ```text
/// uri := (prefix ',')? route
/// | prefix ',' route ',' suffix
///
/// prefix := STRING | expr ; `Origin` or `Absolute`
/// suffix := STRING | expr ; `Reference` or `Absolute`
///
/// route := PATH '(' (named | unnamed) ')'
///
/// named := IDENT = expr (',' named)? ','?
/// unnamed := expr (',' unnamed)? ','?
///
/// expr := EXPR | '_'
///
/// EXPR := a valid Rust expression (examples: `foo()`, `12`, `"hey"`)
/// IDENT := a valid Rust identifier (examples: `name`, `age`)
/// STRING := an uncooked string literal, as defined by Rust (example: `"hi"`)
/// PATH := a path, as defined by Rust (examples: `route`, `my_mod::route`)
/// ```
///
/// ## Dynamic Semantics
///
/// The returned value is that of the prefix (minus any query part) concatenated
/// with the route URI concatenated with the query (if the route has no query
/// part) and fragment parts of the suffix. The route URI is generated by
/// interpolating the declared route URI with the URL-safe version of the route
/// values in `uri!()`. The generated URI is guaranteed to be URI-safe.
///
/// Each route value is rendered in its appropriate place in the URI using the
/// [`UriDisplay`] implementation for the value's type. The `UriDisplay`
/// implementation ensures that the rendered value is URL-safe.
///
/// A `uri!()` invocation allocated at-most once.
///
/// ## Static Semantics
///
/// The `uri!` macro returns one of [`Origin`], [`Absolute`], or [`Reference`],
/// depending on the types of the prefix and suffix, if any. The table below
/// specifies all combinations:
///
/// | Prefix | Suffix | Output |
/// |------------|-------------|-------------|
/// | None | None | `Origin` |
/// | None | `Absolute` | `Origin` |
/// | None | `Reference` | `Reference` |
/// | `Origin` | None | `Origin` |
/// | `Origin` | `Absolute` | `Origin` |
/// | `Origin` | `Reference` | `Reference` |
/// | `Absolute` | None | `Absolute` |
/// | `Absolute` | `Absolute` | `Absolute` |
/// | `Absolute` | `Reference` | `Reference` |
///
/// A `uri!` invocation only typechecks if the type of every route URI value in
/// the invocation matches the type declared for the parameter in the given
/// route, after conversion with [`FromUriParam`], or if a value is ignored
/// using `_` and the corresponding route type implements [`Ignorable`].
///
/// ### Conversion
///
/// The [`FromUriParam`] trait is used to typecheck and perform a conversion for
/// each value passed to `uri!`. If a `FromUriParam for T` implementation
/// exists for a type `T` for part URI part `P`, then a value of type `S` can be
/// used in `uri!` macro for a route URI parameter declared with a type of `T`
/// in part `P`. For example, the following implementation, provided by Rocket,
/// allows an `&str` to be used in a `uri!` invocation for route URI parameters
/// declared as `String`:
///
/// ```rust,ignore
/// impl FromUriParam for String { .. }
/// ```
///
/// ### Ignorables
///
/// Query parameters can be ignored using `_` in place of an expression. The
/// corresponding type in the route URI must implement [`Ignorable`]. Ignored
/// parameters are not interpolated into the resulting `Origin`. Path parameters
/// are not ignorable.
///
/// [`Uri`]: ../rocket/http/uri/enum.Uri.html
/// [`Origin`]: ../rocket/http/uri/struct.Origin.html
/// [`Asterisk`]: ../rocket/http/uri/struct.Asterisk.html
/// [`Authority`]: ../rocket/http/uri/struct.Authority.html
/// [`Absolute`]: ../rocket/http/uri/struct.Absolute.html
/// [`Reference`]: ../rocket/http/uri/struct.Reference.html
/// [`FromUriParam`]: ../rocket/http/uri/trait.FromUriParam.html
/// [`UriDisplay`]: ../rocket/http/uri/trait.UriDisplay.html
/// [`Ignorable`]: ../rocket/http/uri/trait.Ignorable.html
#[proc_macro]
pub fn uri(input: TokenStream) -> TokenStream {
emit!(bang::uri_macro(input))
}
#[doc(hidden)]
#[proc_macro]
/// Internal macro: `rocket_internal_uri!`.
pub fn rocket_internal_uri(input: TokenStream) -> TokenStream {
emit!(bang::uri_internal_macro(input))
}
#[doc(hidden)]
#[proc_macro]
/// Private Rocket internal macro: `internal_guide_tests!`.
pub fn internal_guide_tests(input: TokenStream) -> TokenStream {
emit!(bang::guide_tests_internal(input))
}
#[doc(hidden)]
#[proc_macro]
/// Private Rocket internal macro: `export!`.
pub fn export(input: TokenStream) -> TokenStream {
emit!(bang::export_internal(input))
}