2018-08-07 02:58:07 +00:00
|
|
|
#![recursion_limit="128"]
|
2018-04-12 23:07:37 +00:00
|
|
|
|
2020-10-21 11:54:24 +00:00
|
|
|
#![doc(html_root_url = "https://api.rocket.rs/master")]
|
2020-06-11 09:30:14 +00:00
|
|
|
#![doc(html_favicon_url = "https://rocket.rs/images/favicon.ico")]
|
|
|
|
#![doc(html_logo_url = "https://rocket.rs/images/logo-boxed.png")]
|
2018-10-07 04:16:02 +00:00
|
|
|
|
2021-04-29 04:58:14 +00:00
|
|
|
#![warn(rust_2018_idioms, missing_docs)]
|
2019-06-13 01:59:25 +00:00
|
|
|
|
2018-10-04 10:54:46 +00:00
|
|
|
//! # Rocket - Code Generation
|
|
|
|
//!
|
|
|
|
//! This crate implements the code generation portions of Rocket. This includes
|
|
|
|
//! custom derives, custom attributes, and procedural macros. The documentation
|
|
|
|
//! here is purely technical. The code generation facilities are documented
|
2020-10-21 11:54:24 +00:00
|
|
|
//! thoroughly in the [Rocket programming guide](https://rocket.rs/master/guide).
|
2018-10-04 10:54:46 +00:00
|
|
|
//!
|
2018-10-28 11:07:46 +00:00
|
|
|
//! # Usage
|
|
|
|
//!
|
|
|
|
//! You **_should not_** directly depend on this library. To use the macros,
|
|
|
|
//! attributes, and derives in this crate, it suffices to depend on `rocket` in
|
|
|
|
//! `Cargo.toml`:
|
|
|
|
//!
|
|
|
|
//! ```toml
|
|
|
|
//! [dependencies]
|
2019-05-13 23:18:48 +00:00
|
|
|
//! rocket = "0.5.0-dev"
|
2018-10-28 11:07:46 +00:00
|
|
|
//! ```
|
|
|
|
//!
|
2018-10-30 09:53:19 +00:00
|
|
|
//! And to import all macros, attributes, and derives via `#[macro_use]` in the
|
|
|
|
//! crate root:
|
2018-10-28 11:07:46 +00:00
|
|
|
//!
|
|
|
|
//! ```rust
|
|
|
|
//! #[macro_use] extern crate rocket;
|
|
|
|
//! # #[get("/")] fn hello() { }
|
2021-04-08 08:07:52 +00:00
|
|
|
//! # fn main() { rocket::build().mount("/", routes![hello]); }
|
2018-10-28 11:07:46 +00:00
|
|
|
//! ```
|
|
|
|
//!
|
2018-10-30 09:53:19 +00:00
|
|
|
//! Or, alternatively, selectively import from the top-level scope:
|
|
|
|
//!
|
|
|
|
//! ```rust
|
|
|
|
//! # extern crate rocket;
|
|
|
|
//!
|
|
|
|
//! use rocket::{get, routes};
|
|
|
|
//! # #[get("/")] fn hello() { }
|
2021-04-08 08:07:52 +00:00
|
|
|
//! # fn main() { rocket::build().mount("/", routes![hello]); }
|
2018-10-30 09:53:19 +00:00
|
|
|
//! ```
|
|
|
|
//!
|
2018-10-04 10:54:46 +00:00
|
|
|
//! # Debugging Codegen
|
|
|
|
//!
|
2018-10-18 11:00:36 +00:00
|
|
|
//! When the `ROCKET_CODEGEN_DEBUG` environment variable is set, this crate
|
|
|
|
//! logs, at compile-time and to the console, the items it generates. For
|
|
|
|
//! example, you might run the following to build a Rocket application with
|
|
|
|
//! codegen debug logging enabled:
|
2018-10-04 10:54:46 +00:00
|
|
|
//!
|
2018-10-05 04:44:42 +00:00
|
|
|
//! ```sh
|
2018-10-04 10:54:46 +00:00
|
|
|
//! ROCKET_CODEGEN_DEBUG=1 cargo build
|
|
|
|
//! ```
|
|
|
|
|
2018-04-12 23:07:37 +00:00
|
|
|
#[macro_use] extern crate quote;
|
2019-06-13 01:59:25 +00:00
|
|
|
|
|
|
|
use rocket_http as http;
|
2018-09-20 04:14:30 +00:00
|
|
|
|
2018-11-30 16:43:31 +00:00
|
|
|
#[macro_use]
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
mod exports;
|
2018-11-30 16:43:31 +00:00
|
|
|
mod proc_macro_ext;
|
2018-08-07 02:58:07 +00:00
|
|
|
mod derive;
|
2018-09-16 07:33:16 +00:00
|
|
|
mod attribute;
|
2018-09-16 07:44:47 +00:00
|
|
|
mod bang;
|
2018-08-07 02:58:07 +00:00
|
|
|
mod http_codegen;
|
2018-09-16 07:33:16 +00:00
|
|
|
mod syn_ext;
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
mod name;
|
2018-04-12 23:07:37 +00:00
|
|
|
|
2019-06-13 01:59:25 +00:00
|
|
|
use crate::http::Method;
|
2018-09-20 04:14:30 +00:00
|
|
|
use proc_macro::TokenStream;
|
2018-04-12 23:07:37 +00:00
|
|
|
|
2019-09-20 20:43:05 +00:00
|
|
|
static URI_MACRO_PREFIX: &str = "rocket_uri_macro_";
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
static ROCKET_IDENT_PREFIX: &str = "__rocket_";
|
2018-09-20 04:14:30 +00:00
|
|
|
|
2018-10-05 04:44:42 +00:00
|
|
|
macro_rules! emit {
|
|
|
|
($tokens:expr) => ({
|
2019-09-21 20:36:57 +00:00
|
|
|
use devise::ext::SpanDiagnosticExt;
|
|
|
|
|
|
|
|
let mut tokens = $tokens;
|
2019-06-13 01:59:25 +00:00
|
|
|
if std::env::var_os("ROCKET_CODEGEN_DEBUG").is_some() {
|
2019-09-21 20:36:57 +00:00
|
|
|
let debug_tokens = proc_macro2::Span::call_site()
|
2018-10-05 04:44:42 +00:00
|
|
|
.note("emitting Rocket code generation debug output")
|
|
|
|
.note(tokens.to_string())
|
2020-07-21 17:23:59 +00:00
|
|
|
.emit_as_item_tokens();
|
2019-09-21 20:36:57 +00:00
|
|
|
|
|
|
|
tokens.extend(debug_tokens);
|
2018-10-05 04:44:42 +00:00
|
|
|
}
|
|
|
|
|
2019-09-21 20:36:57 +00:00
|
|
|
tokens.into()
|
2018-10-05 04:44:42 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-09-20 04:14:30 +00:00
|
|
|
macro_rules! route_attribute {
|
|
|
|
($name:ident => $method:expr) => (
|
2018-10-18 11:00:36 +00:00
|
|
|
/// Attribute to generate a [`Route`] and associated metadata.
|
|
|
|
///
|
|
|
|
/// This and all other route attributes can only be applied to free
|
|
|
|
/// functions:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #
|
|
|
|
/// #[get("/")]
|
|
|
|
/// fn index() -> &'static str {
|
|
|
|
/// "Hello, world!"
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// There are 7 method-specific route attributes:
|
|
|
|
///
|
2020-03-09 08:58:20 +00:00
|
|
|
/// * [`get`] - `GET` specific route
|
|
|
|
/// * [`put`] - `PUT` specific route
|
|
|
|
/// * [`post`] - `POST` specific route
|
|
|
|
/// * [`delete`] - `DELETE` specific route
|
|
|
|
/// * [`head`] - `HEAD` specific route
|
|
|
|
/// * [`options`] - `OPTIONS` specific route
|
|
|
|
/// * [`patch`] - `PATCH` specific route
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
/// Additionally, [`route`] allows the method and uri to be explicitly
|
2020-03-09 08:58:20 +00:00
|
|
|
/// specified:
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
/// #[route(GET, uri = "/")]
|
2018-10-18 11:00:36 +00:00
|
|
|
/// fn index() -> &'static str {
|
|
|
|
/// "Hello, world!"
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
2020-03-09 08:58:20 +00:00
|
|
|
/// [`get`]: attr.get.html
|
|
|
|
/// [`put`]: attr.put.html
|
|
|
|
/// [`post`]: attr.post.html
|
|
|
|
/// [`delete`]: attr.delete.html
|
|
|
|
/// [`head`]: attr.head.html
|
|
|
|
/// [`options`]: attr.options.html
|
|
|
|
/// [`patch`]: attr.patch.html
|
|
|
|
/// [`route`]: attr.route.html
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// # Grammar
|
|
|
|
///
|
|
|
|
/// The grammar for all method-specific route attributes is defined as:
|
|
|
|
///
|
|
|
|
/// ```text
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
/// route := '"' uri ('?' query)? '"' (',' parameter)*
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
/// uri := ('/' segment)*
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// query := segment ('&' segment)*
|
|
|
|
///
|
|
|
|
/// segment := URI_SEG
|
|
|
|
/// | SINGLE_PARAM
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
/// | TRAILING_PARAM
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// parameter := 'rank' '=' INTEGER
|
|
|
|
/// | 'format' '=' '"' MEDIA_TYPE '"'
|
|
|
|
/// | 'data' '=' '"' SINGLE_PARAM '"'
|
|
|
|
///
|
|
|
|
/// SINGLE_PARAM := '<' IDENT '>'
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
/// TRAILING_PARAM := '<' IDENT '..>'
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// URI_SEG := valid, non-percent-encoded HTTP URI segment
|
|
|
|
/// MEDIA_TYPE := valid HTTP media type or known shorthand
|
|
|
|
///
|
|
|
|
/// INTEGER := unsigned integer, as defined by Rust
|
|
|
|
/// IDENT := valid identifier, as defined by Rust, except `_`
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The generic route attribute is defined as:
|
|
|
|
///
|
|
|
|
/// ```text
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
/// generic-route := METHOD ',' 'uri' '=' route
|
2018-10-18 11:00:36 +00:00
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// # Typing Requirements
|
|
|
|
///
|
|
|
|
/// Every identifier that appears in a dynamic parameter (`SINGLE_PARAM`
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
/// or `TRAILING_PARAM`) must appear as an argument to the function. For
|
2018-10-18 11:00:36 +00:00
|
|
|
/// example, the following route requires the decorated function to have
|
|
|
|
/// the arguments `foo`, `baz`, `msg`, `rest`, and `form`:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// # use rocket::form::Form;
|
2018-10-18 11:00:36 +00:00
|
|
|
/// # use std::path::PathBuf;
|
|
|
|
/// # #[derive(FromForm)] struct F { a: usize }
|
|
|
|
/// #[get("/<foo>/bar/<baz..>?<msg>&closed&<rest..>", data = "<form>")]
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// # fn f(foo: usize, baz: PathBuf, msg: String, rest: F, form: Form<F>) { }
|
2018-10-18 11:00:36 +00:00
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The type of each function argument corresponding to a dynamic
|
|
|
|
/// parameter is required to implement one of Rocket's guard traits. The
|
|
|
|
/// exact trait that is required to be implemented depends on the kind
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
/// of dynamic parameter (`SINGLE` or `TRAILING`) and where in the route
|
2018-10-18 11:00:36 +00:00
|
|
|
/// attribute the parameter appears. The table below summarizes trait
|
|
|
|
/// requirements:
|
|
|
|
///
|
|
|
|
/// | position | kind | trait |
|
|
|
|
/// |----------|-------------|-------------------|
|
|
|
|
/// | path | `<ident>` | [`FromParam`] |
|
|
|
|
/// | path | `<ident..>` | [`FromSegments`] |
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
/// | query | `<ident>` | [`FromForm`] |
|
2021-03-28 14:07:15 +00:00
|
|
|
/// | query | `<ident..>` | [`FromForm`] |
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// | data | `<ident>` | [`FromData`] |
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// The type of each function argument that _does not_ have a
|
|
|
|
/// corresponding dynamic parameter is required to implement the
|
|
|
|
/// [`FromRequest`] trait.
|
|
|
|
///
|
|
|
|
/// The return type of the decorated function must implement the
|
|
|
|
/// [`Responder`] trait.
|
|
|
|
///
|
|
|
|
/// [`FromParam`]: ../rocket/request/trait.FromParam.html
|
|
|
|
/// [`FromSegments`]: ../rocket/request/trait.FromSegments.html
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// [`FromFormField`]: ../rocket/request/trait.FromFormField.html
|
|
|
|
/// [`FromForm`]: ../rocket/form/trait.FromForm.html
|
|
|
|
/// [`FromData`]: ../rocket/data/trait.FromData.html
|
2018-10-18 11:00:36 +00:00
|
|
|
/// [`FromRequest`]: ../rocket/request/trait.FromRequest.html
|
|
|
|
/// [`Route`]: ../rocket/struct.Route.html
|
|
|
|
/// [`Responder`]: ../rocket/response/trait.Responder.html
|
|
|
|
///
|
|
|
|
/// # Semantics
|
|
|
|
///
|
|
|
|
/// The attribute generates three items:
|
|
|
|
///
|
|
|
|
/// 1. A route [`Handler`].
|
|
|
|
///
|
|
|
|
/// The generated handler validates and generates all arguments for
|
|
|
|
/// the generated function according to the trait that their type
|
|
|
|
/// must implement. The order in which arguments are processed is:
|
|
|
|
///
|
|
|
|
/// 1. Request guards from left to right.
|
|
|
|
///
|
|
|
|
/// If a request guard fails, the request is forwarded if the
|
|
|
|
/// [`Outcome`] is `Forward` or failed if the [`Outcome`] is
|
|
|
|
/// `Failure`. See [`FromRequest` Outcomes] for further
|
|
|
|
/// detail.
|
|
|
|
///
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
/// 2. Path and query guards in an unspecified order. If a path
|
|
|
|
/// or query guard fails, the request is forwarded.
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
/// 3. Data guard, if any.
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// If a data guard fails, the request is forwarded if the
|
|
|
|
/// [`Outcome`] is `Forward` or failed if the [`Outcome`] is
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// `Failure`. See [`FromData` Outcomes] for further detail.
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// If all validation succeeds, the decorated function is called.
|
|
|
|
/// The returned value is used to generate a [`Response`] via the
|
|
|
|
/// type's [`Responder`] implementation.
|
|
|
|
///
|
|
|
|
/// 2. A static structure used by [`routes!`] to generate a [`Route`].
|
|
|
|
///
|
|
|
|
/// The static structure (and resulting [`Route`]) is populated
|
|
|
|
/// with the name (the function's name), path, query, rank, and
|
|
|
|
/// format from the route attribute. The handler is set to the
|
|
|
|
/// generated handler.
|
|
|
|
///
|
|
|
|
/// 3. A macro used by [`uri!`] to type-check and generate an
|
|
|
|
/// [`Origin`].
|
|
|
|
///
|
2021-04-14 01:58:05 +00:00
|
|
|
/// [`Handler`]: rocket::route::Handler
|
2018-10-18 11:00:36 +00:00
|
|
|
/// [`routes!`]: macro.routes.html
|
|
|
|
/// [`uri!`]: macro.uri.html
|
2021-03-20 01:09:13 +00:00
|
|
|
/// [`Origin`]: rocket::http::uri::Origin
|
|
|
|
/// [`Outcome`]: rocket::outcome::Outcome
|
|
|
|
/// [`Response`]: rocket::Response
|
|
|
|
/// [`FromRequest` Outcomes]: rocket::request::FromRequest#outcomes
|
|
|
|
/// [`FromData` Outcomes]: rocket::data::FromData#outcomes
|
2018-09-20 04:14:30 +00:00
|
|
|
#[proc_macro_attribute]
|
|
|
|
pub fn $name(args: TokenStream, input: TokenStream) -> TokenStream {
|
2018-10-05 04:44:42 +00:00
|
|
|
emit!(attribute::route::route_attribute($method, args, input))
|
2018-09-20 04:14:30 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
2018-10-04 10:54:46 +00:00
|
|
|
|
2018-09-20 04:14:30 +00:00
|
|
|
route_attribute!(route => None);
|
|
|
|
route_attribute!(get => Method::Get);
|
|
|
|
route_attribute!(put => Method::Put);
|
|
|
|
route_attribute!(post => Method::Post);
|
|
|
|
route_attribute!(delete => Method::Delete);
|
|
|
|
route_attribute!(head => Method::Head);
|
|
|
|
route_attribute!(patch => Method::Patch);
|
|
|
|
route_attribute!(options => Method::Options);
|
2018-04-12 23:07:37 +00:00
|
|
|
|
2018-10-18 11:00:36 +00:00
|
|
|
/// Attribute to generate a [`Catcher`] and associated metadata.
|
|
|
|
///
|
|
|
|
/// This attribute can only be applied to free functions:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #
|
|
|
|
/// use rocket::Request;
|
2020-07-30 06:07:22 +00:00
|
|
|
/// use rocket::http::Status;
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// #[catch(404)]
|
|
|
|
/// fn not_found(req: &Request) -> String {
|
|
|
|
/// format!("Sorry, {} does not exist.", req.uri())
|
|
|
|
/// }
|
2020-07-30 06:07:22 +00:00
|
|
|
///
|
|
|
|
/// #[catch(default)]
|
|
|
|
/// fn default(status: Status, req: &Request) -> String {
|
2021-04-28 11:54:06 +00:00
|
|
|
/// format!("{} ({})", status, req.uri())
|
2020-07-30 06:07:22 +00:00
|
|
|
/// }
|
2018-10-18 11:00:36 +00:00
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// # Grammar
|
|
|
|
///
|
|
|
|
/// The grammar for the `#[catch]` attributes is defined as:
|
|
|
|
///
|
|
|
|
/// ```text
|
2020-07-30 06:07:22 +00:00
|
|
|
/// catch := STATUS | 'default'
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// STATUS := valid HTTP status code (integer in [200, 599])
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// # Typing Requirements
|
|
|
|
///
|
2020-07-30 06:07:22 +00:00
|
|
|
/// The decorated function may take zero, one, or two arguments. It's type
|
|
|
|
/// signature must be one of the following, where `R:`[`Responder`]:
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
2020-07-30 06:07:22 +00:00
|
|
|
/// * `fn() -> R`
|
|
|
|
/// * `fn(`[`&Request`]`) -> R`
|
|
|
|
/// * `fn(`[`Status`]`, `[`&Request`]`) -> R`
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// # Semantics
|
|
|
|
///
|
|
|
|
/// The attribute generates two items:
|
|
|
|
///
|
2021-04-14 01:58:05 +00:00
|
|
|
/// 1. An error [`Handler`].
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// The generated handler calls the decorated function, passing in the
|
2020-07-30 06:07:22 +00:00
|
|
|
/// [`Status`] and [`&Request`] values if requested. The returned value is
|
|
|
|
/// used to generate a [`Response`] via the type's [`Responder`]
|
|
|
|
/// implementation.
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
|
|
|
/// 2. A static structure used by [`catchers!`] to generate a [`Catcher`].
|
|
|
|
///
|
2020-07-30 06:07:22 +00:00
|
|
|
/// The static structure (and resulting [`Catcher`]) is populated with the
|
|
|
|
/// name (the function's name) and status code from the route attribute or
|
|
|
|
/// `None` if `default`. The handler is set to the generated handler.
|
2018-10-18 11:00:36 +00:00
|
|
|
///
|
2021-03-20 01:09:13 +00:00
|
|
|
/// [`&Request`]: rocket::Request
|
|
|
|
/// [`Status`]: rocket::http::Status
|
2021-04-14 01:58:05 +00:00
|
|
|
/// [`Handler`]: rocket::catcher::Handler
|
2018-10-18 11:00:36 +00:00
|
|
|
/// [`catchers!`]: macro.catchers.html
|
2021-03-20 01:09:13 +00:00
|
|
|
/// [`Catcher`]: rocket::Catcher
|
|
|
|
/// [`Response`]: rocket::Response
|
|
|
|
/// [`Responder`]: rocket::Responder
|
2018-10-18 11:00:36 +00:00
|
|
|
#[proc_macro_attribute]
|
|
|
|
pub fn catch(args: TokenStream, input: TokenStream) -> TokenStream {
|
|
|
|
emit!(attribute::catch::catch_attribute(args, input))
|
|
|
|
}
|
|
|
|
|
2021-04-28 08:41:13 +00:00
|
|
|
/// Retrofits supports for `async fn` in unit tests.
|
|
|
|
///
|
|
|
|
/// Simply decorate a test `async fn` with `#[async_test]` instead of `#[test]`:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #[cfg(test)]
|
|
|
|
/// mod tests {
|
|
|
|
/// #[async_test]
|
|
|
|
/// async fn test() {
|
|
|
|
/// /* .. */
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The attribute rewrites the function to execute inside of a Rocket-compatible
|
|
|
|
/// async runtime.
|
2019-08-24 17:27:10 +00:00
|
|
|
#[proc_macro_attribute]
|
|
|
|
pub fn async_test(args: TokenStream, input: TokenStream) -> TokenStream {
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
emit!(attribute::entry::async_test_attribute(args, input))
|
2020-06-14 15:57:55 +00:00
|
|
|
}
|
|
|
|
|
2021-04-29 04:58:14 +00:00
|
|
|
/// Retrofits `async fn` support in `main` functions.
|
|
|
|
///
|
|
|
|
/// A `main` `async fn` function decorated with `#[rocket::main]` is transformed
|
|
|
|
/// into a regular `main` function that internally initalizes a Rocket-specific
|
|
|
|
/// tokio runtime and runs the attributed `async fn` inside of it:
|
|
|
|
///
|
|
|
|
/// ```rust,no_run
|
|
|
|
/// #[rocket::main]
|
|
|
|
/// async fn main() -> Result<(), rocket::Error> {
|
|
|
|
/// rocket::build()
|
|
|
|
/// .ignite().await?
|
|
|
|
/// .launch().await
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// It should be used only when inspection of an ignited instance of `Rocket` is
|
|
|
|
/// required, or when the return value of `launch()` is to be inspected:
|
|
|
|
///
|
|
|
|
/// ```rust,no_run
|
|
|
|
/// #[rocket::main]
|
|
|
|
/// async fn main() -> Result<(), rocket::Error> {
|
|
|
|
/// let rocket = rocket::build().ignite().await?;
|
|
|
|
/// println!("Hello, Rocket: {:?}", rocket);
|
|
|
|
///
|
|
|
|
/// let result = rocket.launch().await;
|
|
|
|
/// println!("The server shutdown: {:?}", result);
|
|
|
|
///
|
|
|
|
/// result
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// For all other cases, use [`#[launch]`](launch) instead.
|
|
|
|
///
|
|
|
|
/// The function attributed with `#[rocket::main]` _must_ be `async` and _must_
|
|
|
|
/// be called `main`. Violation of either results in a compile-time error.
|
2020-06-14 15:57:55 +00:00
|
|
|
#[proc_macro_attribute]
|
|
|
|
pub fn main(args: TokenStream, input: TokenStream) -> TokenStream {
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
emit!(attribute::entry::main_attribute(args, input))
|
2019-08-24 17:27:10 +00:00
|
|
|
}
|
|
|
|
|
2021-04-29 04:58:14 +00:00
|
|
|
/// Generates a `main` function that launches a returned `Rocket<Build>`.
|
|
|
|
///
|
|
|
|
/// When applied to a function that returns a `Rocket<Build>` instance,
|
|
|
|
/// `#[launch]` automatically initializes an `async` runtime and
|
|
|
|
/// launches the function's returned instance:
|
|
|
|
///
|
|
|
|
/// ```rust,no_run
|
|
|
|
/// # use rocket::launch;
|
|
|
|
/// use rocket::{Rocket, Build};
|
|
|
|
///
|
|
|
|
/// #[launch]
|
|
|
|
/// fn rocket() -> Rocket<Build> {
|
|
|
|
/// rocket::build()
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// This generates code equivalent to the following:
|
|
|
|
///
|
|
|
|
/// ```rust,no_run
|
|
|
|
/// # use rocket::{Rocket, Build};
|
|
|
|
/// # fn rocket() -> Rocket<Build> {
|
|
|
|
/// # rocket::build()
|
|
|
|
/// # }
|
|
|
|
/// #
|
|
|
|
/// #[rocket::main]
|
|
|
|
/// async fn main() {
|
|
|
|
/// // Recall that an uninspected `Error` will cause a pretty-printed panic,
|
|
|
|
/// // so rest assured failures do not go undetected when using `#[launch]`.
|
|
|
|
/// let _ = rocket().launch().await;
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// To avoid needing to import _any_ items in the common case, the `launch`
|
|
|
|
/// attribute will infer a return type written as `_` as `Rocket<Build>`:
|
|
|
|
///
|
|
|
|
/// ```rust,no_run
|
|
|
|
/// # use rocket::launch;
|
|
|
|
/// #[launch]
|
|
|
|
/// fn rocket() -> _ {
|
|
|
|
/// rocket::build()
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The attributed function may be `async`:
|
|
|
|
///
|
|
|
|
/// ```rust,no_run
|
|
|
|
/// # use rocket::launch;
|
|
|
|
/// # async fn some_async_work() {}
|
|
|
|
/// #[launch]
|
|
|
|
/// async fn rocket() -> _ {
|
|
|
|
/// some_async_work().await;
|
|
|
|
/// rocket::build()
|
|
|
|
/// }
|
|
|
|
/// ```
|
2020-06-16 12:01:26 +00:00
|
|
|
#[proc_macro_attribute]
|
|
|
|
pub fn launch(args: TokenStream, input: TokenStream) -> TokenStream {
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
emit!(attribute::entry::launch_attribute(args, input))
|
2020-06-16 12:01:26 +00:00
|
|
|
}
|
|
|
|
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// Derive for the [`FromFormField`] trait.
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// The [`FromFormField`] derive can be applied to enums with nullary
|
2018-10-15 22:27:47 +00:00
|
|
|
/// (zero-length) fields:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// #[derive(FromFormField)]
|
2018-10-15 22:27:47 +00:00
|
|
|
/// enum MyValue {
|
|
|
|
/// First,
|
|
|
|
/// Second,
|
|
|
|
/// Third,
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// The derive generates an implementation of the [`FromFormField`] trait for
|
2018-10-15 22:27:47 +00:00
|
|
|
/// the decorated `enum`. The implementation returns successfully when the form
|
|
|
|
/// value matches, case insensitively, the stringified version of a variant's
|
|
|
|
/// name, returning an instance of said variant. If there is no match, an error
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// recording all of the available options is returned.
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// As an example, for the `enum` above, the form values `"first"`, `"FIRST"`,
|
|
|
|
/// `"fiRSt"`, and so on would parse as `MyValue::First`, while `"second"` and
|
2021-04-08 05:49:34 +00:00
|
|
|
/// `"third"` (in any casing) would parse as `MyValue::Second` and
|
|
|
|
/// `MyValue::Third`, respectively.
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// The `field` field attribute can be used to change the string value that is
|
|
|
|
/// compared against for a given variant:
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// #[derive(FromFormField)]
|
2018-10-15 22:27:47 +00:00
|
|
|
/// enum MyValue {
|
|
|
|
/// First,
|
|
|
|
/// Second,
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// #[field(value = "fourth")]
|
2021-04-08 05:49:34 +00:00
|
|
|
/// #[field(value = "fifth")]
|
2018-10-15 22:27:47 +00:00
|
|
|
/// Third,
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
2021-04-08 05:49:34 +00:00
|
|
|
/// When more than one `value` is specified, matching _any_ value will result in
|
|
|
|
/// parsing the decorated variant. Declaring any two values that are
|
|
|
|
/// case-insensitively equal to any other value or variant name is a
|
|
|
|
/// compile-time error.
|
|
|
|
///
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// The `#[field]` attribute's grammar is:
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// ```text
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// field := 'value' '=' STRING_LIT
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// STRING_LIT := any valid string literal, as defined by Rust
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The attribute accepts a single string parameter of name `value`
|
|
|
|
/// corresponding to the string to use to match against for the decorated
|
2021-04-08 05:49:34 +00:00
|
|
|
/// variant. In the example above, the the strings `"fourth"`, `"FOUrth"`,
|
|
|
|
/// `"fiFTH"` and so on would parse as `MyValue::Third`.
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
2021-03-20 01:09:13 +00:00
|
|
|
/// [`FromFormField`]: rocket::form::FromFormField
|
|
|
|
/// [`FromFormField::Error`]: rocket::form::FromFormField::Error
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
#[proc_macro_derive(FromFormField, attributes(field))]
|
|
|
|
pub fn derive_from_form_field(input: TokenStream) -> TokenStream {
|
|
|
|
emit!(derive::from_form_field::derive_from_form_field(input))
|
2018-04-12 23:07:37 +00:00
|
|
|
}
|
|
|
|
|
2018-10-15 22:27:47 +00:00
|
|
|
/// Derive for the [`FromForm`] trait.
|
|
|
|
///
|
|
|
|
/// The [`FromForm`] derive can be applied to structures with named fields:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #
|
|
|
|
/// #[derive(FromForm)]
|
2021-03-20 01:09:13 +00:00
|
|
|
/// struct MyStruct<'r> {
|
2018-10-15 22:27:47 +00:00
|
|
|
/// field: usize,
|
2021-03-20 01:09:13 +00:00
|
|
|
/// #[field(name = "renamed_field")]
|
|
|
|
/// #[field(name = uncased("RenamedField"))]
|
|
|
|
/// other: &'r str,
|
|
|
|
/// #[field(validate = range(1..))]
|
|
|
|
/// r#type: usize,
|
2018-10-15 22:27:47 +00:00
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
2021-03-20 01:09:13 +00:00
|
|
|
/// Each field's type is required to implement [`FromForm`].
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// The derive generates an implementation of the [`FromForm`] trait. The
|
|
|
|
/// implementation parses a form whose field names match the field names of the
|
|
|
|
/// structure on which the derive was applied. Each field's value is parsed with
|
2021-03-20 01:09:13 +00:00
|
|
|
/// the [`FromForm`] implementation of the field's type. The `FromForm`
|
|
|
|
/// implementation succeeds only when all of the field parses succeed or return
|
|
|
|
/// a default. Errors are collected into a [`form::Errors`] and return if
|
|
|
|
/// non-empty after parsing all fields.
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// The derive accepts one field attribute: `field`, with the following syntax:
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// ```text
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// field := name? validate*
|
|
|
|
///
|
2021-03-20 01:09:13 +00:00
|
|
|
/// name := 'name' '=' name_val
|
|
|
|
/// name_val := '"' FIELD_NAME '"'
|
|
|
|
/// | 'uncased(' '"' FIELD_NAME '"' ')
|
|
|
|
///
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// validate := 'validate' '=' EXPR
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
2021-03-20 01:09:13 +00:00
|
|
|
/// FIELD_NAME := valid field name, according to the HTML5 spec
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// EXPR := valid expression, as defined by Rust
|
2018-10-15 22:27:47 +00:00
|
|
|
/// ```
|
|
|
|
///
|
2021-03-20 01:09:13 +00:00
|
|
|
/// The attribute can be applied any number of times on a field. When applied,
|
|
|
|
/// the attribute looks as follows:
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #
|
|
|
|
/// #[derive(FromForm)]
|
|
|
|
/// struct MyStruct {
|
|
|
|
/// field: usize,
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// #[field(name = "renamed_field")]
|
2021-03-20 01:09:13 +00:00
|
|
|
/// #[field(name = uncased("anotherName"))]
|
|
|
|
/// #[field(validate = eq("banana"))]
|
|
|
|
/// #[field(validate = neq("orange"))]
|
2018-10-15 22:27:47 +00:00
|
|
|
/// other: String
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
2021-03-20 01:09:13 +00:00
|
|
|
/// **`name`**
|
|
|
|
///
|
|
|
|
/// A `name` attribute changes the name to match against when parsing the form
|
|
|
|
/// field. The value is either an exact string to match against (`"foo"`), or
|
|
|
|
/// `uncased("foo")`, which causes the match to be case-insensitive but
|
|
|
|
/// case-preserving. When more than one `name` attribute is applied, the field
|
|
|
|
/// will match against _any_ of the names.
|
|
|
|
///
|
|
|
|
/// **`validate`**
|
|
|
|
///
|
|
|
|
/// The validation expression will be run if the field type parses successfully.
|
|
|
|
/// The expression must return a value of type `Result<(), form::Errors>`. On
|
|
|
|
/// `Err`, the errors are added to the thus-far collected errors. If more than
|
|
|
|
/// one `validate` attribute is applied, _all_ validations are run.
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
2021-03-20 01:09:13 +00:00
|
|
|
/// [`FromForm`]: rocket::form::FromForm
|
|
|
|
/// [`form::Errors`]: rocket::form::Errors
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
#[proc_macro_derive(FromForm, attributes(field))]
|
2018-08-07 02:58:07 +00:00
|
|
|
pub fn derive_from_form(input: TokenStream) -> TokenStream {
|
2018-10-05 04:44:42 +00:00
|
|
|
emit!(derive::from_form::derive_from_form(input))
|
2018-04-12 23:07:37 +00:00
|
|
|
}
|
|
|
|
|
2018-10-15 22:27:47 +00:00
|
|
|
/// Derive for the [`Responder`] trait.
|
|
|
|
///
|
|
|
|
/// The [`Responder`] derive can be applied to enums and structs with named
|
|
|
|
/// fields. When applied to enums, variants must have at least one field. When
|
|
|
|
/// applied to structs, the struct must have at least one field.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// # use std::fs::File;
|
|
|
|
/// # use rocket::http::ContentType;
|
|
|
|
/// # type OtherResponder = MyResponderA;
|
|
|
|
/// #
|
|
|
|
/// #[derive(Responder)]
|
|
|
|
/// enum MyResponderA {
|
|
|
|
/// A(String),
|
|
|
|
/// B(File, ContentType),
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// #[derive(Responder)]
|
|
|
|
/// struct MyResponderB {
|
|
|
|
/// inner: OtherResponder,
|
|
|
|
/// header: ContentType,
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
2021-04-16 08:11:57 +00:00
|
|
|
/// # Semantics
|
|
|
|
///
|
2018-10-15 22:27:47 +00:00
|
|
|
/// The derive generates an implementation of the [`Responder`] trait for the
|
|
|
|
/// decorated enum or structure. The derive uses the _first_ field of a variant
|
|
|
|
/// or structure to generate a [`Response`]. As such, the type of the first
|
|
|
|
/// field must implement [`Responder`]. The remaining fields of a variant or
|
|
|
|
/// structure are set as headers in the produced [`Response`] using
|
|
|
|
/// [`Response::set_header()`]. As such, every other field (unless explicitly
|
|
|
|
/// ignored, explained next) must implement `Into<Header>`.
|
|
|
|
///
|
|
|
|
/// Except for the first field, fields decorated with `#[response(ignore)]` are
|
|
|
|
/// ignored by the derive:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// # use std::fs::File;
|
|
|
|
/// # use rocket::http::ContentType;
|
|
|
|
/// # use rocket::response::NamedFile;
|
|
|
|
/// # type Other = usize;
|
|
|
|
/// #
|
|
|
|
/// #[derive(Responder)]
|
|
|
|
/// enum MyResponder {
|
|
|
|
/// A(String),
|
|
|
|
/// B(File, ContentType, #[response(ignore)] Other),
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// #[derive(Responder)]
|
|
|
|
/// struct MyOtherResponder {
|
|
|
|
/// inner: NamedFile,
|
|
|
|
/// header: ContentType,
|
|
|
|
/// #[response(ignore)]
|
|
|
|
/// other: Other,
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Decorating the first field with `#[response(ignore)]` has no effect.
|
|
|
|
///
|
2021-04-16 08:11:57 +00:00
|
|
|
/// # Field Attribute
|
|
|
|
///
|
2018-10-15 22:27:47 +00:00
|
|
|
/// Additionally, the `response` attribute can be used on named structures and
|
|
|
|
/// enum variants to override the status and/or content-type of the [`Response`]
|
|
|
|
/// produced by the generated implementation. The `response` attribute used in
|
|
|
|
/// these positions has the following grammar:
|
|
|
|
///
|
|
|
|
/// ```text
|
|
|
|
/// response := parameter (',' parameter)?
|
|
|
|
///
|
|
|
|
/// parameter := 'status' '=' STATUS
|
|
|
|
/// | 'content_type' '=' CONTENT_TYPE
|
|
|
|
///
|
|
|
|
/// STATUS := unsigned integer >= 100 and < 600
|
|
|
|
/// CONTENT_TYPE := string literal, as defined by Rust, identifying a valid
|
|
|
|
/// Content-Type, as defined by Rocket
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// It can be used as follows:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// # use rocket::http::ContentType;
|
|
|
|
/// # use rocket::response::NamedFile;
|
|
|
|
/// # type Other = usize;
|
|
|
|
/// # type InnerResponder = String;
|
|
|
|
/// #
|
|
|
|
/// #[derive(Responder)]
|
|
|
|
/// enum Error {
|
|
|
|
/// #[response(status = 500, content_type = "json")]
|
|
|
|
/// A(String),
|
|
|
|
/// #[response(status = 404)]
|
|
|
|
/// B(NamedFile, ContentType),
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// #[derive(Responder)]
|
|
|
|
/// #[response(status = 400)]
|
|
|
|
/// struct MyResponder {
|
|
|
|
/// inner: InnerResponder,
|
|
|
|
/// header: ContentType,
|
|
|
|
/// #[response(ignore)]
|
|
|
|
/// other: Other,
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The attribute accepts two key/value pairs: `status` and `content_type`. The
|
|
|
|
/// value of `status` must be an unsigned integer representing a valid status
|
|
|
|
/// code. The [`Response`] produced from the generated implementation will have
|
2020-07-22 19:54:52 +00:00
|
|
|
/// its status overridden to this value.
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// The value of `content_type` must be a valid media-type in `top/sub` form or
|
|
|
|
/// `shorthand` form. Examples include:
|
|
|
|
///
|
|
|
|
/// * `"text/html"`
|
|
|
|
/// * `"application/x-custom"`
|
|
|
|
/// * `"html"`
|
|
|
|
/// * `"json"`
|
|
|
|
/// * `"plain"`
|
|
|
|
/// * `"binary"`
|
|
|
|
///
|
|
|
|
/// See [`ContentType::parse_flexible()`] for a full list of available
|
|
|
|
/// shorthands. The [`Response`] produced from the generated implementation will
|
2020-07-22 19:54:52 +00:00
|
|
|
/// have its content-type overridden to this value.
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// [`Responder`]: ../rocket/response/trait.Responder.html
|
|
|
|
/// [`Response`]: ../rocket/struct.Response.html
|
|
|
|
/// [`Response::set_header()`]: ../rocket/response/struct.Response.html#method.set_header
|
|
|
|
/// [`ContentType::parse_flexible()`]: ../rocket/http/struct.ContentType.html#method.parse_flexible
|
2021-04-16 08:11:57 +00:00
|
|
|
///
|
|
|
|
/// # Generics
|
|
|
|
///
|
|
|
|
/// The derive accepts at most one type generic and at most one lifetime
|
|
|
|
/// generic. If a type generic is present, the generated implementation will
|
|
|
|
/// require a bound of `Responder` for the generic. As such, the generic should
|
|
|
|
/// be used as a `Responder`:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #[derive(Responder)]
|
|
|
|
/// #[response(status = 404, content_type = "html")]
|
|
|
|
/// struct NotFoundHtml<T>(T);
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// If a lifetime generic is present, it will be used as the second lifetime
|
|
|
|
/// paramter `'o` parameter in `impl Responder<'r, 'o>`:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #[derive(Responder)]
|
|
|
|
/// #[response(status = 404, content_type = "html")]
|
|
|
|
/// struct NotFoundHtmlString<'o>(&'o str);
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Both a type generic and lifetime generic may be used:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// # use rocket::response::Responder;
|
|
|
|
/// #[derive(Responder)]
|
|
|
|
/// struct SomeResult<'o, T>(Result<T, &'o str>);
|
|
|
|
/// ```
|
2018-08-07 02:58:07 +00:00
|
|
|
#[proc_macro_derive(Responder, attributes(response))]
|
|
|
|
pub fn derive_responder(input: TokenStream) -> TokenStream {
|
2018-10-05 04:44:42 +00:00
|
|
|
emit!(derive::responder::derive_responder(input))
|
2018-04-12 23:07:37 +00:00
|
|
|
}
|
2018-09-16 07:33:16 +00:00
|
|
|
|
2018-11-27 16:01:47 +00:00
|
|
|
/// Derive for the [`UriDisplay<Query>`] trait.
|
2018-10-25 09:53:04 +00:00
|
|
|
///
|
2018-11-27 16:01:47 +00:00
|
|
|
/// The [`UriDisplay<Query>`] derive can be applied to enums and structs. When
|
2021-04-08 05:49:34 +00:00
|
|
|
/// applied to an enum, the enum must have at least one variant. When applied to
|
|
|
|
/// a struct, the struct must have at least one field.
|
2018-10-25 09:53:04 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
2018-11-27 16:01:47 +00:00
|
|
|
/// #[derive(UriDisplayQuery)]
|
2018-10-25 09:53:04 +00:00
|
|
|
/// enum Kind {
|
|
|
|
/// A(String),
|
|
|
|
/// B(usize),
|
|
|
|
/// }
|
|
|
|
///
|
2018-11-27 16:01:47 +00:00
|
|
|
/// #[derive(UriDisplayQuery)]
|
2018-10-25 09:53:04 +00:00
|
|
|
/// struct MyStruct {
|
|
|
|
/// name: String,
|
|
|
|
/// id: usize,
|
|
|
|
/// kind: Kind,
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
2018-11-27 16:01:47 +00:00
|
|
|
/// Each field's type is required to implement [`UriDisplay<Query>`].
|
2018-10-25 09:53:04 +00:00
|
|
|
///
|
2018-11-27 16:01:47 +00:00
|
|
|
/// The derive generates an implementation of the [`UriDisplay<Query>`] trait.
|
|
|
|
/// The implementation calls [`Formatter::write_named_value()`] for every named
|
2020-07-22 19:54:52 +00:00
|
|
|
/// field, using the field's name (unless overridden, explained next) as the
|
2018-10-25 09:53:04 +00:00
|
|
|
/// `name` parameter, and [`Formatter::write_value()`] for every unnamed field
|
|
|
|
/// in the order the fields are declared.
|
|
|
|
///
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// The derive accepts one field attribute: `field`, with the following syntax:
|
2018-10-25 09:53:04 +00:00
|
|
|
///
|
|
|
|
/// ```text
|
2021-04-08 05:49:34 +00:00
|
|
|
/// field := 'name' '=' '"' FIELD_NAME '"'
|
|
|
|
/// | 'value' '=' '"' FIELD_VALUE '"'
|
2018-10-25 09:53:04 +00:00
|
|
|
///
|
2021-04-08 05:49:34 +00:00
|
|
|
/// FIELD_NAME := valid HTTP field name
|
|
|
|
/// FIELD_VALUE := valid HTTP field value
|
2018-10-25 09:53:04 +00:00
|
|
|
/// ```
|
|
|
|
///
|
2021-04-08 05:49:34 +00:00
|
|
|
/// When applied to a struct, the attribute can only contain `name` and looks
|
|
|
|
/// as follows:
|
2018-10-25 09:53:04 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
2018-11-27 16:01:47 +00:00
|
|
|
/// # #[derive(UriDisplayQuery)]
|
2018-10-25 09:53:04 +00:00
|
|
|
/// # struct Kind(String);
|
2018-11-27 16:01:47 +00:00
|
|
|
/// #[derive(UriDisplayQuery)]
|
2018-10-25 09:53:04 +00:00
|
|
|
/// struct MyStruct {
|
|
|
|
/// name: String,
|
|
|
|
/// id: usize,
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// #[field(name = "type")]
|
2021-04-08 05:49:34 +00:00
|
|
|
/// #[field(name = "kind")]
|
2018-10-25 09:53:04 +00:00
|
|
|
/// kind: Kind,
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The field attribute directs that a different field name be used when calling
|
|
|
|
/// [`Formatter::write_named_value()`] for the given field. The value of the
|
2021-04-08 05:49:34 +00:00
|
|
|
/// `name` attribute is used instead of the structure's actual field name. If
|
|
|
|
/// more than one `field` attribute is applied to a field, the _first_ name is
|
|
|
|
/// used. In the example above, the field `MyStruct::kind` is rendered with a
|
|
|
|
/// name of `type`.
|
|
|
|
///
|
|
|
|
/// The attribute can slso be applied to variants of C-like enums; it may only
|
|
|
|
/// contain `value` and looks as follows:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #[derive(UriDisplayQuery)]
|
|
|
|
/// enum Kind {
|
|
|
|
/// File,
|
|
|
|
/// #[field(value = "str")]
|
|
|
|
/// #[field(value = "string")]
|
|
|
|
/// String,
|
|
|
|
/// Other
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The field attribute directs that a different value be used when calling
|
|
|
|
/// [`Formatter::write_named_value()`] for the given variant. The value of the
|
|
|
|
/// `value` attribute is used instead of the variant's actual name. If more than
|
|
|
|
/// one `field` attribute is applied to a variant, the _first_ value is used. In
|
|
|
|
/// the example above, the variant `Kind::String` will render with a value of
|
|
|
|
/// `str`.
|
2018-10-25 09:53:04 +00:00
|
|
|
///
|
2018-11-27 16:01:47 +00:00
|
|
|
/// [`UriDisplay<Query>`]: ../rocket/http/uri/trait.UriDisplay.html
|
2018-10-25 09:53:04 +00:00
|
|
|
/// [`Formatter::write_named_value()`]: ../rocket/http/uri/struct.Formatter.html#method.write_named_value
|
|
|
|
/// [`Formatter::write_value()`]: ../rocket/http/uri/struct.Formatter.html#method.write_value
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
#[proc_macro_derive(UriDisplayQuery, attributes(field))]
|
2018-11-27 16:01:47 +00:00
|
|
|
pub fn derive_uri_display_query(input: TokenStream) -> TokenStream {
|
|
|
|
emit!(derive::uri_display::derive_uri_display_query(input))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Derive for the [`UriDisplay<Path>`] trait.
|
|
|
|
///
|
|
|
|
/// The [`UriDisplay<Path>`] derive can only be applied to tuple structs with
|
|
|
|
/// one field.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #[derive(UriDisplayPath)]
|
|
|
|
/// struct Name(String);
|
|
|
|
///
|
|
|
|
/// #[derive(UriDisplayPath)]
|
|
|
|
/// struct Age(usize);
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The field's type is required to implement [`UriDisplay<Path>`].
|
|
|
|
///
|
|
|
|
/// The derive generates an implementation of the [`UriDisplay<Path>`] trait.
|
|
|
|
/// The implementation calls [`Formatter::write_value()`] for the field.
|
|
|
|
///
|
|
|
|
/// [`UriDisplay<Path>`]: ../rocket/http/uri/trait.UriDisplay.html
|
|
|
|
/// [`Formatter::write_value()`]: ../rocket/http/uri/struct.Formatter.html#method.write_value
|
|
|
|
#[proc_macro_derive(UriDisplayPath)]
|
|
|
|
pub fn derive_uri_display_path(input: TokenStream) -> TokenStream {
|
|
|
|
emit!(derive::uri_display::derive_uri_display_path(input))
|
2018-10-25 05:14:05 +00:00
|
|
|
}
|
|
|
|
|
2018-10-15 22:27:47 +00:00
|
|
|
/// Generates a [`Vec`] of [`Route`]s from a set of route paths.
|
|
|
|
///
|
|
|
|
/// The `routes!` macro expands a list of route paths into a [`Vec`] of their
|
|
|
|
/// corresponding [`Route`] structures. For example, given the following routes:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #
|
|
|
|
/// #[get("/")]
|
|
|
|
/// fn index() { /* .. */ }
|
|
|
|
///
|
|
|
|
/// mod person {
|
|
|
|
/// #[post("/hi/<person>")]
|
|
|
|
/// pub fn hello(person: String) { /* .. */ }
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The `routes!` macro can be used as:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #
|
|
|
|
/// # use rocket::http::Method;
|
|
|
|
/// #
|
|
|
|
/// # #[get("/")] fn index() { /* .. */ }
|
|
|
|
/// # mod person {
|
|
|
|
/// # #[post("/hi/<person>")] pub fn hello(person: String) { /* .. */ }
|
|
|
|
/// # }
|
|
|
|
/// let my_routes = routes![index, person::hello];
|
|
|
|
/// assert_eq!(my_routes.len(), 2);
|
|
|
|
///
|
|
|
|
/// let index_route = &my_routes[0];
|
|
|
|
/// assert_eq!(index_route.method, Method::Get);
|
2021-03-11 06:28:06 +00:00
|
|
|
/// assert_eq!(index_route.name.as_ref().unwrap(), "index");
|
2018-10-15 22:27:47 +00:00
|
|
|
/// assert_eq!(index_route.uri.path(), "/");
|
|
|
|
///
|
|
|
|
/// let hello_route = &my_routes[1];
|
|
|
|
/// assert_eq!(hello_route.method, Method::Post);
|
2021-03-11 06:28:06 +00:00
|
|
|
/// assert_eq!(hello_route.name.as_ref().unwrap(), "hello");
|
2018-10-15 22:27:47 +00:00
|
|
|
/// assert_eq!(hello_route.uri.path(), "/hi/<person>");
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The grammar for `routes!` is defined as:
|
|
|
|
///
|
|
|
|
/// ```text
|
|
|
|
/// routes := PATH (',' PATH)*
|
|
|
|
///
|
|
|
|
/// PATH := a path, as defined by Rust
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// [`Route`]: ../rocket/struct.Route.html
|
2018-06-28 15:55:15 +00:00
|
|
|
#[proc_macro]
|
2018-09-16 07:44:47 +00:00
|
|
|
pub fn routes(input: TokenStream) -> TokenStream {
|
2018-10-05 04:44:42 +00:00
|
|
|
emit!(bang::routes_macro(input))
|
2018-06-28 15:55:15 +00:00
|
|
|
}
|
|
|
|
|
2018-10-15 22:27:47 +00:00
|
|
|
/// Generates a [`Vec`] of [`Catcher`]s from a set of catcher paths.
|
|
|
|
///
|
|
|
|
/// The `catchers!` macro expands a list of catcher paths into a [`Vec`] of
|
|
|
|
/// their corresponding [`Catcher`] structures. For example, given the following
|
|
|
|
/// catchers:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #
|
|
|
|
/// #[catch(404)]
|
|
|
|
/// fn not_found() { /* .. */ }
|
|
|
|
///
|
|
|
|
/// mod inner {
|
|
|
|
/// #[catch(400)]
|
|
|
|
/// pub fn unauthorized() { /* .. */ }
|
|
|
|
/// }
|
2020-07-30 06:07:22 +00:00
|
|
|
///
|
|
|
|
/// #[catch(default)]
|
|
|
|
/// fn default_catcher() { /* .. */ }
|
2018-10-15 22:27:47 +00:00
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The `catchers!` macro can be used as:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #
|
|
|
|
/// # #[catch(404)] fn not_found() { /* .. */ }
|
2020-07-30 06:07:22 +00:00
|
|
|
/// # #[catch(default)] fn default_catcher() { /* .. */ }
|
2018-10-15 22:27:47 +00:00
|
|
|
/// # mod inner {
|
2018-10-18 01:33:08 +00:00
|
|
|
/// # #[catch(400)] pub fn unauthorized() { /* .. */ }
|
2018-10-15 22:27:47 +00:00
|
|
|
/// # }
|
2020-07-30 06:07:22 +00:00
|
|
|
/// let my_catchers = catchers![not_found, inner::unauthorized, default_catcher];
|
|
|
|
/// assert_eq!(my_catchers.len(), 3);
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// let not_found = &my_catchers[0];
|
2020-07-30 06:07:22 +00:00
|
|
|
/// assert_eq!(not_found.code, Some(404));
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// let unauthorized = &my_catchers[1];
|
2020-07-30 06:07:22 +00:00
|
|
|
/// assert_eq!(unauthorized.code, Some(400));
|
|
|
|
///
|
|
|
|
/// let default = &my_catchers[2];
|
|
|
|
/// assert_eq!(default.code, None);
|
2018-10-15 22:27:47 +00:00
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The grammar for `catchers!` is defined as:
|
|
|
|
///
|
|
|
|
/// ```text
|
|
|
|
/// catchers := PATH (',' PATH)*
|
|
|
|
///
|
|
|
|
/// PATH := a path, as defined by Rust
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// [`Catcher`]: ../rocket/struct.Catcher.html
|
2018-09-16 07:44:47 +00:00
|
|
|
#[proc_macro]
|
|
|
|
pub fn catchers(input: TokenStream) -> TokenStream {
|
2018-10-05 04:44:42 +00:00
|
|
|
emit!(bang::catchers_macro(input))
|
2018-09-16 07:33:16 +00:00
|
|
|
}
|
2018-09-20 04:47:58 +00:00
|
|
|
|
2021-05-20 01:20:40 +00:00
|
|
|
/// Type-safe, encoding-safe route and non-route URI generation.
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// The `uri!` macro creates type-safe, URL-safe URIs given a route and concrete
|
|
|
|
/// parameters for its URI or a URI string literal.
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// # String Literal Parsing
|
|
|
|
///
|
|
|
|
/// Given a string literal as input, `uri!` parses the string using
|
|
|
|
/// [`Uri::parse_any()`] and emits a `'static`, `const` value whose type is one
|
|
|
|
/// of [`Asterisk`], [`Origin`], [`Authority`], [`Absolute`], or [`Reference`],
|
|
|
|
/// reflecting the parsed value. If the type allows normalization, the value is
|
|
|
|
/// normalized before being emitted. Parse errors are caught and emitted at
|
|
|
|
/// compile-time.
|
|
|
|
///
|
|
|
|
/// The grammar for this variant of `uri!` is:
|
|
|
|
///
|
|
|
|
/// ```text
|
|
|
|
/// uri := STRING
|
|
|
|
///
|
|
|
|
/// STRING := an uncooked string literal, as defined by Rust (example: `"/hi"`)
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// `STRING` is expected to be an undecoded URI of any variant.
|
|
|
|
///
|
|
|
|
/// ## Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// use rocket::http::uri::Absolute;
|
|
|
|
///
|
|
|
|
/// // Values returned from `uri!` are `const` and `'static`.
|
|
|
|
/// const ROOT_CONST: Absolute<'static> = uri!("https://rocket.rs");
|
|
|
|
/// static ROOT_STATIC: Absolute<'static> = uri!("https://rocket.rs?root");
|
|
|
|
///
|
|
|
|
/// // Any variant can be parsed, but beware of ambiguities.
|
|
|
|
/// let asterisk = uri!("*");
|
|
|
|
/// let origin = uri!("/foo/bar/baz");
|
|
|
|
/// let authority = uri!("rocket.rs:443");
|
|
|
|
/// let absolute = uri!("https://rocket.rs:443");
|
|
|
|
/// let reference = uri!("foo?bar#baz");
|
|
|
|
///
|
|
|
|
/// # use rocket::http::uri::{Asterisk, Origin, Authority, Reference};
|
|
|
|
/// # // Ensure we get the types we expect.
|
|
|
|
/// # let asterisk: Asterisk = asterisk;
|
|
|
|
/// # let origin: Origin<'static> = origin;
|
|
|
|
/// # let authority: Authority<'static> = authority;
|
|
|
|
/// # let absolute: Absolute<'static> = absolute;
|
|
|
|
/// # let reference: Reference<'static> = reference;
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// # Type-Safe Route URIs
|
|
|
|
///
|
|
|
|
/// A URI to a route name `foo` is generated using `uri!(foo(v1, v2, v3))` or
|
|
|
|
/// `uri!(foo(a = v1, b = v2, c = v3))`, where `v1`, `v2`, `v3` are the values
|
|
|
|
/// to fill in for route parameters named `a`, `b`, and `c`. If the named
|
|
|
|
/// parameter sytnax is used (`a = v1`, etc.), parameters can appear in any
|
|
|
|
/// order.
|
|
|
|
///
|
|
|
|
/// More concretely, for the route `person` defined below:
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
2018-12-05 12:20:22 +00:00
|
|
|
/// #[get("/person/<name>?<age>")]
|
2021-05-20 01:20:40 +00:00
|
|
|
/// fn person(name: &str, age: Option<u8>) { }
|
2018-10-15 22:27:47 +00:00
|
|
|
/// ```
|
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// ...a URI can be created as follows:
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
2018-12-05 12:20:22 +00:00
|
|
|
/// # #[get("/person/<name>?<age>")]
|
2021-05-20 01:20:40 +00:00
|
|
|
/// # fn person(name: &str, age: Option<u8>) { }
|
2018-10-15 22:27:47 +00:00
|
|
|
/// // with unnamed parameters, in route path declaration order
|
2021-05-20 01:20:40 +00:00
|
|
|
/// let mike = uri!(person("Mike Smith", Some(28)));
|
2018-12-05 12:20:22 +00:00
|
|
|
/// assert_eq!(mike.to_string(), "/person/Mike%20Smith?age=28");
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// // with named parameters, order irrelevant
|
2021-05-20 01:20:40 +00:00
|
|
|
/// let mike = uri!(person(name = "Mike", age = Some(28)));
|
|
|
|
/// let mike = uri!(person(age = Some(28), name = "Mike"));
|
2018-12-05 12:20:22 +00:00
|
|
|
/// assert_eq!(mike.to_string(), "/person/Mike?age=28");
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// // with unnamed values, explicitly `None`.
|
|
|
|
/// let mike = uri!(person("Mike", None::<u8>));
|
2018-12-05 12:20:22 +00:00
|
|
|
/// assert_eq!(mike.to_string(), "/person/Mike");
|
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// // with named values, explicitly `None`
|
Use 'Option', 'Result' directly in 'uri!' query.
Prior to this commit, the conversion 'T -> Option<T>' was applied in
both the path and query parts of a URI in the 'uri' macro via the
'FromUriParam' trait with no implementation for 'Option<T>' directly.
This meant that it was impossible to directly render an 'Option<T>'.
This was exactly desired for the path part, where rendering a 'None'
would yield an incorrect URI, but the restriction was too strict for the
query part, where a 'None' is entirely valid. This commit makes changes
the conversion so that it only applied to path parts and adds the
identity conversions for 'Option<T>' and 'Result<T, E>' for query parts.
The side effect is a breaking change: due to conflicting impls, the 'T'
to 'Option<T>' conversion was removed for query parts. Thus, all 'uri!'
query route arguments of type 'Option' or 'Result' must now be wrapped
in 'Some' or 'Ok'. Due to new 'Option<T> <-> Result<T, E>' conversions,
either 'Some' _and_ 'Ok' work in both contexts.
Closes #1420.
2020-11-01 18:30:30 +00:00
|
|
|
/// let option: Option<u8> = None;
|
2021-05-20 01:20:40 +00:00
|
|
|
/// let mike = uri!(person(name = "Mike", age = None::<u8>));
|
Use 'Option', 'Result' directly in 'uri!' query.
Prior to this commit, the conversion 'T -> Option<T>' was applied in
both the path and query parts of a URI in the 'uri' macro via the
'FromUriParam' trait with no implementation for 'Option<T>' directly.
This meant that it was impossible to directly render an 'Option<T>'.
This was exactly desired for the path part, where rendering a 'None'
would yield an incorrect URI, but the restriction was too strict for the
query part, where a 'None' is entirely valid. This commit makes changes
the conversion so that it only applied to path parts and adds the
identity conversions for 'Option<T>' and 'Result<T, E>' for query parts.
The side effect is a breaking change: due to conflicting impls, the 'T'
to 'Option<T>' conversion was removed for query parts. Thus, all 'uri!'
query route arguments of type 'Option' or 'Result' must now be wrapped
in 'Some' or 'Ok'. Due to new 'Option<T> <-> Result<T, E>' conversions,
either 'Some' _and_ 'Ok' work in both contexts.
Closes #1420.
2020-11-01 18:30:30 +00:00
|
|
|
/// assert_eq!(mike.to_string(), "/person/Mike");
|
2021-05-20 01:20:40 +00:00
|
|
|
/// ```
|
Use 'Option', 'Result' directly in 'uri!' query.
Prior to this commit, the conversion 'T -> Option<T>' was applied in
both the path and query parts of a URI in the 'uri' macro via the
'FromUriParam' trait with no implementation for 'Option<T>' directly.
This meant that it was impossible to directly render an 'Option<T>'.
This was exactly desired for the path part, where rendering a 'None'
would yield an incorrect URI, but the restriction was too strict for the
query part, where a 'None' is entirely valid. This commit makes changes
the conversion so that it only applied to path parts and adds the
identity conversions for 'Option<T>' and 'Result<T, E>' for query parts.
The side effect is a breaking change: due to conflicting impls, the 'T'
to 'Option<T>' conversion was removed for query parts. Thus, all 'uri!'
query route arguments of type 'Option' or 'Result' must now be wrapped
in 'Some' or 'Ok'. Due to new 'Option<T> <-> Result<T, E>' conversions,
either 'Some' _and_ 'Ok' work in both contexts.
Closes #1420.
2020-11-01 18:30:30 +00:00
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// For optional query parameters, those of type `Option` or `Result`, a `_` can
|
|
|
|
/// be used in-place of `None` or `Err`:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// # #[get("/person/<name>?<age>")]
|
|
|
|
/// # fn person(name: &str, age: Option<u8>) { }
|
2018-12-05 12:20:22 +00:00
|
|
|
/// // with named values ignored
|
2021-05-20 01:20:40 +00:00
|
|
|
/// let mike = uri!(person(name = "Mike", age = _));
|
2018-12-05 12:20:22 +00:00
|
|
|
/// assert_eq!(mike.to_string(), "/person/Mike");
|
Use 'Option', 'Result' directly in 'uri!' query.
Prior to this commit, the conversion 'T -> Option<T>' was applied in
both the path and query parts of a URI in the 'uri' macro via the
'FromUriParam' trait with no implementation for 'Option<T>' directly.
This meant that it was impossible to directly render an 'Option<T>'.
This was exactly desired for the path part, where rendering a 'None'
would yield an incorrect URI, but the restriction was too strict for the
query part, where a 'None' is entirely valid. This commit makes changes
the conversion so that it only applied to path parts and adds the
identity conversions for 'Option<T>' and 'Result<T, E>' for query parts.
The side effect is a breaking change: due to conflicting impls, the 'T'
to 'Option<T>' conversion was removed for query parts. Thus, all 'uri!'
query route arguments of type 'Option' or 'Result' must now be wrapped
in 'Some' or 'Ok'. Due to new 'Option<T> <-> Result<T, E>' conversions,
either 'Some' _and_ 'Ok' work in both contexts.
Closes #1420.
2020-11-01 18:30:30 +00:00
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// // with named values ignored
|
|
|
|
/// let mike = uri!(person(age = _, name = "Mike"));
|
|
|
|
/// assert_eq!(mike.to_string(), "/person/Mike");
|
|
|
|
///
|
|
|
|
/// // with unnamed values ignored
|
|
|
|
/// let mike = uri!(person("Mike", _));
|
Use 'Option', 'Result' directly in 'uri!' query.
Prior to this commit, the conversion 'T -> Option<T>' was applied in
both the path and query parts of a URI in the 'uri' macro via the
'FromUriParam' trait with no implementation for 'Option<T>' directly.
This meant that it was impossible to directly render an 'Option<T>'.
This was exactly desired for the path part, where rendering a 'None'
would yield an incorrect URI, but the restriction was too strict for the
query part, where a 'None' is entirely valid. This commit makes changes
the conversion so that it only applied to path parts and adds the
identity conversions for 'Option<T>' and 'Result<T, E>' for query parts.
The side effect is a breaking change: due to conflicting impls, the 'T'
to 'Option<T>' conversion was removed for query parts. Thus, all 'uri!'
query route arguments of type 'Option' or 'Result' must now be wrapped
in 'Some' or 'Ok'. Due to new 'Option<T> <-> Result<T, E>' conversions,
either 'Some' _and_ 'Ok' work in both contexts.
Closes #1420.
2020-11-01 18:30:30 +00:00
|
|
|
/// assert_eq!(mike.to_string(), "/person/Mike");
|
2018-10-15 22:27:47 +00:00
|
|
|
/// ```
|
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// It is a type error to attempt to ignore query parameters that are neither
|
|
|
|
/// `Option` or `Result`. Path parameters can never be ignored. A path parameter
|
|
|
|
/// of type `Option<T>` or `Result<T, E>` must be filled by a value that can
|
|
|
|
/// target a type of `T`:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #[get("/person/<name>")]
|
|
|
|
/// fn maybe(name: Option<&str>) { }
|
|
|
|
///
|
|
|
|
/// let bob1 = uri!(maybe(name = "Bob"));
|
|
|
|
/// let bob2 = uri!(maybe("Bob Smith"));
|
|
|
|
/// assert_eq!(bob1.to_string(), "/person/Bob");
|
|
|
|
/// assert_eq!(bob2.to_string(), "/person/Bob%20Smith");
|
|
|
|
///
|
|
|
|
/// #[get("/person/<age>")]
|
|
|
|
/// fn ok(age: Result<u8, &str>) { }
|
|
|
|
///
|
|
|
|
/// let kid1 = uri!(ok(age = 10));
|
|
|
|
/// let kid2 = uri!(ok(12));
|
|
|
|
/// assert_eq!(kid1.to_string(), "/person/10");
|
|
|
|
/// assert_eq!(kid2.to_string(), "/person/12");
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Values for ignored route segments can be of any type as long as the type
|
|
|
|
/// implements [`UriDisplay`] for the appropriate URI part. If a route URI
|
|
|
|
/// contains ignored segments, the route URI invocation cannot use named
|
|
|
|
/// arguments.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #[get("/ignore/<_>/<other>")]
|
|
|
|
/// fn ignore(other: &str) { }
|
|
|
|
///
|
|
|
|
/// let bob = uri!(ignore("Bob Hope", "hello"));
|
|
|
|
/// let life = uri!(ignore(42, "cat&dog"));
|
|
|
|
/// assert_eq!(bob.to_string(), "/ignore/Bob%20Hope/hello");
|
|
|
|
/// assert_eq!(life.to_string(), "/ignore/42/cat%26dog");
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// ## Prefixes and Suffixes
|
|
|
|
///
|
|
|
|
/// A route URI can be be optionally prefixed and/or suffixed by a URI generated
|
|
|
|
/// from a string literal or an arbitrary expression. This takes the form
|
|
|
|
/// `uri!(prefix, foo(v1, v2, v3), suffix)`, where both `prefix` and `suffix`
|
|
|
|
/// are optional, and either `prefix` or `suffix` may be `_` to specify the
|
|
|
|
/// value as empty.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// #[get("/person/<name>?<age>")]
|
|
|
|
/// fn person(name: &str, age: Option<u8>) { }
|
|
|
|
///
|
|
|
|
/// // with a specific mount-point of `/api`.
|
|
|
|
/// let bob = uri!("/api", person("Bob", Some(28)));
|
|
|
|
/// assert_eq!(bob.to_string(), "/api/person/Bob?age=28");
|
|
|
|
///
|
|
|
|
/// // with an absolute URI as a prefix
|
|
|
|
/// let bob = uri!("https://rocket.rs", person("Bob", Some(28)));
|
|
|
|
/// assert_eq!(bob.to_string(), "https://rocket.rs/person/Bob?age=28");
|
|
|
|
///
|
|
|
|
/// // with another absolute URI as a prefix
|
|
|
|
/// let bob = uri!("https://rocket.rs/foo", person("Bob", Some(28)));
|
|
|
|
/// assert_eq!(bob.to_string(), "https://rocket.rs/foo/person/Bob?age=28");
|
|
|
|
///
|
|
|
|
/// // with an expression as a prefix
|
|
|
|
/// let host = uri!("http://bob.me");
|
|
|
|
/// let bob = uri!(host, person("Bob", Some(28)));
|
|
|
|
/// assert_eq!(bob.to_string(), "http://bob.me/person/Bob?age=28");
|
|
|
|
///
|
|
|
|
/// // with a suffix but no prefix
|
|
|
|
/// let bob = uri!(_, person("Bob", Some(28)), "#baz");
|
|
|
|
/// assert_eq!(bob.to_string(), "/person/Bob?age=28#baz");
|
|
|
|
///
|
|
|
|
/// // with both a prefix and suffix
|
|
|
|
/// let bob = uri!("https://rocket.rs/", person("Bob", Some(28)), "#woo");
|
|
|
|
/// assert_eq!(bob.to_string(), "https://rocket.rs/person/Bob?age=28#woo");
|
|
|
|
///
|
|
|
|
/// // with an expression suffix. if the route URI already has a query, the
|
|
|
|
/// // query part is ignored. otherwise it is added.
|
|
|
|
/// let suffix = uri!("?woo#bam");
|
|
|
|
/// let bob = uri!(_, person("Bob", Some(28)), suffix.clone());
|
|
|
|
/// assert_eq!(bob.to_string(), "/person/Bob?age=28#bam");
|
|
|
|
///
|
|
|
|
/// let bob = uri!(_, person("Bob", None::<u8>), suffix.clone());
|
|
|
|
/// assert_eq!(bob.to_string(), "/person/Bob?woo#bam");
|
|
|
|
/// ```
|
|
|
|
///
|
2018-10-15 22:27:47 +00:00
|
|
|
/// ## Grammar
|
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// The grammar for this variant of the `uri!` macro is:
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// ```text
|
2021-05-20 01:20:40 +00:00
|
|
|
/// uri := (prefix ',')? route
|
|
|
|
/// | prefix ',' route ',' suffix
|
|
|
|
///
|
|
|
|
/// prefix := STRING | expr ; `Origin` or `Absolute`
|
|
|
|
/// suffix := STRING | expr ; `Reference` or `Absolute`
|
|
|
|
///
|
|
|
|
/// route := PATH '(' (named | unnamed) ')'
|
|
|
|
///
|
|
|
|
/// named := IDENT = expr (',' named)? ','?
|
|
|
|
/// unnamed := expr (',' unnamed)? ','?
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
2018-12-05 12:20:22 +00:00
|
|
|
/// expr := EXPR | '_'
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// EXPR := a valid Rust expression (examples: `foo()`, `12`, `"hey"`)
|
|
|
|
/// IDENT := a valid Rust identifier (examples: `name`, `age`)
|
|
|
|
/// STRING := an uncooked string literal, as defined by Rust (example: `"hi"`)
|
|
|
|
/// PATH := a path, as defined by Rust (examples: `route`, `my_mod::route`)
|
|
|
|
/// ```
|
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// ## Dynamic Semantics
|
|
|
|
///
|
|
|
|
/// The returned value is that of the prefix (minus any query part) concatenated
|
|
|
|
/// with the route URI concatenated with the query (if the route has no query
|
|
|
|
/// part) and fragment parts of the suffix. The route URI is generated by
|
|
|
|
/// interpolating the declared route URI with the URL-safe version of the route
|
|
|
|
/// values in `uri!()`. The generated URI is guaranteed to be URI-safe.
|
|
|
|
///
|
|
|
|
/// Each route value is rendered in its appropriate place in the URI using the
|
|
|
|
/// [`UriDisplay`] implementation for the value's type. The `UriDisplay`
|
|
|
|
/// implementation ensures that the rendered value is URL-safe.
|
|
|
|
///
|
|
|
|
/// A `uri!()` invocation allocated at-most once.
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// ## Static Semantics
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// The `uri!` macro returns one of [`Origin`], [`Absolute`], or [`Reference`],
|
|
|
|
/// depending on the types of the prefix and suffix, if any. The table below
|
|
|
|
/// specifies all combinations:
|
2018-12-05 12:20:22 +00:00
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// | Prefix | Suffix | Output |
|
|
|
|
/// |------------|-------------|-------------|
|
|
|
|
/// | None | None | `Origin` |
|
|
|
|
/// | None | `Absolute` | `Origin` |
|
|
|
|
/// | None | `Reference` | `Reference` |
|
|
|
|
/// | `Origin` | None | `Origin` |
|
|
|
|
/// | `Origin` | `Absolute` | `Origin` |
|
|
|
|
/// | `Origin` | `Reference` | `Reference` |
|
|
|
|
/// | `Absolute` | None | `Absolute` |
|
|
|
|
/// | `Absolute` | `Absolute` | `Absolute` |
|
|
|
|
/// | `Absolute` | `Reference` | `Reference` |
|
2018-12-05 12:20:22 +00:00
|
|
|
///
|
2021-05-20 01:20:40 +00:00
|
|
|
/// A `uri!` invocation only typechecks if the type of every route URI value in
|
|
|
|
/// the invocation matches the type declared for the parameter in the given
|
|
|
|
/// route, after conversion with [`FromUriParam`], or if a value is ignored
|
|
|
|
/// using `_` and the corresponding route type implements [`Ignorable`].
|
2018-12-05 12:20:22 +00:00
|
|
|
///
|
|
|
|
/// ### Conversion
|
|
|
|
///
|
2018-10-15 22:27:47 +00:00
|
|
|
/// The [`FromUriParam`] trait is used to typecheck and perform a conversion for
|
2021-05-20 01:20:40 +00:00
|
|
|
/// each value passed to `uri!`. If a `FromUriParam<P, S> for T` implementation
|
|
|
|
/// exists for a type `T` for part URI part `P`, then a value of type `S` can be
|
|
|
|
/// used in `uri!` macro for a route URI parameter declared with a type of `T`
|
|
|
|
/// in part `P`. For example, the following implementation, provided by Rocket,
|
2018-12-07 20:09:15 +00:00
|
|
|
/// allows an `&str` to be used in a `uri!` invocation for route URI parameters
|
|
|
|
/// declared as `String`:
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// ```rust,ignore
|
2021-05-20 01:20:40 +00:00
|
|
|
/// impl<P: Part, 'a> FromUriParam<P, &'a str> for String { .. }
|
2018-10-15 22:27:47 +00:00
|
|
|
/// ```
|
|
|
|
///
|
2018-12-05 12:20:22 +00:00
|
|
|
/// ### Ignorables
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
2018-12-05 12:20:22 +00:00
|
|
|
/// Query parameters can be ignored using `_` in place of an expression. The
|
|
|
|
/// corresponding type in the route URI must implement [`Ignorable`]. Ignored
|
|
|
|
/// parameters are not interpolated into the resulting `Origin`. Path parameters
|
|
|
|
/// are not ignorable.
|
2018-10-15 22:27:47 +00:00
|
|
|
///
|
|
|
|
/// [`Uri`]: ../rocket/http/uri/enum.Uri.html
|
|
|
|
/// [`Origin`]: ../rocket/http/uri/struct.Origin.html
|
2021-05-20 01:20:40 +00:00
|
|
|
/// [`Asterisk`]: ../rocket/http/uri/struct.Asterisk.html
|
|
|
|
/// [`Authority`]: ../rocket/http/uri/struct.Authority.html
|
|
|
|
/// [`Absolute`]: ../rocket/http/uri/struct.Absolute.html
|
|
|
|
/// [`Reference`]: ../rocket/http/uri/struct.Reference.html
|
2018-10-15 22:27:47 +00:00
|
|
|
/// [`FromUriParam`]: ../rocket/http/uri/trait.FromUriParam.html
|
|
|
|
/// [`UriDisplay`]: ../rocket/http/uri/trait.UriDisplay.html
|
2018-12-05 12:20:22 +00:00
|
|
|
/// [`Ignorable`]: ../rocket/http/uri/trait.Ignorable.html
|
2018-09-20 04:47:58 +00:00
|
|
|
#[proc_macro]
|
|
|
|
pub fn uri(input: TokenStream) -> TokenStream {
|
2018-10-05 04:44:42 +00:00
|
|
|
emit!(bang::uri_macro(input))
|
2018-09-20 04:47:58 +00:00
|
|
|
}
|
|
|
|
|
2018-10-05 04:44:42 +00:00
|
|
|
#[doc(hidden)]
|
2018-09-20 04:47:58 +00:00
|
|
|
#[proc_macro]
|
2021-04-28 08:41:13 +00:00
|
|
|
/// Internal macro: `rocket_internal_uri!`.
|
2018-09-20 04:47:58 +00:00
|
|
|
pub fn rocket_internal_uri(input: TokenStream) -> TokenStream {
|
2018-10-05 04:44:42 +00:00
|
|
|
emit!(bang::uri_internal_macro(input))
|
2018-09-20 04:47:58 +00:00
|
|
|
}
|
2020-02-15 11:43:47 +00:00
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[proc_macro]
|
2021-04-28 08:41:13 +00:00
|
|
|
/// Private Rocket internal macro: `internal_guide_tests!`.
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
pub fn internal_guide_tests(input: TokenStream) -> TokenStream {
|
2020-02-15 11:43:47 +00:00
|
|
|
emit!(bang::guide_tests_internal(input))
|
|
|
|
}
|
2021-04-28 08:29:05 +00:00
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[proc_macro]
|
|
|
|
/// Private Rocket internal macro: `export!`.
|
|
|
|
pub fn export(input: TokenStream) -> TokenStream {
|
|
|
|
emit!(bang::export_internal(input))
|
|
|
|
}
|