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