2017-01-21 03:31:46 +00:00
|
|
|
use std::ops::Deref;
|
|
|
|
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
use crate::{Rocket, Phase};
|
2019-06-13 01:48:02 +00:00
|
|
|
use crate::request::{self, FromRequest, Request};
|
|
|
|
use crate::outcome::Outcome;
|
|
|
|
use crate::http::Status;
|
2017-01-21 03:31:46 +00:00
|
|
|
|
2017-02-03 02:00:18 +00:00
|
|
|
/// Request guard to retrieve managed state.
|
|
|
|
///
|
|
|
|
/// This type can be used as a request guard to retrieve the state Rocket is
|
|
|
|
/// managing for some type `T`. This allows for the sharing of state across any
|
|
|
|
/// number of handlers. A value for the given type must previously have been
|
2020-07-22 23:10:02 +00:00
|
|
|
/// registered to be managed by Rocket via [`Rocket::manage()`]. The type being
|
|
|
|
/// managed must be thread safe and sendable across thread boundaries. In other
|
|
|
|
/// words, it must implement [`Send`] + [`Sync`] + `'static`.
|
|
|
|
///
|
|
|
|
/// [`Rocket::manage()`]: crate::Rocket::manage()
|
2017-02-03 02:00:18 +00:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// Imagine you have some configuration struct of the type `MyConfig` that you'd
|
|
|
|
/// like to initialize at start-up and later access it in several handlers. The
|
|
|
|
/// following example does just this:
|
|
|
|
///
|
2020-06-16 12:01:26 +00:00
|
|
|
/// ```rust,no_run
|
2018-06-28 15:55:15 +00:00
|
|
|
/// # #[macro_use] extern crate rocket;
|
2017-02-03 02:00:18 +00:00
|
|
|
/// use rocket::State;
|
|
|
|
///
|
|
|
|
/// // In a real application, this would likely be more complex.
|
2017-07-03 22:13:21 +00:00
|
|
|
/// struct MyConfig {
|
|
|
|
/// user_val: String
|
|
|
|
/// }
|
2017-02-03 02:00:18 +00:00
|
|
|
///
|
|
|
|
/// #[get("/")]
|
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 index(state: State<'_, MyConfig>) -> String {
|
2017-07-03 22:13:21 +00:00
|
|
|
/// format!("The config value is: {}", state.user_val)
|
2017-02-03 02:00:18 +00:00
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// #[get("/raw")]
|
|
|
|
/// fn raw_config_value<'r>(state: State<'r, MyConfig>) -> &'r str {
|
|
|
|
/// // use `inner()` to get a lifetime longer than `deref` gives us
|
2017-07-03 22:13:21 +00:00
|
|
|
/// state.inner().user_val.as_str()
|
2017-02-03 02:00:18 +00:00
|
|
|
/// }
|
|
|
|
///
|
2020-07-22 23:10:02 +00:00
|
|
|
/// #[launch]
|
2021-04-14 01:12:39 +00:00
|
|
|
/// fn rocket() -> _ {
|
2021-04-08 08:07:52 +00:00
|
|
|
/// rocket::build()
|
2017-02-03 02:00:18 +00:00
|
|
|
/// .mount("/", routes![index, raw_config_value])
|
2020-06-16 12:01:26 +00:00
|
|
|
/// .manage(MyConfig { user_val: "user input".to_string() })
|
2017-02-03 02:00:18 +00:00
|
|
|
/// }
|
|
|
|
/// ```
|
2017-07-03 22:13:21 +00:00
|
|
|
///
|
|
|
|
/// # Within Request Guards
|
|
|
|
///
|
|
|
|
/// Because `State` is itself a request guard, managed state can be retrieved
|
2021-03-15 02:57:59 +00:00
|
|
|
/// from another request guard's implementation using either
|
2021-03-26 01:33:15 +00:00
|
|
|
/// [`Request::guard()`] or [`Rocket::state()`]. In the following code example,
|
|
|
|
/// the `Item` request guard retrieves `MyConfig` from managed state:
|
2017-07-03 22:13:21 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use rocket::State;
|
|
|
|
/// use rocket::request::{self, Request, FromRequest};
|
2021-03-15 02:57:59 +00:00
|
|
|
/// use rocket::outcome::IntoOutcome;
|
2017-07-03 22:13:21 +00:00
|
|
|
///
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// # struct MyConfig { user_val: String };
|
2021-03-15 02:57:59 +00:00
|
|
|
/// struct Item<'r>(&'r str);
|
2017-07-03 22:13:21 +00:00
|
|
|
///
|
2020-01-31 09:34:15 +00:00
|
|
|
/// #[rocket::async_trait]
|
2021-03-15 02:57:59 +00:00
|
|
|
/// impl<'r> FromRequest<'r> for Item<'r> {
|
2017-07-03 22:13:21 +00:00
|
|
|
/// type Error = ();
|
|
|
|
///
|
2021-03-15 02:57:59 +00:00
|
|
|
/// async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
|
|
|
/// // Using `State` as a request guard. Use `inner()` to get an `'r`.
|
|
|
|
/// let outcome = request.guard::<State<MyConfig>>().await
|
|
|
|
/// .map(|my_config| Item(&my_config.inner().user_val));
|
|
|
|
///
|
|
|
|
/// // Or alternatively, using `Request::managed_state()`:
|
2021-03-26 01:33:15 +00:00
|
|
|
/// let outcome = request.rocket().state::<MyConfig>()
|
2021-03-15 02:57:59 +00:00
|
|
|
/// .map(|my_config| Item(&my_config.user_val))
|
|
|
|
/// .or_forward(());
|
|
|
|
///
|
|
|
|
/// outcome
|
2017-07-03 22:13:21 +00:00
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// ```
|
2018-11-03 08:51:00 +00:00
|
|
|
///
|
|
|
|
/// # Testing with `State`
|
|
|
|
///
|
|
|
|
/// When unit testing your application, you may find it necessary to manually
|
|
|
|
/// construct a type of `State` to pass to your functions. To do so, use the
|
|
|
|
/// [`State::from()`] static method:
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// use rocket::State;
|
|
|
|
///
|
|
|
|
/// struct MyManagedState(usize);
|
|
|
|
///
|
|
|
|
/// #[get("/")]
|
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 handler(state: State<'_, MyManagedState>) -> String {
|
2018-11-03 08:51:00 +00:00
|
|
|
/// state.0.to_string()
|
|
|
|
/// }
|
|
|
|
///
|
2021-04-08 08:07:52 +00:00
|
|
|
/// let mut rocket = rocket::build().manage(MyManagedState(127));
|
2020-10-22 10:27:04 +00:00
|
|
|
/// let state = State::from(&rocket).expect("managed `MyManagedState`");
|
2018-11-03 08:51:00 +00:00
|
|
|
/// assert_eq!(handler(state), "127");
|
|
|
|
/// ```
|
2017-07-03 22:39:24 +00:00
|
|
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
2017-01-21 03:31:46 +00:00
|
|
|
pub struct State<'r, T: Send + Sync + 'static>(&'r T);
|
|
|
|
|
|
|
|
impl<'r, T: Send + Sync + 'static> State<'r, T> {
|
2018-07-12 03:44:09 +00:00
|
|
|
/// Retrieve a borrow to the underlying value with a lifetime of `'r`.
|
2017-01-21 03:31:46 +00:00
|
|
|
///
|
2018-10-06 13:25:17 +00:00
|
|
|
/// Using this method is typically unnecessary as `State` implements
|
|
|
|
/// [`Deref`] with a [`Deref::Target`] of `T`. This means Rocket will
|
|
|
|
/// automatically coerce a `State<T>` to an `&T` as required. This method
|
|
|
|
/// should only be used when a longer lifetime is required.
|
2017-07-03 22:13:21 +00:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use rocket::State;
|
|
|
|
///
|
|
|
|
/// struct MyConfig {
|
|
|
|
/// user_val: String
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// // Use `inner()` to get a lifetime of `'r`
|
|
|
|
/// fn handler1<'r>(config: State<'r, MyConfig>) -> &'r str {
|
|
|
|
/// &config.inner().user_val
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// // Use the `Deref` implementation which coerces implicitly
|
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 handler2(config: State<'_, MyConfig>) -> String {
|
2017-07-03 22:13:21 +00:00
|
|
|
/// config.user_val.clone()
|
|
|
|
/// }
|
|
|
|
/// ```
|
2017-03-28 10:10:18 +00:00
|
|
|
#[inline(always)]
|
2017-01-21 03:31:46 +00:00
|
|
|
pub fn inner(&self) -> &'r T {
|
|
|
|
self.0
|
|
|
|
}
|
2018-11-03 08:51:00 +00:00
|
|
|
|
|
|
|
/// Returns the managed state value in `rocket` for the type `T` if it is
|
|
|
|
/// being managed by `rocket`. Otherwise, returns `None`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use rocket::State;
|
|
|
|
///
|
|
|
|
/// #[derive(Debug, PartialEq)]
|
|
|
|
/// struct Managed(usize);
|
|
|
|
///
|
|
|
|
/// #[derive(Debug, PartialEq)]
|
|
|
|
/// struct Unmanaged(usize);
|
|
|
|
///
|
2021-04-08 08:07:52 +00:00
|
|
|
/// let rocket = rocket::build().manage(Managed(7));
|
2018-11-03 08:51:00 +00:00
|
|
|
///
|
2020-10-22 10:27:04 +00:00
|
|
|
/// let state: Option<State<Managed>> = State::from(&rocket);
|
2018-11-03 08:51:00 +00:00
|
|
|
/// assert_eq!(state.map(|s| s.inner()), Some(&Managed(7)));
|
|
|
|
///
|
2020-10-22 10:27:04 +00:00
|
|
|
/// let state: Option<State<Unmanaged>> = State::from(&rocket);
|
2018-11-03 08:51:00 +00:00
|
|
|
/// assert_eq!(state, None);
|
|
|
|
/// ```
|
|
|
|
#[inline(always)]
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
pub fn from<P: Phase>(rocket: &'r Rocket<P>) -> Option<Self> {
|
2020-06-28 05:59:40 +00:00
|
|
|
rocket.state().map(State)
|
2018-11-03 08:51:00 +00:00
|
|
|
}
|
2017-01-21 03:31:46 +00:00
|
|
|
}
|
|
|
|
|
2020-01-31 09:34:15 +00:00
|
|
|
#[crate::async_trait]
|
2021-03-15 02:57:59 +00:00
|
|
|
impl<'r, T: Send + Sync + 'static> FromRequest<'r> for State<'r, T> {
|
2017-01-21 03:31:46 +00:00
|
|
|
type Error = ();
|
|
|
|
|
2017-03-28 10:10:18 +00:00
|
|
|
#[inline(always)]
|
2021-03-15 02:57:59 +00:00
|
|
|
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
2021-03-26 01:33:15 +00:00
|
|
|
match req.rocket().state::<T>() {
|
2017-03-28 10:10:18 +00:00
|
|
|
Some(state) => Outcome::Success(State(state)),
|
|
|
|
None => {
|
2021-03-24 18:59:23 +00:00
|
|
|
error_!("Attempted to retrieve unmanaged state `{}`!", std::any::type_name::<T>());
|
2017-03-28 10:10:18 +00:00
|
|
|
Outcome::Failure((Status::InternalServerError, ()))
|
2017-01-21 03:31:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-13 01:48:02 +00:00
|
|
|
impl<T: Send + Sync + 'static> Deref for State<'_, T> {
|
2017-01-21 03:31:46 +00:00
|
|
|
type Target = T;
|
|
|
|
|
2017-03-28 10:10:18 +00:00
|
|
|
#[inline(always)]
|
2017-01-21 03:31:46 +00:00
|
|
|
fn deref(&self) -> &T {
|
|
|
|
self.0
|
|
|
|
}
|
|
|
|
}
|
2020-10-02 09:54:11 +00:00
|
|
|
|
|
|
|
impl<T: Send + Sync + 'static> Clone for State<'_, T> {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
State(self.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
#[test]
|
|
|
|
fn state_is_cloneable() {
|
|
|
|
struct Token(usize);
|
|
|
|
|
2020-10-30 09:48:56 +00:00
|
|
|
let rocket = crate::custom(crate::Config::default()).manage(Token(123));
|
2020-10-02 09:54:11 +00:00
|
|
|
let state = rocket.state::<Token>().unwrap();
|
|
|
|
assert_eq!(state.0, 123);
|
|
|
|
assert_eq!(state.clone().0, 123);
|
|
|
|
}
|
|
|
|
}
|