2023-10-31 17:11:03 +00:00
|
|
|
//! Success, error, and forward handling.
|
2016-10-19 07:30:02 +00:00
|
|
|
//!
|
|
|
|
//! The `Outcome<S, E, F>` type is similar to the standard library's `Result<S,
|
|
|
|
//! E>` type. It is an enum with three variants, each containing a value:
|
2023-10-31 17:11:03 +00:00
|
|
|
//! `Success(S)`, which represents a successful outcome, `Error(E)`, which
|
|
|
|
//! represents an erroring outcome, and `Forward(F)`, which represents neither a
|
|
|
|
//! success or error, but instead, indicates that processing could not be
|
2016-10-19 07:30:02 +00:00
|
|
|
//! handled and should instead be _forwarded_ to whatever can handle the
|
|
|
|
//! processing next.
|
|
|
|
//!
|
|
|
|
//! The `Outcome` type is the return type of many of the core Rocket traits,
|
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
|
|
|
//! including [`FromRequest`](crate::request::FromRequest), [`FromData`]
|
|
|
|
//! [`Responder`]. It is also the return type of request handlers via the
|
|
|
|
//! [`Response`](crate::response::Response) type.
|
2020-02-03 08:53:59 +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
|
|
|
//! [`FromData`]: crate::data::FromData
|
2020-02-03 08:53:59 +00:00
|
|
|
//! [`Responder`]: crate::response::Responder
|
2016-10-19 07:30:02 +00:00
|
|
|
//!
|
|
|
|
//! # Success
|
|
|
|
//!
|
|
|
|
//! A successful `Outcome<S, E, F>`, `Success(S)`, is returned from functions
|
|
|
|
//! that complete successfully. The meaning of a `Success` outcome depends on
|
|
|
|
//! the context. For instance, the `Outcome` of the `from_data` method of the
|
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
|
|
|
//! [`FromData`] trait will be matched against the type expected by
|
2020-07-22 23:10:02 +00:00
|
|
|
//! the user. For example, consider the following handler:
|
2016-10-19 07:30:02 +00:00
|
|
|
//!
|
2020-07-22 23:10:02 +00:00
|
|
|
//! ```rust
|
|
|
|
//! # use rocket::post;
|
2021-06-08 09:13:02 +00:00
|
|
|
//! # type S = String;
|
2016-10-19 07:30:02 +00:00
|
|
|
//! #[post("/", data = "<my_val>")]
|
2020-07-22 23:10:02 +00:00
|
|
|
//! fn hello(my_val: S) { /* ... */ }
|
2016-10-19 07:30:02 +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 [`FromData`] implementation for the type `S` returns an `Outcome` with a
|
|
|
|
//! `Success(S)`. If `from_data` returns a `Success`, the `Success` value will
|
|
|
|
//! be unwrapped and the value will be used as the value of `my_val`.
|
2016-10-19 07:30:02 +00:00
|
|
|
//!
|
2023-10-31 17:11:03 +00:00
|
|
|
//! # Error
|
2016-10-19 07:30:02 +00:00
|
|
|
//!
|
2023-10-31 17:11:03 +00:00
|
|
|
//! An error `Outcome<S, E, F>`, `Error(E)`, is returned when a function
|
2016-10-19 07:30:02 +00:00
|
|
|
//! fails with some error and no processing can or should continue as a result.
|
2023-10-31 17:11:03 +00:00
|
|
|
//! The meaning of an error depends on the context.
|
2016-10-19 07:30:02 +00:00
|
|
|
//!
|
2023-10-31 17:11:03 +00:00
|
|
|
//! In Rocket, an `Error` generally means that a request is taken out of normal
|
2016-10-19 07:30:02 +00:00
|
|
|
//! processing. The request is then given to the catcher corresponding to some
|
2023-10-31 17:11:03 +00:00
|
|
|
//! status code. Users can catch errors by requesting a type of `Result<S, E>`
|
2016-10-19 07:30:02 +00:00
|
|
|
//! or `Option<S>` in request handlers. For example, if a user's handler looks
|
|
|
|
//! like:
|
|
|
|
//!
|
2020-07-22 23:10:02 +00:00
|
|
|
//! ```rust
|
|
|
|
//! # use rocket::post;
|
2021-06-08 09:13:02 +00:00
|
|
|
//! # type S = Option<String>;
|
2020-07-22 23:10:02 +00:00
|
|
|
//! # type E = std::convert::Infallible;
|
2016-10-19 07:30:02 +00:00
|
|
|
//! #[post("/", data = "<my_val>")]
|
2020-07-22 23:10:02 +00:00
|
|
|
//! fn hello(my_val: Result<S, E>) { /* ... */ }
|
2016-10-19 07:30:02 +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 [`FromData`] implementation for the type `S` returns an `Outcome` with a
|
2023-10-31 17:11:03 +00:00
|
|
|
//! `Success(S)` and `Error(E)`. If `from_data` returns an `Error`, the `Error`
|
|
|
|
//! value will be unwrapped and the value will be used as the `Err` value of
|
|
|
|
//! `my_val` while a `Success` will be unwrapped and used the `Ok` value.
|
2016-10-19 07:30:02 +00:00
|
|
|
//!
|
|
|
|
//! # Forward
|
|
|
|
//!
|
|
|
|
//! A forward `Outcome<S, E, F>`, `Forward(F)`, is returned when a function
|
|
|
|
//! wants to indicate that the requested processing should be _forwarded_ to the
|
|
|
|
//! next available processor. Again, the exact meaning depends on the context.
|
|
|
|
//!
|
|
|
|
//! In Rocket, a `Forward` generally means that a request is forwarded to the
|
|
|
|
//! next available request handler. For example, consider the following request
|
|
|
|
//! handler:
|
|
|
|
//!
|
2020-07-22 23:10:02 +00:00
|
|
|
//! ```rust
|
|
|
|
//! # use rocket::post;
|
2021-06-08 09:13:02 +00:00
|
|
|
//! # type S = String;
|
2016-10-19 07:30:02 +00:00
|
|
|
//! #[post("/", data = "<my_val>")]
|
2020-07-22 23:10:02 +00:00
|
|
|
//! fn hello(my_val: S) { /* ... */ }
|
2016-10-19 07:30:02 +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 [`FromData`] implementation for the type `S` returns an `Outcome` with a
|
2023-10-31 17:11:03 +00:00
|
|
|
//! `Success(S)`, `Error(E)`, and `Forward(F)`. If the `Outcome` is a
|
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
|
|
|
//! `Forward`, the `hello` handler isn't called. Instead, the incoming request
|
|
|
|
//! is forwarded, or passed on to, the next matching route, if any. Ultimately,
|
|
|
|
//! if there are no non-forwarding routes, forwarded requests are handled by the
|
2023-10-31 17:11:03 +00:00
|
|
|
//! 404 catcher. Similar to `Error`s, users can catch `Forward`s by requesting
|
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
|
|
|
//! a type of `Option<S>`. If an `Outcome` is a `Forward`, the `Option` will be
|
|
|
|
//! `None`.
|
2016-10-19 07:30:02 +00:00
|
|
|
|
2016-10-04 00:09:13 +00:00
|
|
|
use std::fmt;
|
2016-04-11 10:57:23 +00:00
|
|
|
|
2017-06-02 04:44:31 +00:00
|
|
|
use yansi::{Paint, Color};
|
2016-10-04 00:09:13 +00:00
|
|
|
|
Improve forwarding status code precision.
Previously, the `NotFound` status code was used to signal many kinds of
recoverable, forwarding errors. This included validation errors, incorrect
Content-Type errors, and more.
This commit modifies the status code used to forward in these instances to more
precisely indicate the forwarding condition. In particular:
* Parameter `FromParam` errors now forward as 422 (`UnprocessableEntity`).
* Query paramater errors now forward as 422 (`UnprocessableEntity`).
* Use of incorrect form content-type forwards as 413 (`UnsupportedMediaType`).
* `WebSocket` guard now forwards as 400 (`BadRequest`).
* `&Host`, `&Accept`, `&ContentType`, `IpAddr`, and `SocketAddr` all forward
with a 500 (`InternalServerError`).
Additionally, the `IntoOutcome` trait was overhauled to support functionality
previously offered by methods on `Outcome`. The `Outcome::forward()` method now
requires a status code to use for the forwarding outcome.
Finally, logging of `Outcome`s now includes the relevant status code.
Resolves #2626.
2023-10-31 23:27:03 +00:00
|
|
|
use crate::{route, request, response};
|
|
|
|
use crate::data::{self, Data, FromData};
|
|
|
|
use crate::http::Status;
|
|
|
|
|
2016-10-25 09:17:49 +00:00
|
|
|
use self::Outcome::*;
|
|
|
|
|
2023-10-31 17:11:03 +00:00
|
|
|
/// An enum representing success (`Success`), error (`Error`), or forwarding
|
|
|
|
/// (`Forward`).
|
2016-12-10 03:53:13 +00:00
|
|
|
///
|
2019-06-13 01:48:02 +00:00
|
|
|
/// See the [top level documentation](crate::outcome) for detailed information.
|
2016-10-08 06:20:49 +00:00
|
|
|
#[must_use]
|
2016-10-19 07:30:02 +00:00
|
|
|
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
2016-10-14 01:39:23 +00:00
|
|
|
pub enum Outcome<S, E, F> {
|
|
|
|
/// Contains the success value.
|
|
|
|
Success(S),
|
2023-10-31 17:11:03 +00:00
|
|
|
/// Contains the error error value.
|
|
|
|
Error(E),
|
2016-10-14 01:39:23 +00:00
|
|
|
/// Contains the value to forward on.
|
|
|
|
Forward(F),
|
2016-04-11 10:57:23 +00:00
|
|
|
}
|
|
|
|
|
2016-10-14 01:39:23 +00:00
|
|
|
impl<S, E, F> Outcome<S, E, F> {
|
|
|
|
/// Unwraps the Outcome, yielding the contents of a Success.
|
|
|
|
///
|
|
|
|
/// # Panics
|
|
|
|
///
|
2016-10-19 07:30:02 +00:00
|
|
|
/// Panics if the value is not `Success`.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
/// assert_eq!(x.unwrap(), 10);
|
|
|
|
/// ```
|
2017-02-03 10:16:46 +00:00
|
|
|
#[inline]
|
2021-05-23 03:37:18 +00:00
|
|
|
#[track_caller]
|
2016-10-14 01:39:23 +00:00
|
|
|
pub fn unwrap(self) -> S {
|
|
|
|
match self {
|
2016-10-25 09:17:49 +00:00
|
|
|
Success(val) => val,
|
2021-05-23 03:37:18 +00:00
|
|
|
_ => panic!("unwrapped a non-successful outcome")
|
2016-10-09 11:29:02 +00:00
|
|
|
}
|
2016-10-14 01:39:23 +00:00
|
|
|
}
|
2016-10-09 11:29:02 +00:00
|
|
|
|
2016-11-04 13:35:04 +00:00
|
|
|
/// Unwraps the Outcome, yielding the contents of a Success.
|
|
|
|
///
|
|
|
|
/// # Panics
|
|
|
|
///
|
|
|
|
/// If the value is not `Success`, panics with the given `message`.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
/// assert_eq!(x.expect("success value"), 10);
|
|
|
|
/// ```
|
2017-02-03 10:16:46 +00:00
|
|
|
#[inline]
|
2021-05-23 03:37:18 +00:00
|
|
|
#[track_caller]
|
2016-11-04 13:35:04 +00:00
|
|
|
pub fn expect(self, message: &str) -> S {
|
|
|
|
match self {
|
|
|
|
Success(val) => val,
|
2021-05-23 03:37:18 +00:00
|
|
|
_ => panic!("unwrapped a non-successful outcome: {}", message)
|
2016-11-04 13:35:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-14 01:39:23 +00:00
|
|
|
/// Return true if this `Outcome` is a `Success`.
|
2016-10-19 07:30:02 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
/// assert_eq!(x.is_success(), true);
|
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
|
2016-10-19 07:30:02 +00:00
|
|
|
/// assert_eq!(x.is_success(), false);
|
|
|
|
///
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Forward(25);
|
|
|
|
/// assert_eq!(x.is_success(), false);
|
|
|
|
/// ```
|
2017-02-03 10:16:46 +00:00
|
|
|
#[inline]
|
2016-10-14 01:39:23 +00:00
|
|
|
pub fn is_success(&self) -> bool {
|
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
|
|
|
matches!(self, Success(_))
|
2016-10-09 11:29:02 +00:00
|
|
|
}
|
|
|
|
|
2023-10-31 17:11:03 +00:00
|
|
|
/// Return true if this `Outcome` is an `Error`.
|
2016-10-19 07:30:02 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
2023-10-31 17:11:03 +00:00
|
|
|
/// assert_eq!(x.is_error(), false);
|
2016-10-19 07:30:02 +00:00
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
|
|
|
|
/// assert_eq!(x.is_error(), true);
|
2016-10-19 07:30:02 +00:00
|
|
|
///
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Forward(25);
|
2023-10-31 17:11:03 +00:00
|
|
|
/// assert_eq!(x.is_error(), false);
|
2016-10-19 07:30:02 +00:00
|
|
|
/// ```
|
2017-02-03 10:16:46 +00:00
|
|
|
#[inline]
|
2023-10-31 17:11:03 +00:00
|
|
|
pub fn is_error(&self) -> bool {
|
|
|
|
matches!(self, Error(_))
|
2016-04-11 10:57:23 +00:00
|
|
|
}
|
|
|
|
|
2016-10-14 01:39:23 +00:00
|
|
|
/// Return true if this `Outcome` is a `Forward`.
|
2016-10-19 07:30:02 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
/// assert_eq!(x.is_forward(), false);
|
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
|
2016-10-19 07:30:02 +00:00
|
|
|
/// assert_eq!(x.is_forward(), false);
|
|
|
|
///
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Forward(25);
|
|
|
|
/// assert_eq!(x.is_forward(), true);
|
|
|
|
/// ```
|
2017-02-03 10:16:46 +00:00
|
|
|
#[inline]
|
2016-10-14 01:39:23 +00:00
|
|
|
pub fn is_forward(&self) -> bool {
|
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
|
|
|
matches!(self, Forward(_))
|
2016-10-08 06:20:49 +00:00
|
|
|
}
|
|
|
|
|
2016-10-14 01:39:23 +00:00
|
|
|
/// Converts from `Outcome<S, E, F>` to `Option<S>`.
|
|
|
|
///
|
|
|
|
/// Returns the `Some` of the `Success` if this is a `Success`, otherwise
|
|
|
|
/// returns `None`. `self` is consumed, and all other values are discarded.
|
2016-10-19 07:30:02 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
/// assert_eq!(x.succeeded(), Some(10));
|
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
|
2016-10-19 07:30:02 +00:00
|
|
|
/// assert_eq!(x.succeeded(), None);
|
|
|
|
///
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Forward(25);
|
|
|
|
/// assert_eq!(x.succeeded(), None);
|
|
|
|
/// ```
|
2017-02-03 10:16:46 +00:00
|
|
|
#[inline]
|
2016-10-14 01:39:23 +00:00
|
|
|
pub fn succeeded(self) -> Option<S> {
|
|
|
|
match self {
|
2016-10-25 09:17:49 +00:00
|
|
|
Success(val) => Some(val),
|
2016-10-14 01:39:23 +00:00
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Converts from `Outcome<S, E, F>` to `Option<E>`.
|
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// Returns the `Some` of the `Error` if this is an `Error`, otherwise
|
2016-10-14 01:39:23 +00:00
|
|
|
/// returns `None`. `self` is consumed, and all other values are discarded.
|
2016-10-19 07:30:02 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
/// assert_eq!(x.failed(), None);
|
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
|
2016-10-19 07:30:02 +00:00
|
|
|
/// assert_eq!(x.failed(), Some("Hi! I'm an error."));
|
|
|
|
///
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Forward(25);
|
|
|
|
/// assert_eq!(x.failed(), None);
|
|
|
|
/// ```
|
2017-02-03 10:16:46 +00:00
|
|
|
#[inline]
|
2016-10-14 01:39:23 +00:00
|
|
|
pub fn failed(self) -> Option<E> {
|
|
|
|
match self {
|
2023-10-31 17:11:03 +00:00
|
|
|
Error(val) => Some(val),
|
2016-10-14 01:39:23 +00:00
|
|
|
_ => None
|
2016-04-11 10:57:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-14 01:39:23 +00:00
|
|
|
/// Converts from `Outcome<S, E, F>` to `Option<F>`.
|
|
|
|
///
|
|
|
|
/// Returns the `Some` of the `Forward` if this is a `Forward`, otherwise
|
|
|
|
/// returns `None`. `self` is consumed, and all other values are discarded.
|
2016-10-19 07:30:02 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
/// assert_eq!(x.forwarded(), None);
|
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
|
2016-10-19 07:30:02 +00:00
|
|
|
/// assert_eq!(x.forwarded(), None);
|
|
|
|
///
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Forward(25);
|
|
|
|
/// assert_eq!(x.forwarded(), Some(25));
|
|
|
|
/// ```
|
2017-02-03 10:16:46 +00:00
|
|
|
#[inline]
|
2016-10-14 01:39:23 +00:00
|
|
|
pub fn forwarded(self) -> Option<F> {
|
|
|
|
match self {
|
2016-10-25 09:17:49 +00:00
|
|
|
Forward(val) => Some(val),
|
2016-10-14 01:39:23 +00:00
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
/// Returns a `Success` value as `Ok()` or `value` in `Err`. Converts from
|
|
|
|
/// `Outcome<S, E, F>` to `Result<S, T>` for a given `T`.
|
2017-12-24 04:23:03 +00:00
|
|
|
///
|
|
|
|
/// Returns `Ok` with the `Success` value if this is a `Success`, otherwise
|
|
|
|
/// returns an `Err` with the provided value. `self` is consumed, and all
|
|
|
|
/// other values are discarded.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
/// assert_eq!(x.success_or(false), Ok(10));
|
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
|
2017-12-24 04:23:03 +00:00
|
|
|
/// assert_eq!(x.success_or(false), Err(false));
|
|
|
|
///
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Forward(25);
|
|
|
|
/// assert_eq!(x.success_or("whoops"), Err("whoops"));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn success_or<T>(self, value: T) -> Result<S, T> {
|
|
|
|
match self {
|
|
|
|
Success(val) => Ok(val),
|
|
|
|
_ => Err(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
|
|
|
/// Returns a `Success` value as `Ok()` or `f()` in `Err`. Converts from
|
|
|
|
/// `Outcome<S, E, F>` to `Result<S, T>` for a given `T` produced from a
|
|
|
|
/// supplied function or closure.
|
2017-12-24 04:23:03 +00:00
|
|
|
///
|
|
|
|
/// Returns `Ok` with the `Success` value if this is a `Success`, otherwise
|
|
|
|
/// returns an `Err` with the result of calling `f`. `self` is consumed, and
|
|
|
|
/// all other values are discarded.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
/// assert_eq!(x.success_or_else(|| false), Ok(10));
|
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
|
2017-12-24 04:23:03 +00:00
|
|
|
/// assert_eq!(x.success_or_else(|| false), Err(false));
|
|
|
|
///
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Forward(25);
|
|
|
|
/// assert_eq!(x.success_or_else(|| "whoops"), Err("whoops"));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn success_or_else<T, V: FnOnce() -> T>(self, f: V) -> Result<S, T> {
|
|
|
|
match self {
|
|
|
|
Success(val) => Ok(val),
|
|
|
|
_ => Err(f())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-19 07:30:02 +00:00
|
|
|
/// Converts from `Outcome<S, E, F>` to `Outcome<&S, &E, &F>`.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
/// assert_eq!(x.as_ref(), Success(&10));
|
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, usize> = Error("Hi! I'm an error.");
|
|
|
|
/// assert_eq!(x.as_ref(), Error(&"Hi! I'm an error."));
|
2016-10-19 07:30:02 +00:00
|
|
|
/// ```
|
2017-02-03 10:16:46 +00:00
|
|
|
#[inline]
|
2016-10-19 07:30:02 +00:00
|
|
|
pub fn as_ref(&self) -> Outcome<&S, &E, &F> {
|
|
|
|
match *self {
|
2016-10-25 09:17:49 +00:00
|
|
|
Success(ref val) => Success(val),
|
2023-10-31 17:11:03 +00:00
|
|
|
Error(ref val) => Error(val),
|
2016-10-25 09:17:49 +00:00
|
|
|
Forward(ref val) => Forward(val),
|
2016-10-19 07:30:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-23 03:37:18 +00:00
|
|
|
/// Converts from `Outcome<S, E, F>` to `Outcome<&mut S, &mut E, &mut F>`.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let mut x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
/// if let Success(val) = x.as_mut() {
|
|
|
|
/// *val = 20;
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// assert_eq!(x.unwrap(), 20);
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn as_mut(&mut self) -> Outcome<&mut S, &mut E, &mut F> {
|
|
|
|
match *self {
|
|
|
|
Success(ref mut val) => Success(val),
|
2023-10-31 17:11:03 +00:00
|
|
|
Error(ref mut val) => Error(val),
|
2021-05-23 03:37:18 +00:00
|
|
|
Forward(ref mut val) => Forward(val),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
/// Maps the `Success` value using `f`. Maps an `Outcome<S, E, F>` to an
|
|
|
|
/// `Outcome<T, E, F>` by applying the function `f` to the value of type `S`
|
|
|
|
/// in `self` if `self` is an `Outcome::Success`.
|
2017-04-19 04:52:02 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
///
|
|
|
|
/// let mapped = x.map(|v| if v == 10 { "10" } else { "not 10" });
|
|
|
|
/// assert_eq!(mapped, Success("10"));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn map<T, M: FnOnce(S) -> T>(self, f: M) -> Outcome<T, E, F> {
|
|
|
|
match self {
|
|
|
|
Success(val) => Success(f(val)),
|
2023-10-31 17:11:03 +00:00
|
|
|
Error(val) => Error(val),
|
2017-04-19 04:52:02 +00:00
|
|
|
Forward(val) => Forward(val),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-31 17:11:03 +00:00
|
|
|
/// Maps the `Error` value using `f`. Maps an `Outcome<S, E, F>` to an
|
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
|
|
|
/// `Outcome<S, T, F>` by applying the function `f` to the value of type `E`
|
2023-10-31 17:11:03 +00:00
|
|
|
/// in `self` if `self` is an `Outcome::Error`.
|
2017-04-19 04:52:02 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, usize> = Error("hi");
|
2017-04-19 04:52:02 +00:00
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let mapped = x.map_error(|v| if v == "hi" { 10 } else { 0 });
|
|
|
|
/// assert_eq!(mapped, Error(10));
|
2017-04-19 04:52:02 +00:00
|
|
|
/// ```
|
|
|
|
#[inline]
|
2023-10-31 17:11:03 +00:00
|
|
|
pub fn map_error<T, M: FnOnce(E) -> T>(self, f: M) -> Outcome<S, T, F> {
|
2017-04-19 04:52:02 +00:00
|
|
|
match self {
|
|
|
|
Success(val) => Success(val),
|
2023-10-31 17:11:03 +00:00
|
|
|
Error(val) => Error(f(val)),
|
2017-04-19 04:52:02 +00:00
|
|
|
Forward(val) => Forward(val),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
/// Maps the `Forward` value using `f`. Maps an `Outcome<S, E, F>` to an
|
|
|
|
/// `Outcome<S, E, T>` by applying the function `f` to the value of type `F`
|
|
|
|
/// in `self` if `self` is an `Outcome::Forward`.
|
2017-04-19 04:52:02 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Forward(5);
|
|
|
|
///
|
|
|
|
/// let mapped = x.map_forward(|v| if v == 5 { "a" } else { "b" });
|
|
|
|
/// assert_eq!(mapped, Forward("a"));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn map_forward<T, M: FnOnce(F) -> T>(self, f: M) -> Outcome<S, E, T> {
|
|
|
|
match self {
|
|
|
|
Success(val) => Success(val),
|
2023-10-31 17:11:03 +00:00
|
|
|
Error(val) => Error(val),
|
2017-04-19 04:52:02 +00:00
|
|
|
Forward(val) => Forward(f(val)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-23 03:37:18 +00:00
|
|
|
/// Converts from `Outcome<S, E, F>` to `Outcome<T, E, F>` using `f` to map
|
|
|
|
/// `Success(S)` to `Success(T)`.
|
|
|
|
///
|
|
|
|
/// If `self` is not `Success`, `self` is returned.
|
2018-07-29 10:34:35 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, bool> = Success(10);
|
|
|
|
///
|
|
|
|
/// let mapped = x.and_then(|v| match v {
|
|
|
|
/// 10 => Success("10"),
|
|
|
|
/// 1 => Forward(false),
|
2023-10-31 17:11:03 +00:00
|
|
|
/// _ => Error("30")
|
2018-07-29 10:34:35 +00:00
|
|
|
/// });
|
|
|
|
///
|
|
|
|
/// assert_eq!(mapped, Success("10"));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn and_then<T, M: FnOnce(S) -> Outcome<T, E, F>>(self, f: M) -> Outcome<T, E, F> {
|
|
|
|
match self {
|
|
|
|
Success(val) => f(val),
|
2023-10-31 17:11:03 +00:00
|
|
|
Error(val) => Error(val),
|
2018-07-29 10:34:35 +00:00
|
|
|
Forward(val) => Forward(val),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-23 03:37:18 +00:00
|
|
|
/// Converts from `Outcome<S, E, F>` to `Outcome<S, T, F>` using `f` to map
|
2023-10-31 17:11:03 +00:00
|
|
|
/// `Error(E)` to `Error(T)`.
|
2021-05-23 03:37:18 +00:00
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// If `self` is not `Error`, `self` is returned.
|
2018-07-29 10:34:35 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, bool> = Error("hi");
|
2018-07-29 10:34:35 +00:00
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let mapped = x.error_then(|v| match v {
|
|
|
|
/// "hi" => Error(10),
|
2018-07-29 10:34:35 +00:00
|
|
|
/// "test" => Forward(false),
|
|
|
|
/// _ => Success(10)
|
|
|
|
/// });
|
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// assert_eq!(mapped, Error(10));
|
2018-07-29 10:34:35 +00:00
|
|
|
/// ```
|
|
|
|
#[inline]
|
2023-10-31 17:11:03 +00:00
|
|
|
pub fn error_then<T, M: FnOnce(E) -> Outcome<S, T, F>>(self, f: M) -> Outcome<S, T, F> {
|
2018-07-29 10:34:35 +00:00
|
|
|
match self {
|
|
|
|
Success(val) => Success(val),
|
2023-10-31 17:11:03 +00:00
|
|
|
Error(val) => f(val),
|
2018-07-29 10:34:35 +00:00
|
|
|
Forward(val) => Forward(val),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-23 03:37:18 +00:00
|
|
|
/// Converts from `Outcome<S, E, F>` to `Outcome<S, E, T>` using `f` to map
|
|
|
|
/// `Forward(F)` to `Forward(T)`.
|
|
|
|
///
|
|
|
|
/// If `self` is not `Forward`, `self` is returned.
|
2018-07-29 10:34:35 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, Option<bool>> = Forward(Some(false));
|
|
|
|
///
|
|
|
|
/// let mapped = x.forward_then(|v| match v {
|
|
|
|
/// Some(true) => Success(10),
|
|
|
|
/// Some(false) => Forward(20),
|
2023-10-31 17:11:03 +00:00
|
|
|
/// None => Error("10")
|
2018-07-29 10:34:35 +00:00
|
|
|
/// });
|
|
|
|
///
|
|
|
|
/// assert_eq!(mapped, Forward(20));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn forward_then<T, M: FnOnce(F) -> Outcome<S, E, T>>(self, f: M) -> Outcome<S, E, T> {
|
|
|
|
match self {
|
|
|
|
Success(val) => Success(val),
|
2023-10-31 17:11:03 +00:00
|
|
|
Error(val) => Error(val),
|
2018-07-29 10:34:35 +00:00
|
|
|
Forward(val) => f(val),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-23 03:37:42 +00:00
|
|
|
/// Converts `Outcome<S, E, F>` to `Result<S, E>` by identity mapping
|
2023-10-31 17:11:03 +00:00
|
|
|
/// `Success(S)` and `Error(E)` to `Result<T, E>` and mapping `Forward(F)`
|
2021-05-23 03:37:42 +00:00
|
|
|
/// to `Result<T, E>` using `f`.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
|
|
|
/// assert_eq!(x.ok_map_forward(|x| Ok(x as i32 + 1)), Ok(10));
|
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, usize> = Error("hello");
|
2021-05-23 03:37:42 +00:00
|
|
|
/// assert_eq!(x.ok_map_forward(|x| Ok(x as i32 + 1)), Err("hello"));
|
|
|
|
///
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Forward(0);
|
|
|
|
/// assert_eq!(x.ok_map_forward(|x| Ok(x as i32 + 1)), Ok(1));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn ok_map_forward<M>(self, f: M) -> Result<S, E>
|
|
|
|
where M: FnOnce(F) -> Result<S, E>
|
|
|
|
{
|
|
|
|
match self {
|
|
|
|
Outcome::Success(s) => Ok(s),
|
2023-10-31 17:11:03 +00:00
|
|
|
Outcome::Error(e) => Err(e),
|
2021-05-23 03:37:42 +00:00
|
|
|
Outcome::Forward(v) => f(v),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Converts `Outcome<S, E, F>` to `Result<S, E>` by identity mapping
|
2023-10-31 17:11:03 +00:00
|
|
|
/// `Success(S)` and `Forward(F)` to `Result<T, F>` and mapping `Error(E)`
|
2021-05-23 03:37:42 +00:00
|
|
|
/// to `Result<T, F>` using `f`.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use rocket::outcome::Outcome;
|
|
|
|
/// # use rocket::outcome::Outcome::*;
|
|
|
|
/// #
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Success(10);
|
2023-10-31 17:11:03 +00:00
|
|
|
/// assert_eq!(x.ok_map_error(|s| Ok(123)), Ok(10));
|
2021-05-23 03:37:42 +00:00
|
|
|
///
|
2023-10-31 17:11:03 +00:00
|
|
|
/// let x: Outcome<i32, &str, usize> = Error("hello");
|
|
|
|
/// assert_eq!(x.ok_map_error(|s| Ok(123)), Ok(123));
|
2021-05-23 03:37:42 +00:00
|
|
|
///
|
|
|
|
/// let x: Outcome<i32, &str, usize> = Forward(0);
|
2023-10-31 17:11:03 +00:00
|
|
|
/// assert_eq!(x.ok_map_error(|s| Ok(123)), Err(0));
|
2021-05-23 03:37:42 +00:00
|
|
|
/// ```
|
|
|
|
#[inline]
|
2023-10-31 17:11:03 +00:00
|
|
|
pub fn ok_map_error<M>(self, f: M) -> Result<S, F>
|
2021-05-23 03:37:42 +00:00
|
|
|
where M: FnOnce(E) -> Result<S, F>
|
|
|
|
{
|
|
|
|
match self {
|
|
|
|
Outcome::Success(s) => Ok(s),
|
2023-10-31 17:11:03 +00:00
|
|
|
Outcome::Error(e) => f(e),
|
2021-05-23 03:37:42 +00:00
|
|
|
Outcome::Forward(v) => Err(v),
|
|
|
|
}
|
|
|
|
}
|
2016-04-11 10:57:23 +00:00
|
|
|
}
|
2021-05-23 03:37:18 +00:00
|
|
|
|
2020-06-19 13:01:10 +00:00
|
|
|
impl<'a, S: Send + 'a, E: Send + 'a, F: Send + 'a> Outcome<S, E, F> {
|
2021-04-28 08:41:13 +00:00
|
|
|
/// Pins a future that resolves to `self`, returning a
|
|
|
|
/// [`BoxFuture`](crate::futures::future::BoxFuture) that resolves to
|
|
|
|
/// `self`.
|
2020-06-19 13:01:10 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn pin(self) -> futures::future::BoxFuture<'a, Self> {
|
|
|
|
Box::pin(async move { self })
|
|
|
|
}
|
|
|
|
}
|
2016-04-11 10:57:23 +00:00
|
|
|
|
2021-04-28 08:29:05 +00:00
|
|
|
crate::export! {
|
|
|
|
/// Unwraps a [`Success`](Outcome::Success) or propagates a `Forward` or
|
2023-10-31 17:11:03 +00:00
|
|
|
/// `Error` by returning early.
|
2021-04-28 08:29:05 +00:00
|
|
|
///
|
|
|
|
/// # Syntax
|
|
|
|
///
|
|
|
|
/// The macro has the following "signature":
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use rocket::outcome::Outcome;
|
|
|
|
///
|
|
|
|
/// // Returns the inner `S` if `outcome` is `Outcome::Success`. Otherwise
|
|
|
|
/// // returns from the caller with `Outcome<impl From<E>, impl From<F>>`.
|
|
|
|
/// fn try_outcome<S, E, F>(outcome: Outcome<S, E, F>) -> S
|
|
|
|
/// # { unimplemented!() }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// This is just like `?` (or previously, `try!`), but for `Outcome`. In the
|
2023-10-31 17:11:03 +00:00
|
|
|
/// case of a `Forward` or `Error` variant, the inner type is passed to
|
2021-04-28 08:29:05 +00:00
|
|
|
/// [`From`](std::convert::From), allowing for the conversion between
|
|
|
|
/// specific and more general types. The resulting forward/error is
|
|
|
|
/// immediately returned. Because of the early return, `try_outcome!` can
|
|
|
|
/// only be used in methods that return [`Outcome`].
|
|
|
|
///
|
|
|
|
/// [`Outcome`]: crate::outcome::Outcome
|
|
|
|
///
|
|
|
|
/// ## Example
|
|
|
|
///
|
|
|
|
/// ```rust,no_run
|
|
|
|
/// # #[macro_use] extern crate rocket;
|
|
|
|
/// use std::sync::atomic::{AtomicUsize, Ordering};
|
|
|
|
///
|
|
|
|
/// use rocket::State;
|
|
|
|
/// use rocket::request::{self, Request, FromRequest};
|
|
|
|
/// use rocket::outcome::{try_outcome, Outcome::*};
|
|
|
|
///
|
|
|
|
/// #[derive(Default)]
|
|
|
|
/// struct Atomics {
|
|
|
|
/// uncached: AtomicUsize,
|
|
|
|
/// cached: AtomicUsize,
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// struct Guard1;
|
|
|
|
/// struct Guard2;
|
|
|
|
///
|
|
|
|
/// #[rocket::async_trait]
|
|
|
|
/// impl<'r> FromRequest<'r> for Guard1 {
|
|
|
|
/// type Error = ();
|
|
|
|
///
|
|
|
|
/// async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
|
|
|
/// // Attempt to fetch the guard, passing through any error or forward.
|
2021-05-11 13:56:35 +00:00
|
|
|
/// let atomics = try_outcome!(req.guard::<&State<Atomics>>().await);
|
2021-04-28 08:29:05 +00:00
|
|
|
/// atomics.uncached.fetch_add(1, Ordering::Relaxed);
|
|
|
|
/// req.local_cache(|| atomics.cached.fetch_add(1, Ordering::Relaxed));
|
|
|
|
///
|
|
|
|
/// Success(Guard1)
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// #[rocket::async_trait]
|
|
|
|
/// impl<'r> FromRequest<'r> for Guard2 {
|
|
|
|
/// type Error = ();
|
|
|
|
///
|
|
|
|
/// async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
|
|
|
/// // Attempt to fetch the guard, passing through any error or forward.
|
|
|
|
/// let guard1: Guard1 = try_outcome!(req.guard::<Guard1>().await);
|
|
|
|
/// Success(Guard2)
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
macro_rules! try_outcome {
|
|
|
|
($expr:expr $(,)?) => (match $expr {
|
|
|
|
$crate::outcome::Outcome::Success(val) => val,
|
2023-10-31 17:11:03 +00:00
|
|
|
$crate::outcome::Outcome::Error(e) => {
|
|
|
|
return $crate::outcome::Outcome::Error(::std::convert::From::from(e))
|
2021-04-28 08:29:05 +00:00
|
|
|
},
|
|
|
|
$crate::outcome::Outcome::Forward(f) => {
|
|
|
|
return $crate::outcome::Outcome::Forward(::std::convert::From::from(f))
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
2017-06-24 09:49:16 +00:00
|
|
|
}
|
|
|
|
|
Improve forwarding status code precision.
Previously, the `NotFound` status code was used to signal many kinds of
recoverable, forwarding errors. This included validation errors, incorrect
Content-Type errors, and more.
This commit modifies the status code used to forward in these instances to more
precisely indicate the forwarding condition. In particular:
* Parameter `FromParam` errors now forward as 422 (`UnprocessableEntity`).
* Query paramater errors now forward as 422 (`UnprocessableEntity`).
* Use of incorrect form content-type forwards as 413 (`UnsupportedMediaType`).
* `WebSocket` guard now forwards as 400 (`BadRequest`).
* `&Host`, `&Accept`, `&ContentType`, `IpAddr`, and `SocketAddr` all forward
with a 500 (`InternalServerError`).
Additionally, the `IntoOutcome` trait was overhauled to support functionality
previously offered by methods on `Outcome`. The `Outcome::forward()` method now
requires a status code to use for the forwarding outcome.
Finally, logging of `Outcome`s now includes the relevant status code.
Resolves #2626.
2023-10-31 23:27:03 +00:00
|
|
|
impl<S, E, F> Outcome<S, E, F> {
|
|
|
|
#[inline]
|
|
|
|
fn dbg_str(&self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
Success(..) => "Success",
|
|
|
|
Error(..) => "Error",
|
|
|
|
Forward(..) => "Forward",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn color(&self) -> Color {
|
|
|
|
match self {
|
|
|
|
Success(..) => Color::Green,
|
|
|
|
Error(..) => Color::Red,
|
|
|
|
Forward(..) => Color::Yellow,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) struct Display<'a, 'r>(&'a route::Outcome<'r>);
|
|
|
|
|
|
|
|
impl<'r> route::Outcome<'r> {
|
|
|
|
pub(crate) fn log_display(&self) -> Display<'_, 'r> {
|
|
|
|
impl fmt::Display for Display<'_, '_> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
write!(f, "{}", "Outcome: ".primary().bold())?;
|
|
|
|
|
|
|
|
let color = self.0.color();
|
|
|
|
match self.0 {
|
|
|
|
Success(r) => write!(f, "{}({})", "Success".paint(color), r.status().primary()),
|
|
|
|
Error(s) => write!(f, "{}({})", "Error".paint(color), s.primary()),
|
|
|
|
Forward((_, s)) => write!(f, "{}({})", "Forward".paint(color), s.primary()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Display(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-14 01:39:23 +00:00
|
|
|
impl<S, E, F> fmt::Debug for Outcome<S, E, F> {
|
2019-06-13 01:48:02 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
Improve forwarding status code precision.
Previously, the `NotFound` status code was used to signal many kinds of
recoverable, forwarding errors. This included validation errors, incorrect
Content-Type errors, and more.
This commit modifies the status code used to forward in these instances to more
precisely indicate the forwarding condition. In particular:
* Parameter `FromParam` errors now forward as 422 (`UnprocessableEntity`).
* Query paramater errors now forward as 422 (`UnprocessableEntity`).
* Use of incorrect form content-type forwards as 413 (`UnsupportedMediaType`).
* `WebSocket` guard now forwards as 400 (`BadRequest`).
* `&Host`, `&Accept`, `&ContentType`, `IpAddr`, and `SocketAddr` all forward
with a 500 (`InternalServerError`).
Additionally, the `IntoOutcome` trait was overhauled to support functionality
previously offered by methods on `Outcome`. The `Outcome::forward()` method now
requires a status code to use for the forwarding outcome.
Finally, logging of `Outcome`s now includes the relevant status code.
Resolves #2626.
2023-10-31 23:27:03 +00:00
|
|
|
write!(f, "Outcome::{}", self.dbg_str())
|
2016-04-11 10:57:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-14 01:39:23 +00:00
|
|
|
impl<S, E, F> fmt::Display for Outcome<S, E, F> {
|
2019-06-13 01:48:02 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
Improve forwarding status code precision.
Previously, the `NotFound` status code was used to signal many kinds of
recoverable, forwarding errors. This included validation errors, incorrect
Content-Type errors, and more.
This commit modifies the status code used to forward in these instances to more
precisely indicate the forwarding condition. In particular:
* Parameter `FromParam` errors now forward as 422 (`UnprocessableEntity`).
* Query paramater errors now forward as 422 (`UnprocessableEntity`).
* Use of incorrect form content-type forwards as 413 (`UnsupportedMediaType`).
* `WebSocket` guard now forwards as 400 (`BadRequest`).
* `&Host`, `&Accept`, `&ContentType`, `IpAddr`, and `SocketAddr` all forward
with a 500 (`InternalServerError`).
Additionally, the `IntoOutcome` trait was overhauled to support functionality
previously offered by methods on `Outcome`. The `Outcome::forward()` method now
requires a status code to use for the forwarding outcome.
Finally, logging of `Outcome`s now includes the relevant status code.
Resolves #2626.
2023-10-31 23:27:03 +00:00
|
|
|
write!(f, "{}", self.dbg_str().paint(self.color()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Conversion trait from some type into an Outcome type.
|
|
|
|
pub trait IntoOutcome<Outcome> {
|
|
|
|
/// The type to use when returning an `Outcome::Error`.
|
|
|
|
type Error: Sized;
|
|
|
|
|
|
|
|
/// The type to use when returning an `Outcome::Forward`.
|
|
|
|
type Forward: Sized;
|
|
|
|
|
|
|
|
/// Converts `self` into an `Outcome`. If `self` represents a success, an
|
|
|
|
/// `Outcome::Success` is returned. Otherwise, an `Outcome::Error` is
|
|
|
|
/// returned with `error` as the inner value.
|
|
|
|
fn or_error(self, error: Self::Error) -> Outcome;
|
|
|
|
|
|
|
|
/// Converts `self` into an `Outcome`. If `self` represents a success, an
|
|
|
|
/// `Outcome::Success` is returned. Otherwise, an `Outcome::Forward` is
|
|
|
|
/// returned with `forward` as the inner value.
|
|
|
|
fn or_forward(self, forward: Self::Forward) -> Outcome;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<S, E, F> IntoOutcome<Outcome<S, E, F>> for Option<S> {
|
|
|
|
type Error = E;
|
|
|
|
type Forward = F;
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn or_error(self, error: E) -> Outcome<S, E, F> {
|
|
|
|
match self {
|
|
|
|
Some(val) => Success(val),
|
|
|
|
None => Error(error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn or_forward(self, forward: F) -> Outcome<S, E, F> {
|
|
|
|
match self {
|
|
|
|
Some(val) => Success(val),
|
|
|
|
None => Forward(forward)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'r, T: FromData<'r>> IntoOutcome<data::Outcome<'r, T>> for Result<T, T::Error> {
|
|
|
|
type Error = Status;
|
|
|
|
type Forward = (Data<'r>, Status);
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn or_error(self, error: Status) -> data::Outcome<'r, T> {
|
|
|
|
match self {
|
|
|
|
Ok(val) => Success(val),
|
|
|
|
Err(err) => Error((error, err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn or_forward(self, (data, forward): (Data<'r>, Status)) -> data::Outcome<'r, T> {
|
|
|
|
match self {
|
|
|
|
Ok(val) => Success(val),
|
|
|
|
Err(_) => Forward((data, forward))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<S, E> IntoOutcome<request::Outcome<S, E>> for Result<S, E> {
|
|
|
|
type Error = Status;
|
|
|
|
type Forward = Status;
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn or_error(self, error: Status) -> request::Outcome<S, E> {
|
|
|
|
match self {
|
|
|
|
Ok(val) => Success(val),
|
|
|
|
Err(err) => Error((error, err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn or_forward(self, status: Status) -> request::Outcome<S, E> {
|
|
|
|
match self {
|
|
|
|
Ok(val) => Success(val),
|
|
|
|
Err(_) => Forward(status)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'r, 'o: 'r> IntoOutcome<route::Outcome<'r>> for response::Result<'o> {
|
|
|
|
type Error = ();
|
|
|
|
type Forward = (Data<'r>, Status);
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn or_error(self, _: ()) -> route::Outcome<'r> {
|
|
|
|
match self {
|
|
|
|
Ok(val) => Success(val),
|
|
|
|
Err(status) => Error(status),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn or_forward(self, (data, forward): (Data<'r>, Status)) -> route::Outcome<'r> {
|
|
|
|
match self {
|
|
|
|
Ok(val) => Success(val),
|
|
|
|
Err(_) => Forward((data, forward))
|
|
|
|
}
|
2016-04-11 10:57:23 +00:00
|
|
|
}
|
|
|
|
}
|