rocket_codegen/
lib.rs

1#![recursion_limit="128"]
2
3#![doc(html_root_url = "https://api.rocket.rs/v0.5")]
4#![doc(html_favicon_url = "https://rocket.rs/images/favicon.ico")]
5#![doc(html_logo_url = "https://rocket.rs/images/logo-boxed.png")]
6
7#![warn(rust_2018_idioms, missing_docs)]
8
9//! # Rocket - Code Generation
10//!
11//! This crate implements the code generation portions of Rocket. This includes
12//! custom derives, custom attributes, and procedural macros. The documentation
13//! here is purely technical. The code generation facilities are documented
14//! thoroughly in the [Rocket programming guide](https://rocket.rs/v0.5/guide).
15//!
16//! # Usage
17//!
18//! You **_should not_** directly depend on this library. To use the macros,
19//! attributes, and derives in this crate, it suffices to depend on `rocket` in
20//! `Cargo.toml`:
21//!
22//! ```toml
23//! [dependencies]
24//! rocket = "0.5.1"
25//! ```
26//!
27//! And to import all macros, attributes, and derives via `#[macro_use]` in the
28//! crate root:
29//!
30//! ```rust
31//! #[macro_use] extern crate rocket;
32//! # #[get("/")] fn hello() { }
33//! # fn main() { rocket::build().mount("/", routes![hello]); }
34//! ```
35//!
36//! Or, alternatively, selectively import from the top-level scope:
37//!
38//! ```rust
39//! # extern crate rocket;
40//!
41//! use rocket::{get, routes};
42//! # #[get("/")] fn hello() { }
43//! # fn main() { rocket::build().mount("/", routes![hello]); }
44//! ```
45//!
46//! # Debugging Codegen
47//!
48//! When the `ROCKET_CODEGEN_DEBUG` environment variable is set, this crate
49//! logs, at compile-time and to the console, the items it generates. For
50//! example, you might run the following to build a Rocket application with
51//! codegen debug logging enabled:
52//!
53//! ```sh
54//! ROCKET_CODEGEN_DEBUG=1 cargo build
55//! ```
56
57#[macro_use] extern crate quote;
58
59use rocket_http as http;
60
61#[macro_use]
62mod exports;
63mod proc_macro_ext;
64mod derive;
65mod attribute;
66mod bang;
67mod http_codegen;
68mod syn_ext;
69mod name;
70
71use crate::http::Method;
72use proc_macro::TokenStream;
73
74static URI_MACRO_PREFIX: &str = "rocket_uri_macro_";
75static ROCKET_IDENT_PREFIX: &str = "__rocket_";
76
77macro_rules! emit {
78    ($tokens:expr) => ({
79        use devise::ext::SpanDiagnosticExt;
80
81        let mut tokens = $tokens;
82        if std::env::var_os("ROCKET_CODEGEN_DEBUG").is_some() {
83            let debug_tokens = proc_macro2::Span::call_site()
84                .note("emitting Rocket code generation debug output")
85                .note(tokens.to_string())
86                .emit_as_item_tokens();
87
88            tokens.extend(debug_tokens);
89        }
90
91        tokens.into()
92    })
93}
94
95macro_rules! route_attribute {
96    ($name:ident => $method:expr) => (
97        /// Attribute to generate a [`Route`] and associated metadata.
98        ///
99        /// This and all other route attributes can only be applied to free
100        /// functions:
101        ///
102        /// ```rust
103        /// # #[macro_use] extern crate rocket;
104        /// #
105        /// #[get("/")]
106        /// fn index() -> &'static str {
107        ///     "Hello, world!"
108        /// }
109        /// ```
110        ///
111        /// There are 7 method-specific route attributes:
112        ///
113        ///   * [`get`] - `GET` specific route
114        ///   * [`put`] - `PUT` specific route
115        ///   * [`post`] - `POST` specific route
116        ///   * [`delete`] - `DELETE` specific route
117        ///   * [`head`] - `HEAD` specific route
118        ///   * [`options`] - `OPTIONS` specific route
119        ///   * [`patch`] - `PATCH` specific route
120        ///
121        /// Additionally, [`route`] allows the method and uri to be explicitly
122        /// specified:
123        ///
124        /// ```rust
125        /// # #[macro_use] extern crate rocket;
126        /// #
127        /// #[route(GET, uri = "/")]
128        /// fn index() -> &'static str {
129        ///     "Hello, world!"
130        /// }
131        /// ```
132        ///
133        /// [`get`]: attr.get.html
134        /// [`put`]: attr.put.html
135        /// [`post`]: attr.post.html
136        /// [`delete`]: attr.delete.html
137        /// [`head`]: attr.head.html
138        /// [`options`]: attr.options.html
139        /// [`patch`]: attr.patch.html
140        /// [`route`]: attr.route.html
141        ///
142        /// # Grammar
143        ///
144        /// The grammar for all method-specific route attributes is defined as:
145        ///
146        /// ```text
147        /// route := '"' uri ('?' query)? '"' (',' parameter)*
148        ///
149        /// uri := ('/' segment)*
150        ///
151        /// query := segment ('&' segment)*
152        ///
153        /// segment := URI_SEG
154        ///          | SINGLE_PARAM
155        ///          | TRAILING_PARAM
156        ///
157        /// parameter := 'rank' '=' INTEGER
158        ///            | 'format' '=' '"' MEDIA_TYPE '"'
159        ///            | 'data' '=' '"' SINGLE_PARAM '"'
160        ///
161        /// SINGLE_PARAM := '<' IDENT '>'
162        /// TRAILING_PARAM := '<' IDENT '..>'
163        ///
164        /// URI_SEG := valid, non-percent-encoded HTTP URI segment
165        /// MEDIA_TYPE := valid HTTP media type or known shorthand
166        ///
167        /// INTEGER := unsigned integer, as defined by Rust
168        /// IDENT := valid identifier, as defined by Rust
169        /// ```
170        ///
171        /// The generic route attribute is defined as:
172        ///
173        /// ```text
174        /// generic-route := METHOD ',' 'uri' '=' route
175        /// ```
176        ///
177        /// # Typing Requirements
178        ///
179        /// Every identifier, except for `_`, that appears in a dynamic
180        /// parameter (`SINGLE_PARAM` or `TRAILING_PARAM`) must appear as an
181        /// argument to the function. For example, the following route requires
182        /// the decorated function to have the arguments `foo`, `baz`, `msg`,
183        /// `rest`, and `form`:
184        ///
185        /// ```rust
186        /// # #[macro_use] extern crate rocket;
187        /// # use rocket::form::Form;
188        /// # use std::path::PathBuf;
189        /// # #[derive(FromForm)] struct F { a: usize }
190        /// #[get("/<foo>/bar/<baz..>?<msg>&closed&<rest..>", data = "<form>")]
191        /// # fn f(foo: usize, baz: PathBuf, msg: String, rest: F, form: Form<F>) {  }
192        /// ```
193        ///
194        /// The type of each function argument corresponding to a dynamic
195        /// parameter is required to implement one of Rocket's guard traits. The
196        /// exact trait that is required to be implemented depends on the kind
197        /// of dynamic parameter (`SINGLE` or `TRAILING`) and where in the route
198        /// attribute the parameter appears. The table below summarizes trait
199        /// requirements:
200        ///
201        /// | position | kind        | trait             |
202        /// |----------|-------------|-------------------|
203        /// | path     | `<ident>`   | [`FromParam`]     |
204        /// | path     | `<ident..>` | [`FromSegments`]  |
205        /// | query    | `<ident>`   | [`FromForm`]      |
206        /// | query    | `<ident..>` | [`FromForm`]      |
207        /// | data     | `<ident>`   | [`FromData`]      |
208        ///
209        /// The type of each function argument that _does not_ have a
210        /// corresponding dynamic parameter is required to implement the
211        /// [`FromRequest`] trait.
212        ///
213        /// A route argument declared a `_` must _not_ appear in the function
214        /// argument list and has no typing requirements.
215        ///
216        /// The return type of the decorated function must implement the
217        /// [`Responder`] trait.
218        ///
219        /// [`FromParam`]: ../rocket/request/trait.FromParam.html
220        /// [`FromSegments`]: ../rocket/request/trait.FromSegments.html
221        /// [`FromFormField`]: ../rocket/request/trait.FromFormField.html
222        /// [`FromForm`]: ../rocket/form/trait.FromForm.html
223        /// [`FromData`]: ../rocket/data/trait.FromData.html
224        /// [`FromRequest`]: ../rocket/request/trait.FromRequest.html
225        /// [`Route`]: ../rocket/struct.Route.html
226        /// [`Responder`]: ../rocket/response/trait.Responder.html
227        ///
228        /// # Semantics
229        ///
230        /// The attribute generates three items:
231        ///
232        ///   1. A route [`Handler`].
233        ///
234        ///      The generated handler validates and generates all arguments for
235        ///      the generated function according to the trait that their type
236        ///      must implement. The order in which arguments are processed is:
237        ///
238        ///         1. Request guards from left to right.
239        ///
240        ///            If a request guard fails, the request is forwarded if the
241        ///            [`Outcome`] is `Forward` or failed if the [`Outcome`] is
242        ///            `Error`. See [`FromRequest` Outcomes] for further detail.
243        ///
244        ///         2. Path and query guards in an unspecified order. If a path
245        ///            or query guard fails, the request is forwarded.
246        ///
247        ///         3. Data guard, if any.
248        ///
249        ///            If a data guard fails, the request is forwarded if the
250        ///            [`Outcome`] is `Forward` or failed if the [`Outcome`] is
251        ///            `Error`. See [`FromData`] for further detail.
252        ///
253        ///      If all validation succeeds, the decorated function is called.
254        ///      The returned value is used to generate a [`Response`] via the
255        ///      type's [`Responder`] implementation.
256        ///
257        ///   2. A static structure used by [`routes!`] to generate a [`Route`].
258        ///
259        ///      The static structure (and resulting [`Route`]) is populated
260        ///      with the name (the function's name), path, query, rank, and
261        ///      format from the route attribute. The handler is set to the
262        ///      generated handler.
263        ///
264        ///   3. A macro used by [`uri!`] to type-check and generate an
265        ///      [`Origin`].
266        ///
267        /// [`Handler`]: ../rocket/route/trait.Handler.html
268        /// [`routes!`]: macro.routes.html
269        /// [`uri!`]: macro.uri.html
270        /// [`Origin`]: ../rocket/http/uri/struct.Origin.html
271        /// [`Outcome`]: ../rocket/outcome/enum.Outcome.html
272        /// [`Response`]: ../rocket/struct.Response.html
273        /// [`FromRequest` Outcomes]: ../rocket/request/trait.FromRequest.html#outcomes
274        #[proc_macro_attribute]
275        pub fn $name(args: TokenStream, input: TokenStream) -> TokenStream {
276            emit!(attribute::route::route_attribute($method, args, input))
277        }
278    )
279}
280
281route_attribute!(route => None);
282route_attribute!(get => Method::Get);
283route_attribute!(put => Method::Put);
284route_attribute!(post => Method::Post);
285route_attribute!(delete => Method::Delete);
286route_attribute!(head => Method::Head);
287route_attribute!(patch => Method::Patch);
288route_attribute!(options => Method::Options);
289
290/// Attribute to generate a [`Catcher`] and associated metadata.
291///
292/// This attribute can only be applied to free functions:
293///
294/// ```rust
295/// # #[macro_use] extern crate rocket;
296/// #
297/// use rocket::Request;
298/// use rocket::http::Status;
299///
300/// #[catch(404)]
301/// fn not_found(req: &Request) -> String {
302///     format!("Sorry, {} does not exist.", req.uri())
303/// }
304///
305/// #[catch(default)]
306/// fn default(status: Status, req: &Request) -> String {
307///     format!("{} ({})", status, req.uri())
308/// }
309/// ```
310///
311/// # Grammar
312///
313/// The grammar for the `#[catch]` attributes is defined as:
314///
315/// ```text
316/// catch := STATUS | 'default'
317///
318/// STATUS := valid HTTP status code (integer in [200, 599])
319/// ```
320///
321/// # Typing Requirements
322///
323/// The decorated function may take zero, one, or two arguments. It's type
324/// signature must be one of the following, where `R:`[`Responder`]:
325///
326///   * `fn() -> R`
327///   * `fn(`[`&Request`]`) -> R`
328///   * `fn(`[`Status`]`, `[`&Request`]`) -> R`
329///
330/// # Semantics
331///
332/// The attribute generates two items:
333///
334///   1. An error [`Handler`].
335///
336///      The generated handler calls the decorated function, passing in the
337///      [`Status`] and [`&Request`] values if requested. The returned value is
338///      used to generate a [`Response`] via the type's [`Responder`]
339///      implementation.
340///
341///   2. A static structure used by [`catchers!`] to generate a [`Catcher`].
342///
343///      The static structure (and resulting [`Catcher`]) is populated with the
344///      name (the function's name) and status code from the route attribute or
345///      `None` if `default`. The handler is set to the generated handler.
346///
347/// [`&Request`]: ../rocket/struct.Request.html
348/// [`Status`]: ../rocket/http/struct.Status.html
349/// [`Handler`]: ../rocket/catcher/trait.Handler.html
350/// [`catchers!`]: macro.catchers.html
351/// [`Catcher`]: ../rocket/struct.Catcher.html
352/// [`Response`]: ../rocket/struct.Response.html
353/// [`Responder`]: ../rocket/response/trait.Responder.html
354#[proc_macro_attribute]
355pub fn catch(args: TokenStream, input: TokenStream) -> TokenStream {
356    emit!(attribute::catch::catch_attribute(args, input))
357}
358
359/// Retrofits supports for `async fn` in unit tests.
360///
361/// Simply decorate a test `async fn` with `#[async_test]` instead of `#[test]`:
362///
363/// ```rust
364/// # #[macro_use] extern crate rocket;
365/// #[cfg(test)]
366/// mod tests {
367///     #[async_test]
368///     async fn test() {
369///         /* .. */
370///     }
371/// }
372/// ```
373///
374/// The attribute rewrites the function to execute inside of a Rocket-compatible
375/// async runtime.
376#[proc_macro_attribute]
377pub fn async_test(args: TokenStream, input: TokenStream) -> TokenStream {
378    emit!(attribute::entry::async_test_attribute(args, input))
379}
380
381/// Retrofits `async fn` support in `main` functions.
382///
383/// A `main` `async fn` function decorated with `#[rocket::main]` is transformed
384/// into a regular `main` function that internally initializes a Rocket-specific
385/// tokio runtime and runs the attributed `async fn` inside of it:
386///
387/// ```rust,no_run
388/// #[rocket::main]
389/// async fn main() -> Result<(), rocket::Error> {
390///     let _rocket = rocket::build()
391///         .ignite().await?
392///         .launch().await?;
393///
394///     Ok(())
395/// }
396/// ```
397///
398/// It should be used only when the return values of `ignite()` or `launch()`
399/// are to be inspected:
400///
401/// ```rust,no_run
402/// #[rocket::main]
403/// async fn main() -> Result<(), rocket::Error> {
404///     let rocket = rocket::build().ignite().await?;
405///     println!("Hello, Rocket: {:?}", rocket);
406///
407///     let rocket = rocket.launch().await?;
408///     println!("Welcome back, Rocket: {:?}", rocket);
409///
410///     Ok(())
411/// }
412/// ```
413///
414/// For all other cases, use [`#[launch]`](launch) instead.
415///
416/// The function attributed with `#[rocket::main]` _must_ be `async` and _must_
417/// be called `main`. Violation of either results in a compile-time error.
418#[proc_macro_attribute]
419pub fn main(args: TokenStream, input: TokenStream) -> TokenStream {
420    emit!(attribute::entry::main_attribute(args, input))
421}
422
423/// Generates a `main` function that launches a returned `Rocket<Build>`.
424///
425/// When applied to a function that returns a `Rocket<Build>` instance,
426/// `#[launch]` automatically initializes an `async` runtime and
427/// launches the function's returned instance:
428///
429/// ```rust,no_run
430/// # use rocket::launch;
431/// use rocket::{Rocket, Build};
432///
433/// #[launch]
434/// fn rocket() -> Rocket<Build> {
435///     rocket::build()
436/// }
437/// ```
438///
439/// This generates code equivalent to the following:
440///
441/// ```rust,no_run
442/// # use rocket::{Rocket, Build};
443/// # fn rocket() -> Rocket<Build> {
444/// #     rocket::build()
445/// # }
446/// #
447/// #[rocket::main]
448/// async fn main() {
449///     // Recall that an uninspected `Error` will cause a pretty-printed panic,
450///     // so rest assured errors do not go undetected when using `#[launch]`.
451///     let _ = rocket().launch().await;
452/// }
453/// ```
454///
455/// To avoid needing to import _any_ items in the common case, the `launch`
456/// attribute will infer a return type written as `_` as `Rocket<Build>`:
457///
458/// ```rust,no_run
459/// # use rocket::launch;
460/// #[launch]
461/// fn rocket() -> _ {
462///     rocket::build()
463/// }
464/// ```
465///
466/// The attributed function may be `async`:
467///
468/// ```rust,no_run
469/// # use rocket::launch;
470/// # async fn some_async_work() {}
471/// #[launch]
472/// async fn rocket() -> _ {
473///     some_async_work().await;
474///     rocket::build()
475/// }
476/// ```
477#[proc_macro_attribute]
478pub fn launch(args: TokenStream, input: TokenStream) -> TokenStream {
479    emit!(attribute::entry::launch_attribute(args, input))
480}
481
482/// Derive for the [`FromFormField`] trait.
483///
484/// The [`FromFormField`] derive can be applied to enums with nullary
485/// (zero-length) fields:
486///
487/// ```rust
488/// # #[macro_use] extern crate rocket;
489/// #
490/// #[derive(FromFormField)]
491/// enum MyValue {
492///     First,
493///     Second,
494///     Third,
495/// }
496/// ```
497///
498/// The derive generates an implementation of the [`FromFormField`] trait for
499/// the decorated `enum`. The implementation returns successfully when the form
500/// value matches, case insensitively, the stringified version of a variant's
501/// name, returning an instance of said variant. If there is no match, an error
502/// recording all of the available options is returned.
503///
504/// As an example, for the `enum` above, the form values `"first"`, `"FIRST"`,
505/// `"fiRSt"`, and so on would parse as `MyValue::First`, while `"second"` and
506/// `"third"` (in any casing) would parse as `MyValue::Second` and
507/// `MyValue::Third`, respectively.
508///
509/// The `field` field attribute can be used to change the string value that is
510/// compared against for a given variant:
511///
512/// ```rust
513/// # #[macro_use] extern crate rocket;
514/// #
515/// #[derive(FromFormField)]
516/// enum MyValue {
517///     First,
518///     Second,
519///     #[field(value = "fourth")]
520///     #[field(value = "fifth")]
521///     Third,
522/// }
523/// ```
524///
525/// When more than one `value` is specified, matching _any_ value will result in
526/// parsing the decorated variant. Declaring any two values that are
527/// case-insensitively equal to any other value or variant name is a
528/// compile-time error.
529///
530/// The `#[field]` attribute's grammar is:
531///
532/// ```text
533/// field := 'value' '=' STRING_LIT
534///
535/// STRING_LIT := any valid string literal, as defined by Rust
536/// ```
537///
538/// The attribute accepts a single string parameter of name `value`
539/// corresponding to the string to use to match against for the decorated
540/// variant. In the example above, the the strings `"fourth"`, `"FOUrth"`,
541/// `"fiFTH"` and so on would parse as `MyValue::Third`.
542///
543/// [`FromFormField`]: ../rocket/form/trait.FromFormField.html
544#[proc_macro_derive(FromFormField, attributes(field))]
545pub fn derive_from_form_field(input: TokenStream) -> TokenStream {
546    emit!(derive::from_form_field::derive_from_form_field(input))
547}
548
549/// Derive for the [`FromForm`] trait.
550///
551/// The [`FromForm`] derive can be applied to structures with named or unnamed
552/// fields:
553///
554/// ```rust
555/// use rocket::form::FromForm;
556///
557/// #[derive(FromForm)]
558/// struct MyStruct<'r> {
559///     field: usize,
560///     #[field(name = "renamed_field")]
561///     #[field(name = uncased("RenamedField"))]
562///     other: &'r str,
563///     #[field(validate = range(1..), default = 3)]
564///     r#type: usize,
565///     #[field(default = None)]
566///     is_nice: bool,
567/// }
568///
569/// #[derive(FromForm)]
570/// #[field(validate = len(6..))]
571/// #[field(validate = neq("password"))]
572/// struct Password<'r>(&'r str);
573/// ```
574///
575/// Each field type is required to implement [`FromForm`].
576///
577/// The derive generates an implementation of the [`FromForm`] trait.
578///
579/// **Named Fields**
580///
581/// If the structure has named fields, the implementation parses a form whose
582/// field names match the field names of the structure on which the derive was
583/// applied. Each field's value is parsed with the [`FromForm`] implementation
584/// of the field's type. The `FromForm` implementation succeeds only when all
585/// fields parse successfully or return a default. Errors are collected into a
586/// [`form::Errors`] and returned if non-empty after parsing all fields.
587///
588/// **Unnamed Fields**
589///
590/// If the structure is a tuple struct, it must have exactly one field. The
591/// implementation parses a form exactly when the internal field parses a form
592/// _and_ any `#[field]` validations succeed.
593///
594/// ## Syntax
595///
596/// The derive accepts one field attribute: `field`, and one container
597/// attribute, `form`, with the following syntax:
598///
599/// ```text
600/// field := name? default? validate*
601///
602/// name := 'name' '=' name_val ','?
603/// name_val :=  '"' FIELD_NAME '"'
604///          | 'uncased(' '"' FIELD_NAME '"' ')
605///
606/// default := 'default' '=' EXPR ','?
607///          | 'default_with' '=' EXPR ','?
608///
609/// validate := 'validate' '=' EXPR ','?
610///
611/// FIELD_NAME := valid field name, according to the HTML5 spec
612/// EXPR := valid expression, as defined by Rust
613/// ```
614///
615/// `#[field]` can be applied any number of times on a field. `default` and
616/// `default_with` are mutually exclusive: at most _one_ of `default` or
617/// `default_with` can be present per field.
618///
619/// ```rust
620/// # #[macro_use] extern crate rocket;
621/// #[derive(FromForm)]
622/// struct MyStruct {
623///     #[field(name = uncased("number"))]
624///     #[field(default = 42)]
625///     field: usize,
626///     #[field(name = "renamed_field")]
627///     #[field(name = uncased("anotherName"))]
628///     #[field(validate = eq("banana"))]
629///     #[field(validate = neq("orange"))]
630///     other: String
631/// }
632/// ```
633///
634/// For tuples structs, the `field` attribute can be applied to the structure
635/// itself:
636///
637/// ```rust
638/// # #[macro_use] extern crate rocket;
639/// #[derive(FromForm)]
640/// #[field(default = 42, validate = eq(42))]
641/// struct Meaning(usize);
642/// ```
643///
644/// ## Field Attribute Parameters
645///
646///   * **`name`**
647///
648///     A `name` attribute changes the name to match against when parsing the
649///     form field. The value is either an exact string to match against
650///     (`"foo"`), or `uncased("foo")`, which causes the match to be
651///     case-insensitive but case-preserving. When more than one `name`
652///     attribute is applied, the field will match against _any_ of the names.
653///
654///   * **`validate = expr`**
655///
656///     The validation `expr` is run if the field type parses successfully. The
657///     expression must return a value of type `Result<(), form::Errors>`. On
658///     `Err`, the errors are added to the thus-far collected errors. If more
659///     than one `validate` attribute is applied, _all_ validations are run.
660///
661///   * **`default = expr`**
662///
663///     If `expr` is not literally `None`, the parameter sets the default value
664///     of the field to be `expr.into()`. If `expr` _is_ `None`, the parameter
665///     _unsets_ the default value of the field, if any. The expression is only
666///     evaluated if the attributed field is missing in the incoming form.
667///
668///     Except when `expr` is `None`, `expr` must be of type `T: Into<F>` where
669///     `F` is the field's type.
670///
671///   * **`default_with = expr`**
672///
673///     The parameter sets the default value of the field to be exactly `expr`
674///     which must be of type `Option<F>` where `F` is the field's type. If the
675///     expression evaluates to `None`, there is no default. Otherwise the value
676///     wrapped in `Some` is used. The expression is only evaluated if the
677///     attributed field is missing in the incoming form.
678///
679///     ```rust
680///     # #[macro_use] extern crate rocket;
681///     use std::num::NonZeroUsize;
682///
683///     #[derive(FromForm)]
684///     struct MyForm {
685///         // `NonZeroUsize::new()` return an `Option<NonZeroUsize>`.
686///         #[field(default_with = NonZeroUsize::new(42))]
687///         num: NonZeroUsize,
688///     }
689///     ```
690///
691/// [`FromForm`]: ../rocket/form/trait.FromForm.html
692/// [`form::Errors`]: ../rocket/form/struct.Errors.html
693///
694/// # Generics
695///
696/// The derive accepts any number of type generics and at most one lifetime
697/// generic. If a type generic is present, the generated implementation will
698/// require a bound of `FromForm<'r>` for the field type containing the generic.
699/// For example, for a struct `struct Foo<T>(Json<T>)`, the bound `Json<T>:
700/// FromForm<'r>` will be added to the generated implementation.
701///
702/// ```rust
703/// use rocket::form::FromForm;
704/// use rocket::serde::json::Json;
705///
706/// // The bounds `A: FromForm<'r>`, `B: FromForm<'r>` will be required.
707/// #[derive(FromForm)]
708/// struct FancyForm<A, B> {
709///     first: A,
710///     second: B,
711/// };
712///
713/// // The bound `Json<T>: FromForm<'r>` will be required.
714/// #[derive(FromForm)]
715/// struct JsonToken<T> {
716///     token: Json<T>,
717///     id: usize,
718/// }
719/// ```
720///
721/// If a lifetime generic is present, it is replaced with `'r` in the
722/// generated implementation `impl FromForm<'r>`:
723///
724/// ```rust
725/// # #[macro_use] extern crate rocket;
726/// // Generates `impl<'r> FromForm<'r> for MyWrapper<'r>`.
727/// #[derive(FromForm)]
728/// struct MyWrapper<'a>(&'a str);
729/// ```
730///
731/// Both type generics and one lifetime generic may be used:
732///
733/// ```rust
734/// use rocket::form::{self, FromForm};
735///
736/// // The bound `form::Result<'r, T>: FromForm<'r>` will be required.
737/// #[derive(FromForm)]
738/// struct SomeResult<'o, T>(form::Result<'o, T>);
739/// ```
740///
741/// The special bounds on `Json` and `Result` are required due to incomplete and
742/// incorrect support for lifetime generics in `async` blocks in Rust. See
743/// [rust-lang/#64552](https://github.com/rust-lang/rust/issues/64552) for
744/// further details.
745#[proc_macro_derive(FromForm, attributes(form, field))]
746pub fn derive_from_form(input: TokenStream) -> TokenStream {
747    emit!(derive::from_form::derive_from_form(input))
748}
749
750/// Derive for the [`Responder`] trait.
751///
752/// The [`Responder`] derive can be applied to enums and structs with named
753/// fields. When applied to enums, variants must have at least one field. When
754/// applied to structs, the struct must have at least one field.
755///
756/// ```rust
757/// # #[macro_use] extern crate rocket;
758/// # use std::fs::File;
759/// # use rocket::http::ContentType;
760/// # type OtherResponder = MyResponderA;
761/// #
762/// #[derive(Responder)]
763/// enum MyResponderA {
764///     A(String),
765///     B(File, ContentType),
766/// }
767///
768/// #[derive(Responder)]
769/// struct MyResponderB {
770///     inner: OtherResponder,
771///     header: ContentType,
772/// }
773/// ```
774///
775/// # Semantics
776///
777/// The derive generates an implementation of the [`Responder`] trait for the
778/// decorated enum or structure. The derive uses the _first_ field of a variant
779/// or structure to generate a [`Response`]. As such, the type of the first
780/// field must implement [`Responder`]. The remaining fields of a variant or
781/// structure are set as headers in the produced [`Response`] using
782/// [`Response::set_header()`]. As such, every other field (unless explicitly
783/// ignored, explained next) must implement `Into<Header>`.
784///
785/// Except for the first field, fields decorated with `#[response(ignore)]` are
786/// ignored by the derive:
787///
788/// ```rust
789/// # #[macro_use] extern crate rocket;
790/// # use std::fs::File;
791/// # use rocket::http::ContentType;
792/// # use rocket::fs::NamedFile;
793/// # type Other = usize;
794/// #
795/// #[derive(Responder)]
796/// enum MyResponder {
797///     A(String),
798///     B(File, ContentType, #[response(ignore)] Other),
799/// }
800///
801/// #[derive(Responder)]
802/// struct MyOtherResponder {
803///     inner: NamedFile,
804///     header: ContentType,
805///     #[response(ignore)]
806///     other: Other,
807/// }
808/// ```
809///
810/// Decorating the first field with `#[response(ignore)]` has no effect.
811///
812/// # Field Attribute
813///
814/// Additionally, the `response` attribute can be used on named structures and
815/// enum variants to override the status and/or content-type of the [`Response`]
816/// produced by the generated implementation. The `response` attribute used in
817/// these positions has the following grammar:
818///
819/// ```text
820/// response := parameter (',' parameter)?
821///
822/// parameter := 'status' '=' STATUS
823///            | 'content_type' '=' CONTENT_TYPE
824///
825/// STATUS := unsigned integer >= 100 and < 600
826/// CONTENT_TYPE := string literal, as defined by Rust, identifying a valid
827///                 Content-Type, as defined by Rocket
828/// ```
829///
830/// It can be used as follows:
831///
832/// ```rust
833/// # #[macro_use] extern crate rocket;
834/// # use rocket::http::ContentType;
835/// # use rocket::fs::NamedFile;
836/// # type Other = usize;
837/// # type InnerResponder = String;
838/// #
839/// #[derive(Responder)]
840/// enum Error {
841///     #[response(status = 500, content_type = "json")]
842///     A(String),
843///     #[response(status = 404)]
844///     B(NamedFile, ContentType),
845/// }
846///
847/// #[derive(Responder)]
848/// #[response(status = 400)]
849/// struct MyResponder {
850///     inner: InnerResponder,
851///     header: ContentType,
852///     #[response(ignore)]
853///     other: Other,
854/// }
855/// ```
856///
857/// The attribute accepts two key/value pairs: `status` and `content_type`. The
858/// value of `status` must be an unsigned integer representing a valid status
859/// code. The [`Response`] produced from the generated implementation will have
860/// its status overridden to this value.
861///
862/// The value of `content_type` must be a valid media-type in `top/sub` form or
863/// `shorthand` form. Examples include:
864///
865///   * `"text/html"`
866///   * `"application/x-custom"`
867///   * `"html"`
868///   * `"json"`
869///   * `"plain"`
870///   * `"binary"`
871///
872/// See [`ContentType::parse_flexible()`] for a full list of available
873/// shorthands. The [`Response`] produced from the generated implementation will
874/// have its content-type overridden to this value.
875///
876/// [`Responder`]: ../rocket/response/trait.Responder.html
877/// [`Response`]: ../rocket/struct.Response.html
878/// [`Response::set_header()`]: ../rocket/response/struct.Response.html#method.set_header
879/// [`ContentType::parse_flexible()`]: ../rocket/http/struct.ContentType.html#method.parse_flexible
880///
881/// # Generics
882///
883/// The derive accepts any number of type generics and at most one lifetime
884/// generic. If a type generic is present and the generic is used in the first
885/// field of a structure, the generated implementation will require a bound of
886/// `Responder<'r, 'o>` for the field type containing the generic. In all other
887/// fields, unless ignores, a bound of `Into<Header<'o>` is added.
888///
889/// For example, for a struct `struct Foo<T, H>(Json<T>, H)`, the derive adds:
890///
891///   * `Json<T>: Responder<'r, 'o>`
892///   * `H: Into<Header<'o>>`
893///
894/// ```rust
895/// # #[macro_use] extern crate rocket;
896/// use rocket::serde::Serialize;
897/// use rocket::serde::json::Json;
898/// use rocket::http::ContentType;
899/// use rocket::response::Responder;
900///
901/// // The bound `T: Responder` will be added.
902/// #[derive(Responder)]
903/// #[response(status = 404, content_type = "html")]
904/// struct NotFoundHtml<T>(T);
905///
906/// // The bound `Json<T>: Responder` will be added.
907/// #[derive(Responder)]
908/// struct NotFoundJson<T>(Json<T>);
909///
910/// // The bounds `Json<T>: Responder, E: Responder` will be added.
911/// #[derive(Responder)]
912/// enum MyResult<T, E> {
913///     Ok(Json<T>),
914///     #[response(status = 404)]
915///     Err(E, ContentType)
916/// }
917/// ```
918///
919/// If a lifetime generic is present, it will be replaced with `'o` in the
920/// generated implementation `impl Responder<'r, 'o>`:
921///
922/// ```rust
923/// # #[macro_use] extern crate rocket;
924/// // Generates `impl<'r, 'o> Responder<'r, 'o> for NotFoundHtmlString<'o>`.
925/// #[derive(Responder)]
926/// #[response(status = 404, content_type = "html")]
927/// struct NotFoundHtmlString<'a>(&'a str);
928/// ```
929///
930/// Both type generics and lifetime generic may be used:
931///
932/// ```rust
933/// # #[macro_use] extern crate rocket;
934/// # use rocket::response::Responder;
935/// #[derive(Responder)]
936/// struct SomeResult<'o, T>(Result<T, &'o str>);
937/// ```
938#[proc_macro_derive(Responder, attributes(response))]
939pub fn derive_responder(input: TokenStream) -> TokenStream {
940    emit!(derive::responder::derive_responder(input))
941}
942
943/// Derive for the [`UriDisplay<Query>`] trait.
944///
945/// The [`UriDisplay<Query>`] derive can be applied to enums and structs. When
946/// applied to an enum, the enum must have at least one variant. When applied to
947/// a struct, the struct must have at least one field.
948///
949/// ```rust
950/// # #[macro_use] extern crate rocket;
951/// #[derive(UriDisplayQuery)]
952/// enum Kind {
953///     A(String),
954///     B(usize),
955/// }
956///
957/// #[derive(UriDisplayQuery)]
958/// struct MyStruct {
959///     name: String,
960///     id: usize,
961///     kind: Kind,
962/// }
963/// ```
964///
965/// Each field's type is required to implement [`UriDisplay<Query>`].
966///
967/// The derive generates an implementation of the [`UriDisplay<Query>`] trait.
968/// The implementation calls [`Formatter::write_named_value()`] for every named
969/// field, using the field's name (unless overridden, explained next) as the
970/// `name` parameter, and [`Formatter::write_value()`] for every unnamed field
971/// in the order the fields are declared.
972///
973/// The derive accepts one field attribute: `field`, with the following syntax:
974///
975/// ```text
976/// field := 'name' '=' '"' FIELD_NAME '"'
977///        | 'value' '=' '"' FIELD_VALUE '"'
978///
979/// FIELD_NAME := valid HTTP field name
980/// FIELD_VALUE := valid HTTP field value
981/// ```
982///
983/// When applied to a struct, the attribute can only contain `name` and looks
984/// as follows:
985///
986/// ```rust
987/// # #[macro_use] extern crate rocket;
988/// # #[derive(UriDisplayQuery)]
989/// # struct Kind(String);
990/// #[derive(UriDisplayQuery)]
991/// struct MyStruct {
992///     name: String,
993///     id: usize,
994///     #[field(name = "type")]
995///     #[field(name = "kind")]
996///     kind: Kind,
997/// }
998/// ```
999///
1000/// The field attribute directs that a different field name be used when calling
1001/// [`Formatter::write_named_value()`] for the given field. The value of the
1002/// `name` attribute is used instead of the structure's actual field name. If
1003/// more than one `field` attribute is applied to a field, the _first_ name is
1004/// used. In the example above, the field `MyStruct::kind` is rendered with a
1005/// name of `type`.
1006///
1007/// The attribute can also be applied to variants of C-like enums; it may only
1008/// contain `value` and looks as follows:
1009///
1010/// ```rust
1011/// # #[macro_use] extern crate rocket;
1012/// #[derive(UriDisplayQuery)]
1013/// enum Kind {
1014///     File,
1015///     #[field(value = "str")]
1016///     #[field(value = "string")]
1017///     String,
1018///     Other
1019/// }
1020/// ```
1021///
1022/// The field attribute directs that a different value be used when calling
1023/// [`Formatter::write_named_value()`] for the given variant. The value of the
1024/// `value` attribute is used instead of the variant's actual name. If more than
1025/// one `field` attribute is applied to a variant, the _first_ value is used. In
1026/// the example above, the variant `Kind::String` will render with a value of
1027/// `str`.
1028///
1029/// [`UriDisplay<Query>`]: ../rocket/http/uri/fmt/trait.UriDisplay.html
1030/// [`Formatter::write_named_value()`]: ../rocket/http/uri/fmt/struct.Formatter.html#method.write_named_value
1031/// [`Formatter::write_value()`]: ../rocket/http/uri/fmt/struct.Formatter.html#method.write_value
1032#[proc_macro_derive(UriDisplayQuery, attributes(field))]
1033pub fn derive_uri_display_query(input: TokenStream) -> TokenStream {
1034    emit!(derive::uri_display::derive_uri_display_query(input))
1035}
1036
1037/// Derive for the [`UriDisplay<Path>`] trait.
1038///
1039/// The [`UriDisplay<Path>`] derive can only be applied to tuple structs with
1040/// one field.
1041///
1042/// ```rust
1043/// # #[macro_use] extern crate rocket;
1044/// #[derive(UriDisplayPath)]
1045/// struct Name(String);
1046///
1047/// #[derive(UriDisplayPath)]
1048/// struct Age(usize);
1049/// ```
1050///
1051/// The field's type is required to implement [`UriDisplay<Path>`].
1052///
1053/// The derive generates an implementation of the [`UriDisplay<Path>`] trait.
1054/// The implementation calls [`Formatter::write_value()`] for the field.
1055///
1056/// [`UriDisplay<Path>`]: ../rocket/http/uri/fmt/trait.UriDisplay.html
1057/// [`Formatter::write_value()`]: ../rocket/http/uri/fmt/struct.Formatter.html#method.write_value
1058#[proc_macro_derive(UriDisplayPath)]
1059pub fn derive_uri_display_path(input: TokenStream) -> TokenStream {
1060    emit!(derive::uri_display::derive_uri_display_path(input))
1061}
1062
1063/// Generates a `Vec` of [`Route`]s from a set of route paths.
1064///
1065/// The `routes!` macro expands a list of route paths into a `Vec` of their
1066/// corresponding [`Route`] structures. For example, given the following routes:
1067///
1068/// ```rust
1069/// # #[macro_use] extern crate rocket;
1070/// #
1071/// #[get("/")]
1072/// fn index() { /* .. */ }
1073///
1074/// mod person {
1075///     #[post("/hi/<person>")]
1076///     pub fn hello(person: String) { /* .. */ }
1077/// }
1078/// ```
1079///
1080/// The `routes!` macro can be used as:
1081///
1082/// ```rust
1083/// # #[macro_use] extern crate rocket;
1084/// #
1085/// # use rocket::http::Method;
1086/// #
1087/// # #[get("/")] fn index() { /* .. */ }
1088/// # mod person {
1089/// #   #[post("/hi/<person>")] pub fn hello(person: String) { /* .. */ }
1090/// # }
1091/// let my_routes = routes![index, person::hello];
1092/// assert_eq!(my_routes.len(), 2);
1093///
1094/// let index_route = &my_routes[0];
1095/// assert_eq!(index_route.method, Method::Get);
1096/// assert_eq!(index_route.name.as_ref().unwrap(), "index");
1097/// assert_eq!(index_route.uri.path(), "/");
1098///
1099/// let hello_route = &my_routes[1];
1100/// assert_eq!(hello_route.method, Method::Post);
1101/// assert_eq!(hello_route.name.as_ref().unwrap(), "hello");
1102/// assert_eq!(hello_route.uri.path(), "/hi/<person>");
1103/// ```
1104///
1105/// The grammar for `routes!` is defined as:
1106///
1107/// ```text
1108/// routes := PATH (',' PATH)*
1109///
1110/// PATH := a path, as defined by Rust
1111/// ```
1112///
1113/// [`Route`]: ../rocket/struct.Route.html
1114#[proc_macro]
1115pub fn routes(input: TokenStream) -> TokenStream {
1116    emit!(bang::routes_macro(input))
1117}
1118
1119/// Generates a `Vec` of [`Catcher`]s from a set of catcher paths.
1120///
1121/// The `catchers!` macro expands a list of catcher paths into a `Vec` of
1122/// their corresponding [`Catcher`] structures. For example, given the following
1123/// catchers:
1124///
1125/// ```rust
1126/// # #[macro_use] extern crate rocket;
1127/// #
1128/// #[catch(404)]
1129/// fn not_found() { /* .. */ }
1130///
1131/// mod inner {
1132///     #[catch(400)]
1133///     pub fn unauthorized() { /* .. */ }
1134/// }
1135///
1136/// #[catch(default)]
1137/// fn default_catcher() { /* .. */ }
1138/// ```
1139///
1140/// The `catchers!` macro can be used as:
1141///
1142/// ```rust
1143/// # #[macro_use] extern crate rocket;
1144/// #
1145/// # #[catch(404)] fn not_found() { /* .. */ }
1146/// # #[catch(default)] fn default_catcher() { /* .. */ }
1147/// # mod inner {
1148/// #     #[catch(400)] pub fn unauthorized() { /* .. */ }
1149/// # }
1150/// let my_catchers = catchers![not_found, inner::unauthorized, default_catcher];
1151/// assert_eq!(my_catchers.len(), 3);
1152///
1153/// let not_found = &my_catchers[0];
1154/// assert_eq!(not_found.code, Some(404));
1155///
1156/// let unauthorized = &my_catchers[1];
1157/// assert_eq!(unauthorized.code, Some(400));
1158///
1159/// let default = &my_catchers[2];
1160/// assert_eq!(default.code, None);
1161/// ```
1162///
1163/// The grammar for `catchers!` is defined as:
1164///
1165/// ```text
1166/// catchers := PATH (',' PATH)*
1167///
1168/// PATH := a path, as defined by Rust
1169/// ```
1170///
1171/// [`Catcher`]: ../rocket/struct.Catcher.html
1172#[proc_macro]
1173pub fn catchers(input: TokenStream) -> TokenStream {
1174    emit!(bang::catchers_macro(input))
1175}
1176
1177/// Type-safe, encoding-safe route and non-route URI generation.
1178///
1179/// The `uri!` macro creates type-safe, URL-safe URIs given a route and concrete
1180/// parameters for its URI or a URI string literal.
1181///
1182/// # String Literal Parsing
1183///
1184/// Given a string literal as input, `uri!` parses the string using
1185/// [`Uri::parse_any()`] and emits a `'static`, `const` value whose type is one
1186/// of [`Asterisk`], [`Origin`], [`Authority`], [`Absolute`], or [`Reference`],
1187/// reflecting the parsed value. If the type allows normalization, the value is
1188/// normalized before being emitted. Parse errors are caught and emitted at
1189/// compile-time.
1190///
1191/// The grammar for this variant of `uri!` is:
1192///
1193/// ```text
1194/// uri := STRING
1195///
1196/// STRING := an uncooked string literal, as defined by Rust (example: `"/hi"`)
1197/// ```
1198///
1199/// `STRING` is expected to be an undecoded URI of any variant.
1200///
1201/// ## Examples
1202///
1203/// ```rust
1204/// # #[macro_use] extern crate rocket;
1205/// use rocket::http::uri::Absolute;
1206///
1207/// // Values returned from `uri!` are `const` and `'static`.
1208/// const ROOT_CONST: Absolute<'static> = uri!("https://rocket.rs");
1209/// static ROOT_STATIC: Absolute<'static> = uri!("https://rocket.rs?root");
1210///
1211/// // Any variant can be parsed, but beware of ambiguities.
1212/// let asterisk = uri!("*");
1213/// let origin = uri!("/foo/bar/baz");
1214/// let authority = uri!("rocket.rs:443");
1215/// let absolute = uri!("https://rocket.rs:443");
1216/// let reference = uri!("foo?bar#baz");
1217///
1218/// # use rocket::http::uri::{Asterisk, Origin, Authority, Reference};
1219/// # // Ensure we get the types we expect.
1220/// # let asterisk: Asterisk = asterisk;
1221/// # let origin: Origin<'static> = origin;
1222/// # let authority: Authority<'static> = authority;
1223/// # let absolute: Absolute<'static> = absolute;
1224/// # let reference: Reference<'static> = reference;
1225/// ```
1226///
1227/// # Type-Safe Route URIs
1228///
1229/// A URI to a route name `foo` is generated using `uri!(foo(v1, v2, v3))` or
1230/// `uri!(foo(a = v1, b = v2, c = v3))`, where `v1`, `v2`, `v3` are the values
1231/// to fill in for route parameters named `a`, `b`, and `c`. If the named
1232/// parameter syntax is used (`a = v1`, etc.), parameters can appear in any
1233/// order.
1234///
1235/// More concretely, for the route `person` defined below:
1236///
1237/// ```rust
1238/// # #[macro_use] extern crate rocket;
1239/// #[get("/person/<name>?<age>")]
1240/// fn person(name: &str, age: Option<u8>) { }
1241/// ```
1242///
1243/// ...a URI can be created as follows:
1244///
1245/// ```rust
1246/// # #[macro_use] extern crate rocket;
1247/// # #[get("/person/<name>?<age>")]
1248/// # fn person(name: &str, age: Option<u8>) { }
1249/// // with unnamed parameters, in route path declaration order
1250/// let mike = uri!(person("Mike Smith", Some(28)));
1251/// assert_eq!(mike.to_string(), "/person/Mike%20Smith?age=28");
1252///
1253/// // with named parameters, order irrelevant
1254/// let mike = uri!(person(name = "Mike", age = Some(28)));
1255/// let mike = uri!(person(age = Some(28), name = "Mike"));
1256/// assert_eq!(mike.to_string(), "/person/Mike?age=28");
1257///
1258/// // with unnamed values, explicitly `None`.
1259/// let mike = uri!(person("Mike", None::<u8>));
1260/// assert_eq!(mike.to_string(), "/person/Mike");
1261///
1262/// // with named values, explicitly `None`
1263/// let option: Option<u8> = None;
1264/// let mike = uri!(person(name = "Mike", age = None::<u8>));
1265/// assert_eq!(mike.to_string(), "/person/Mike");
1266/// ```
1267///
1268/// For optional query parameters, those of type `Option` or `Result`, a `_` can
1269/// be used in-place of `None` or `Err`:
1270///
1271/// ```rust
1272/// # #[macro_use] extern crate rocket;
1273/// # #[get("/person/<name>?<age>")]
1274/// # fn person(name: &str, age: Option<u8>) { }
1275/// // with named values ignored
1276/// let mike = uri!(person(name = "Mike", age = _));
1277/// assert_eq!(mike.to_string(), "/person/Mike");
1278///
1279/// // with named values ignored
1280/// let mike = uri!(person(age = _, name = "Mike"));
1281/// assert_eq!(mike.to_string(), "/person/Mike");
1282///
1283/// // with unnamed values ignored
1284/// let mike = uri!(person("Mike", _));
1285/// assert_eq!(mike.to_string(), "/person/Mike");
1286/// ```
1287///
1288/// It is a type error to attempt to ignore query parameters that are neither
1289/// `Option` or `Result`. Path parameters can never be ignored. A path parameter
1290/// of type `Option<T>` or `Result<T, E>` must be filled by a value that can
1291/// target a type of `T`:
1292///
1293/// ```rust
1294/// # #[macro_use] extern crate rocket;
1295/// #[get("/person/<name>")]
1296/// fn maybe(name: Option<&str>) { }
1297///
1298/// let bob1 = uri!(maybe(name = "Bob"));
1299/// let bob2 = uri!(maybe("Bob Smith"));
1300/// assert_eq!(bob1.to_string(), "/person/Bob");
1301/// assert_eq!(bob2.to_string(), "/person/Bob%20Smith");
1302///
1303/// #[get("/person/<age>")]
1304/// fn ok(age: Result<u8, &str>) { }
1305///
1306/// let kid1 = uri!(ok(age = 10));
1307/// let kid2 = uri!(ok(12));
1308/// assert_eq!(kid1.to_string(), "/person/10");
1309/// assert_eq!(kid2.to_string(), "/person/12");
1310/// ```
1311///
1312/// Values for ignored route segments can be of any type as long as the type
1313/// implements [`UriDisplay`] for the appropriate URI part. If a route URI
1314/// contains ignored segments, the route URI invocation cannot use named
1315/// arguments.
1316///
1317/// ```rust
1318/// # #[macro_use] extern crate rocket;
1319/// #[get("/ignore/<_>/<other>")]
1320/// fn ignore(other: &str) { }
1321///
1322/// let bob = uri!(ignore("Bob Hope", "hello"));
1323/// let life = uri!(ignore(42, "cat&dog"));
1324/// assert_eq!(bob.to_string(), "/ignore/Bob%20Hope/hello");
1325/// assert_eq!(life.to_string(), "/ignore/42/cat%26dog");
1326/// ```
1327///
1328/// ## Prefixes and Suffixes
1329///
1330/// A route URI can be be optionally prefixed and/or suffixed by a URI generated
1331/// from a string literal or an arbitrary expression. This takes the form
1332/// `uri!(prefix, foo(v1, v2, v3), suffix)`, where both `prefix` and `suffix`
1333/// are optional, and either `prefix` or `suffix` may be `_` to specify the
1334/// value as empty.
1335///
1336/// ```rust
1337/// # #[macro_use] extern crate rocket;
1338/// #[get("/person/<name>?<age>")]
1339/// fn person(name: &str, age: Option<u8>) { }
1340///
1341/// // with a specific mount-point of `/api`.
1342/// let bob = uri!("/api", person("Bob", Some(28)));
1343/// assert_eq!(bob.to_string(), "/api/person/Bob?age=28");
1344///
1345/// // with an absolute URI as a prefix
1346/// let bob = uri!("https://rocket.rs", person("Bob", Some(28)));
1347/// assert_eq!(bob.to_string(), "https://rocket.rs/person/Bob?age=28");
1348///
1349/// // with another absolute URI as a prefix
1350/// let bob = uri!("https://rocket.rs/foo", person("Bob", Some(28)));
1351/// assert_eq!(bob.to_string(), "https://rocket.rs/foo/person/Bob?age=28");
1352///
1353/// // with an expression as a prefix
1354/// let host = uri!("http://bob.me");
1355/// let bob = uri!(host, person("Bob", Some(28)));
1356/// assert_eq!(bob.to_string(), "http://bob.me/person/Bob?age=28");
1357///
1358/// // with a suffix but no prefix
1359/// let bob = uri!(_, person("Bob", Some(28)), "#baz");
1360/// assert_eq!(bob.to_string(), "/person/Bob?age=28#baz");
1361///
1362/// // with both a prefix and suffix
1363/// let bob = uri!("https://rocket.rs/", person("Bob", Some(28)), "#woo");
1364/// assert_eq!(bob.to_string(), "https://rocket.rs/person/Bob?age=28#woo");
1365///
1366/// // with an expression suffix. if the route URI already has a query, the
1367/// // query part is ignored. otherwise it is added.
1368/// let suffix = uri!("?woo#bam");
1369/// let bob = uri!(_, person("Bob", Some(28)), suffix.clone());
1370/// assert_eq!(bob.to_string(), "/person/Bob?age=28#bam");
1371///
1372/// let bob = uri!(_, person("Bob", None::<u8>), suffix.clone());
1373/// assert_eq!(bob.to_string(), "/person/Bob?woo#bam");
1374/// ```
1375///
1376/// ## Grammar
1377///
1378/// The grammar for this variant of the `uri!` macro is:
1379///
1380/// ```text
1381/// uri := (prefix ',')? route
1382///      | prefix ',' route ',' suffix
1383///
1384/// prefix := STRING | expr                     ; `Origin` or `Absolute`
1385/// suffix := STRING | expr                     ; `Reference` or `Absolute`
1386///
1387/// route := PATH '(' (named | unnamed) ')'
1388///
1389/// named := IDENT = expr (',' named)? ','?
1390/// unnamed := expr (',' unnamed)? ','?
1391///
1392/// expr := EXPR | '_'
1393///
1394/// EXPR := a valid Rust expression (examples: `foo()`, `12`, `"hey"`)
1395/// IDENT := a valid Rust identifier (examples: `name`, `age`)
1396/// STRING := an uncooked string literal, as defined by Rust (example: `"hi"`)
1397/// PATH := a path, as defined by Rust (examples: `route`, `my_mod::route`)
1398/// ```
1399///
1400/// ## Dynamic Semantics
1401///
1402/// The returned value is that of the prefix (minus any query part) concatenated
1403/// with the route URI concatenated with the query (if the route has no query
1404/// part) and fragment parts of the suffix. The route URI is generated by
1405/// interpolating the declared route URI with the URL-safe version of the route
1406/// values in `uri!()`. The generated URI is guaranteed to be URI-safe.
1407///
1408/// Each route value is rendered in its appropriate place in the URI using the
1409/// [`UriDisplay`] implementation for the value's type. The `UriDisplay`
1410/// implementation ensures that the rendered value is URL-safe.
1411///
1412/// A `uri!()` invocation allocated at-most once.
1413///
1414/// ## Static Semantics
1415///
1416/// The `uri!` macro returns one of [`Origin`], [`Absolute`], or [`Reference`],
1417/// depending on the types of the prefix and suffix, if any. The table below
1418/// specifies all combinations:
1419///
1420/// | Prefix     | Suffix      | Output      |
1421/// |------------|-------------|-------------|
1422/// | None       | None        | `Origin`    |
1423/// | None       | `Absolute`  | `Origin`    |
1424/// | None       | `Reference` | `Reference` |
1425/// | `Origin`   | None        | `Origin`    |
1426/// | `Origin`   | `Absolute`  | `Origin`    |
1427/// | `Origin`   | `Reference` | `Reference` |
1428/// | `Absolute` | None        | `Absolute`  |
1429/// | `Absolute` | `Absolute`  | `Absolute`  |
1430/// | `Absolute` | `Reference` | `Reference` |
1431///
1432/// A `uri!` invocation only typechecks if the type of every route URI value in
1433/// the invocation matches the type declared for the parameter in the given
1434/// route, after conversion with [`FromUriParam`], or if a value is ignored
1435/// using `_` and the corresponding route type implements [`Ignorable`].
1436///
1437/// ### Conversion
1438///
1439/// The [`FromUriParam`] trait is used to typecheck and perform a conversion for
1440/// each value passed to `uri!`. If a `FromUriParam<P, S> for T` implementation
1441/// exists for a type `T` for part URI part `P`, then a value of type `S` can be
1442/// used in `uri!` macro for a route URI parameter declared with a type of `T`
1443/// in part `P`. For example, the following implementation, provided by Rocket,
1444/// allows an `&str` to be used in a `uri!` invocation for route URI parameters
1445/// declared as `String`:
1446///
1447/// ```rust,ignore
1448/// impl<P: Part, 'a> FromUriParam<P, &'a str> for String { .. }
1449/// ```
1450///
1451/// ### Ignorables
1452///
1453/// Query parameters can be ignored using `_` in place of an expression. The
1454/// corresponding type in the route URI must implement [`Ignorable`]. Ignored
1455/// parameters are not interpolated into the resulting `Origin`. Path parameters
1456/// are not ignorable.
1457///
1458/// [`Uri`]: ../rocket/http/uri/enum.Uri.html
1459/// [`Uri::parse_any()`]: ../rocket/http/uri/enum.Uri.html#method.parse_any
1460/// [`Origin`]: ../rocket/http/uri/struct.Origin.html
1461/// [`Asterisk`]: ../rocket/http/uri/struct.Asterisk.html
1462/// [`Authority`]: ../rocket/http/uri/struct.Authority.html
1463/// [`Absolute`]: ../rocket/http/uri/struct.Absolute.html
1464/// [`Reference`]: ../rocket/http/uri/struct.Reference.html
1465/// [`FromUriParam`]: ../rocket/http/uri/fmt/trait.FromUriParam.html
1466/// [`UriDisplay`]: ../rocket/http/uri/fmt/trait.UriDisplay.html
1467/// [`Ignorable`]: ../rocket/http/uri/fmt/trait.Ignorable.html
1468#[proc_macro]
1469pub fn uri(input: TokenStream) -> TokenStream {
1470    emit!(bang::uri_macro(input))
1471}
1472
1473/// Internal macro: `rocket_internal_uri!`.
1474#[proc_macro]
1475#[doc(hidden)]
1476pub fn rocket_internal_uri(input: TokenStream) -> TokenStream {
1477    emit!(bang::uri_internal_macro(input))
1478}
1479
1480/// Internal macro: `__typed_stream!`.
1481#[proc_macro]
1482#[doc(hidden)]
1483pub fn __typed_stream(input: TokenStream) -> TokenStream {
1484    emit!(bang::typed_stream(input))
1485}
1486
1487/// Private Rocket internal macro: `internal_guide_tests!`.
1488#[proc_macro]
1489#[doc(hidden)]
1490pub fn internal_guide_tests(input: TokenStream) -> TokenStream {
1491    emit!(bang::guide_tests_internal(input))
1492}
1493
1494/// Private Rocket internal macro: `export!`.
1495#[proc_macro]
1496#[doc(hidden)]
1497pub fn export(input: TokenStream) -> TokenStream {
1498    emit!(bang::export_internal(input))
1499}