Rearrange top-level exports. Use '#[launch]'.

This commits makes the following high-level changes:

  * 'ShutdownHandle' is renamed to 'Shutdown'.
  * 'Rocket::shutdown_handle()' is renamed to 'Rocket::shutdown()'.
  * '#[launch]` is preferred to '#[rocket::launch]'.
  * Various docs phrasings are improved.
  * Fixed various broken links in docs.

This commits rearranges top-level exports as follows:

  * 'shutdown' module is no longer exported.
  * 'Shutdown' is exported from the crate root.
  * 'Outcome' is not longer exported from the root.
  * 'Handler', 'ErrorHandler' are no longer exported from the root.
This commit is contained in:
Sergio Benitez 2020-07-22 16:10:02 -07:00
parent 9895eb736d
commit adc79016cd
57 changed files with 278 additions and 275 deletions

View File

@ -145,15 +145,15 @@ pub fn database_attr(attr: TokenStream, input: TokenStream) -> Result<TokenStrea
type Error = ();
async fn from_request(request: &'a #request::Request<'r>) -> #request::Outcome<Self, ()> {
use ::rocket::{Outcome, http::Status};
use ::rocket::http::Status;
let guard = request.guard::<::rocket::State<'_, #pool_type>>();
let pool = ::rocket::try_outcome!(guard.await).0.clone();
#spawn_blocking(move || {
match pool.get() {
Ok(conn) => Outcome::Success(#guard_type(conn)),
Err(_) => Outcome::Failure((Status::ServiceUnavailable, ())),
Ok(conn) => #request::Outcome::Success(#guard_type(conn)),
Err(_) => #request::Outcome::Failure((Status::ServiceUnavailable, ())),
}
}).await.expect("failed to spawn a blocking task to get a pooled connection")
}

View File

@ -60,7 +60,7 @@
//! #[database("sqlite_logs")]
//! struct LogsDbConn(diesel::SqliteConnection);
//!
//! #[rocket::launch]
//! #[launch]
//! fn rocket() -> rocket::Rocket {
//! rocket::ignite().attach(LogsDbConn::fairing())
//! }
@ -138,14 +138,14 @@
//! The example below does just this:
//!
//! ```rust
//! extern crate rocket;
//! #[macro_use] extern crate rocket;
//!
//! # #[cfg(feature = "diesel_sqlite_pool")]
//! # mod test {
//! use std::collections::HashMap;
//! use rocket::config::{Config, Environment, Value};
//!
//! #[rocket::launch]
//! #[launch]
//! fn rocket() -> rocket::Rocket {
//! let mut database_config = HashMap::new();
//! let mut databases = HashMap::new();
@ -246,7 +246,7 @@
//! together, a use of the `#[database]` attribute looks as follows:
//!
//! ```rust
//! # extern crate rocket;
//! # #[macro_use] extern crate rocket;
//! # #[macro_use] extern crate rocket_contrib;
//! #
//! # #[cfg(feature = "diesel_sqlite_pool")]
@ -259,7 +259,7 @@
//! #[database("my_db")]
//! struct MyDatabase(diesel::SqliteConnection);
//!
//! #[rocket::launch]
//! #[launch]
//! fn rocket() -> rocket::Rocket {
//! # let mut db_config = HashMap::new();
//! # let mut databases = HashMap::new();

View File

@ -131,11 +131,11 @@ impl std::ops::BitOr for Options {
/// requests for a directory (the default), you might write the following:
///
/// ```rust,no_run
/// # extern crate rocket;
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// use rocket_contrib::serve::StaticFiles;
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// rocket::ignite().mount("/public", StaticFiles::from("/static"))
/// }
@ -154,11 +154,11 @@ impl std::ops::BitOr for Options {
/// the `static` subdirectory of your crate at `/`, you might write:
///
/// ```rust,no_run
/// # extern crate rocket;
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// use rocket_contrib::serve::StaticFiles;
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// rocket::ignite()
/// .mount("/", StaticFiles::from(concat!(env!("CARGO_MANIFEST_DIR"), "/static")))
@ -187,11 +187,11 @@ impl StaticFiles {
/// `/static`.
///
/// ```rust,no_run
/// # extern crate rocket;
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// use rocket_contrib::serve::StaticFiles;
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// rocket::ignite().mount("/static", StaticFiles::from("/www/public"))
/// }
@ -200,11 +200,11 @@ impl StaticFiles {
/// Exactly as before, but set the rank for generated routes to `30`.
///
/// ```rust,no_run
/// # extern crate rocket;
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// use rocket_contrib::serve::StaticFiles;
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// rocket::ignite().mount("/static", StaticFiles::from("/www/public").rank(30))
/// }
@ -225,11 +225,11 @@ impl StaticFiles {
/// index files and dot files.
///
/// ```rust,no_run
/// # extern crate rocket;
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// use rocket_contrib::serve::{StaticFiles, Options};
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// let options = Options::Index | Options::DotFiles;
/// rocket::ignite()

View File

@ -1,4 +1,4 @@
use rocket::{Request, State, Outcome};
use rocket::{Request, State};
use rocket::http::Status;
use rocket::request::{self, FromRequest};
@ -91,12 +91,12 @@ impl<'a, 'r> FromRequest<'a, 'r> for Metadata<'a> {
async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, ()> {
request.guard::<State<'_, ContextManager>>().await
.succeeded()
.and_then(|cm| Some(Outcome::Success(Metadata(cm.inner()))))
.and_then(|cm| Some(request::Outcome::Success(Metadata(cm.inner()))))
.unwrap_or_else(|| {
error_!("Uninitialized template context: missing fairing.");
info_!("To use templates, you must attach `Template::fairing()`.");
info_!("See the `Template` documentation for more information.");
Outcome::Failure((Status::InternalServerError, ()))
request::Outcome::Failure((Status::InternalServerError, ()))
})
}
}

View File

@ -82,14 +82,14 @@ vars_and_mods! {
response => rocket::response,
handler => rocket::handler,
log => rocket::logger,
Outcome => rocket::Outcome,
Outcome => rocket::outcome::Outcome,
FromTransformedData => rocket::data::FromTransformedData,
Transform => rocket::data::Transform,
Query => rocket::request::Query,
FromFormValue => rocket::request::FromFormValue,
Request => rocket::Request,
Request => rocket::request::Request,
Response => rocket::response::Response,
Data => rocket::Data,
Data => rocket::data::Data,
StaticRouteInfo => rocket::StaticRouteInfo,
SmallVec => rocket::http::private::SmallVec,
HandlerFuture => rocket::handler::HandlerFuture,
@ -322,7 +322,7 @@ macro_rules! route_attribute {
/// [`routes!`]: macro.routes.html
/// [`uri!`]: macro.uri.html
/// [`Origin`]: ../rocket/http/uri/struct.Origin.html
/// [`Outcome`]: ../rocket/enum.Outcome.html
/// [`Outcome`]: ../rocket/outcome/enum.Outcome.html
/// [`Response`]: ../rocket/struct.Response.html
/// [`FromRequest` Outcomes]: ../rocket/request/trait.FromRequest.html#outcomes
/// [`FromTransformedData` Outcomes]: ../rocket/data/trait.FromTransformedData.html#outcomes
@ -878,9 +878,9 @@ pub fn catchers(input: TokenStream) -> TokenStream {
emit!(bang::catchers_macro(input))
}
/// Type safe generation of route URIs.
/// Type-safe, URI-safe generation of an [`Origin`] URI from a route.
///
/// The `uri!` macro creates a type-safe, URL safe URI given a route and values
/// The `uri!` macro creates a type-safe, URL-safe URI given a route and values
/// for the route's URI parameters. The inputs to the macro are the path to a
/// route, a colon, and one argument for each dynamic parameter (parameters in
/// `<>`) in the route's path and query.

View File

@ -1,6 +1,6 @@
#[macro_use] extern crate rocket;
use rocket::{Request, Data, Outcome::*};
use rocket::{Request, Data};
use rocket::local::blocking::Client;
use rocket::request::Form;
use rocket::data::{self, FromData};
@ -24,10 +24,10 @@ impl FromData for Simple {
let mut string = String::new();
let mut stream = data.open().take(64);
if let Err(_) = stream.read_to_string(&mut string).await {
return Failure((Status::InternalServerError, ()));
return data::Outcome::Failure((Status::InternalServerError, ()));
}
Success(Simple(string))
data::Outcome::Success(Simple(string))
}
}

View File

@ -7,11 +7,10 @@
use std::path::PathBuf;
use rocket::{Request, Outcome::*};
use rocket::http::ext::Normalize;
use rocket::local::blocking::Client;
use rocket::data::{self, Data, FromData};
use rocket::request::Form;
use rocket::request::{Request, Form};
use rocket::http::{Status, RawStr, ContentType};
use rocket::tokio::io::AsyncReadExt;
@ -32,7 +31,7 @@ impl FromData for Simple {
let mut string = String::new();
let mut stream = data.open().take(64);
stream.read_to_string(&mut string).await.unwrap();
Success(Simple(string))
data::Outcome::Success(Simple(string))
}
}

View File

@ -38,91 +38,91 @@ note: this function must be `async`
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: attribute cannot be applied to `main` function
--> $DIR/async-entry.rs:52:5
--> $DIR/async-entry.rs:51:5
|
52 | #[rocket::launch]
51 | #[rocket::launch]
| ^^^^^^^^^^^^^^^^^
|
= note: this attribute generates a `main` function
note: this function cannot be `main`
--> $DIR/async-entry.rs:53:8
--> $DIR/async-entry.rs:52:8
|
53 | fn main() -> rocket::Rocket {
52 | fn main() -> rocket::Rocket {
| ^^^^
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: attribute can only be applied to functions that return a value
--> $DIR/async-entry.rs:59:5
--> $DIR/async-entry.rs:58:5
|
59 | #[rocket::launch]
58 | #[rocket::launch]
| ^^^^^^^^^^^^^^^^^
|
note: this function must return a value
--> $DIR/async-entry.rs:60:5
--> $DIR/async-entry.rs:59:5
|
60 | async fn rocket() {
59 | async fn rocket() {
| ^^^^^^^^^^^^^^^^^
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: attribute can only be applied to functions that return a value
--> $DIR/async-entry.rs:67:5
--> $DIR/async-entry.rs:66:5
|
67 | #[rocket::launch]
66 | #[rocket::launch]
| ^^^^^^^^^^^^^^^^^
|
note: this function must return a value
--> $DIR/async-entry.rs:68:5
--> $DIR/async-entry.rs:67:5
|
68 | fn rocket() {
67 | fn rocket() {
| ^^^^^^^^^^^
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: attribute cannot be applied to `main` function
--> $DIR/async-entry.rs:82:5
--> $DIR/async-entry.rs:81:5
|
82 | #[rocket::launch]
81 | #[rocket::launch]
| ^^^^^^^^^^^^^^^^^
|
= note: this attribute generates a `main` function
note: this function cannot be `main`
--> $DIR/async-entry.rs:83:8
--> $DIR/async-entry.rs:82:8
|
83 | fn main() -> &'static str {
82 | fn main() -> &'static str {
| ^^^^
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: attribute cannot be applied to `main` function
--> $DIR/async-entry.rs:90:5
--> $DIR/async-entry.rs:89:5
|
90 | #[rocket::launch]
89 | #[rocket::launch]
| ^^^^^^^^^^^^^^^^^
|
= note: this attribute generates a `main` function
note: this function cannot be `main`
--> $DIR/async-entry.rs:91:14
--> $DIR/async-entry.rs:90:14
|
91 | async fn main() -> rocket::Rocket {
90 | async fn main() -> rocket::Rocket {
| ^^^^
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/async-entry.rs:76:17
--> $DIR/async-entry.rs:75:17
|
75 | fn rocket() -> rocket::Rocket {
74 | fn rocket() -> rocket::Rocket {
| ------ this is not `async`
76 | let _ = rocket::ignite().launch().await;
75 | let _ = rocket::ignite().launch().await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
error[E0308]: mismatched types
--> $DIR/async-entry.rs:38:9
--> $DIR/async-entry.rs:37:9
|
38 | rocket::ignite()
37 | rocket::ignite()
| ^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found struct `rocket::Rocket`
error[E0308]: mismatched types
--> $DIR/async-entry.rs:47:9
--> $DIR/async-entry.rs:46:9
|
47 | "hi".to_string()
46 | "hi".to_string()
| ^^^^^^^^^^^^^^^^ expected struct `rocket::Rocket`, found struct `std::string::String`
error[E0308]: mismatched types
@ -132,26 +132,25 @@ error[E0308]: mismatched types
| ^ expected `()` because of default return type
| _____________________|
| |
27 | |
28 | | rocket::ignite()
29 | | }
27 | | rocket::ignite()
28 | | }
| | ^- help: try adding a semicolon: `;`
| |_____|
| expected `()`, found struct `rocket::Rocket`
error[E0308]: mismatched types
--> $DIR/async-entry.rs:36:26
--> $DIR/async-entry.rs:35:26
|
36 | async fn rocket() -> String {
35 | async fn rocket() -> String {
| ^^^^^^
| |
| expected struct `rocket::Rocket`, found struct `std::string::String`
| expected due to this
error[E0277]: `main` has invalid return type `rocket::Rocket`
--> $DIR/async-entry.rs:97:20
--> $DIR/async-entry.rs:96:20
|
97 | async fn main() -> rocket::Rocket {
96 | async fn main() -> rocket::Rocket {
| ^^^^^^^^^^^^^^ `main` can only return types that implement `std::process::Termination`
|
= help: consider using `()`, or a `Result`

View File

@ -53,4 +53,4 @@ error[E0277]: the trait bound `usize: rocket::response::Responder<'_, '_>` is no
28 | fn foo() -> usize { 0 }
| ^^^^^ the trait `rocket::response::Responder<'_, '_>` is not implemented for `usize`
|
= note: required by `rocket::handler::<impl rocket::Outcome<rocket::Response<'o>, rocket::http::Status, rocket::Data>>::from`
= note: required by `rocket::handler::<impl rocket::outcome::Outcome<rocket::Response<'o>, rocket::http::Status, rocket::Data>>::from`

View File

@ -28,95 +28,95 @@ error: [note] this function must be `async`
error: attribute cannot be applied to `main` function
--- note: this attribute generates a `main` function
--> $DIR/async-entry.rs:52:5
--> $DIR/async-entry.rs:51:5
|
52 | #[rocket::launch]
51 | #[rocket::launch]
| ^^^^^^^^^^^^^^^^^
|
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: [note] this function cannot be `main`
--> $DIR/async-entry.rs:53:8
--> $DIR/async-entry.rs:52:8
|
53 | fn main() -> rocket::Rocket {
52 | fn main() -> rocket::Rocket {
| ^^^^
error: attribute can only be applied to functions that return a value
--> $DIR/async-entry.rs:59:5
--> $DIR/async-entry.rs:58:5
|
59 | #[rocket::launch]
58 | #[rocket::launch]
| ^^^^^^^^^^^^^^^^^
|
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: [note] this function must return a value
--> $DIR/async-entry.rs:60:5
--> $DIR/async-entry.rs:59:5
|
60 | async fn rocket() {
59 | async fn rocket() {
| ^^^^^
error: attribute can only be applied to functions that return a value
--> $DIR/async-entry.rs:67:5
--> $DIR/async-entry.rs:66:5
|
67 | #[rocket::launch]
66 | #[rocket::launch]
| ^^^^^^^^^^^^^^^^^
|
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: [note] this function must return a value
--> $DIR/async-entry.rs:68:5
--> $DIR/async-entry.rs:67:5
|
68 | fn rocket() {
67 | fn rocket() {
| ^^
error: attribute cannot be applied to `main` function
--- note: this attribute generates a `main` function
--> $DIR/async-entry.rs:82:5
--> $DIR/async-entry.rs:81:5
|
82 | #[rocket::launch]
81 | #[rocket::launch]
| ^^^^^^^^^^^^^^^^^
|
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: [note] this function cannot be `main`
--> $DIR/async-entry.rs:83:8
--> $DIR/async-entry.rs:82:8
|
83 | fn main() -> &'static str {
82 | fn main() -> &'static str {
| ^^^^
error: attribute cannot be applied to `main` function
--- note: this attribute generates a `main` function
--> $DIR/async-entry.rs:90:5
--> $DIR/async-entry.rs:89:5
|
90 | #[rocket::launch]
89 | #[rocket::launch]
| ^^^^^^^^^^^^^^^^^
|
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: [note] this function cannot be `main`
--> $DIR/async-entry.rs:91:14
--> $DIR/async-entry.rs:90:14
|
91 | async fn main() -> rocket::Rocket {
90 | async fn main() -> rocket::Rocket {
| ^^^^
error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/async-entry.rs:76:17
--> $DIR/async-entry.rs:75:17
|
75 | fn rocket() -> rocket::Rocket {
74 | fn rocket() -> rocket::Rocket {
| ------ this is not `async`
76 | let _ = rocket::ignite().launch().await;
75 | let _ = rocket::ignite().launch().await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
error[E0308]: mismatched types
--> $DIR/async-entry.rs:38:9
--> $DIR/async-entry.rs:37:9
|
38 | rocket::ignite()
37 | rocket::ignite()
| ^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found struct `rocket::rocket::Rocket`
error[E0308]: mismatched types
--> $DIR/async-entry.rs:47:9
--> $DIR/async-entry.rs:46:9
|
47 | "hi".to_string()
46 | "hi".to_string()
| ^^^^^^^^^^^^^^^^ expected struct `rocket::rocket::Rocket`, found struct `std::string::String`
error[E0308]: mismatched types
@ -126,26 +126,25 @@ error[E0308]: mismatched types
| ^ expected `()` because of default return type
| _____________________|
| |
27 | |
28 | | rocket::ignite()
29 | | }
27 | | rocket::ignite()
28 | | }
| | ^- help: try adding a semicolon: `;`
| |_____|
| expected `()`, found struct `rocket::rocket::Rocket`
error[E0308]: mismatched types
--> $DIR/async-entry.rs:36:26
--> $DIR/async-entry.rs:35:26
|
36 | async fn rocket() -> String {
35 | async fn rocket() -> String {
| ^^^^^^
| |
| expected struct `rocket::rocket::Rocket`, found struct `std::string::String`
| expected due to this
error[E0277]: `main` has invalid return type `rocket::rocket::Rocket`
--> $DIR/async-entry.rs:97:20
--> $DIR/async-entry.rs:96:20
|
97 | async fn main() -> rocket::Rocket {
96 | async fn main() -> rocket::Rocket {
| ^^^^^^^^^^^^^^ `main` can only return types that implement `std::process::Termination`
|
= help: consider using `()`, or a `Result`

View File

@ -53,4 +53,4 @@ error[E0277]: the trait bound `usize: rocket::response::Responder<'_, '_>` is no
28 | fn foo() -> usize { 0 }
| ^^^^^ the trait `rocket::response::Responder<'_, '_>` is not implemented for `usize`
|
= note: required by `rocket::handler::<impl rocket::Outcome<rocket::Response<'o>, rocket::http::Status, rocket::Data>>::from`
= note: required by `rocket::handler::<impl rocket::outcome::Outcome<rocket::Response<'o>, rocket::http::Status, rocket::Data>>::from`

View File

@ -24,12 +24,11 @@ mod main_d {
mod main_f {
#[rocket::main]
async fn main() {
rocket::ignite()
}
}
// rocket::launch
// launch
mod launch_a {
#[rocket::launch]

View File

@ -50,7 +50,7 @@ use yansi::Color::*;
/// format!("I couldn't find '{}'. Try something else?", req.uri())
/// }
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// rocket::ignite().register(catchers![internal_error, not_found])
/// }

View File

@ -123,16 +123,17 @@ pub type FromDataFuture<'fut, T, E> = BoxFuture<'fut, Outcome<T, E>>;
///
/// A data guard is a [request guard] that operates on a request's body data.
/// Data guards validate, parse, and optionally convert request body data.
/// Validation and parsing/conversion is implemented through `FromTransformedData`. In
/// other words, every type that implements `FromTransformedData` is a data guard.
/// Validation and parsing/conversion is implemented through
/// `FromTransformedData`. In other words, every type that implements
/// `FromTransformedData` is a data guard.
///
/// Data guards are used as the target of the `data` route attribute parameter.
/// A handler can have at most one data guard.
///
/// For many data guards, implementing [`FromData`] will be simpler and
/// sufficient. All types that implement `FromData` automatically
/// implement `FromTransformedData`. Thus, when possible, prefer to implement
/// [`FromData`] instead of `FromTransformedData`.
/// sufficient. All types that implement `FromData` automatically implement
/// `FromTransformedData`. Thus, when possible, prefer to implement [`FromData`]
/// instead of `FromTransformedData`.
///
/// [request guard]: crate::request::FromRequest
///
@ -154,22 +155,23 @@ pub type FromDataFuture<'fut, T, E> = BoxFuture<'fut, Outcome<T, E>>;
/// # Transforming
///
/// Data guards can optionally _transform_ incoming data before processing it
/// via an implementation of the [`FromTransformedData::transform()`] method. This is
/// useful when a data guard requires or could benefit from a reference to body
/// data as opposed to an owned version. If a data guard has no need to operate
/// on a reference to body data, [`FromData`] should be implemented
/// via an implementation of the [`FromTransformedData::transform()`] method.
/// This is useful when a data guard requires or could benefit from a reference
/// to body data as opposed to an owned version. If a data guard has no need to
/// operate on a reference to body data, [`FromData`] should be implemented
/// instead; it is simpler to implement and less error prone. All types that
/// implement `FromData` automatically implement `FromTransformedData`.
///
/// When exercising a data guard, Rocket first calls the guard's
/// [`FromTransformedData::transform()`] method and awaits on the returned future, then
/// calls the guard's [`FromTransformedData::from_data()`] method and awaits on that
/// returned future. Rocket stores data returned by [`FromTransformedData::transform()`] on
/// the stack. If `transform` returns a [`Transform::Owned`], Rocket moves the
/// data back to the data guard in the subsequent `from_data` call as a
/// `Transform::Owned`. If instead `transform` returns a [`Transform::Borrowed`]
/// variant, Rocket calls `borrow()` on the owned value, producing a borrow of
/// the associated [`FromTransformedData::Borrowed`] type and passing it as a
/// [`FromTransformedData::transform()`] method and awaits on the returned
/// future, then calls the guard's [`FromTransformedData::from_data()`] method
/// and awaits on that returned future. Rocket stores data returned by
/// [`FromTransformedData::transform()`] on the stack. If `transform` returns a
/// [`Transform::Owned`], Rocket moves the data back to the data guard in the
/// subsequent `from_data` call as a `Transform::Owned`. If instead `transform`
/// returns a [`Transform::Borrowed`] variant, Rocket calls `borrow()` on the
/// owned value, producing a borrow of the associated
/// [`FromTransformedData::Borrowed`] type and passing it as a
/// `Transform::Borrowed`.
///
/// ## Example
@ -197,7 +199,7 @@ pub type FromDataFuture<'fut, T, E> = BoxFuture<'fut, Outcome<T, E>>;
///
/// use tokio::io::AsyncReadExt;
///
/// use rocket::{Request, Data, Outcome::*};
/// use rocket::{Request, Data};
/// use rocket::data::{FromTransformedData, Outcome, Transform, Transformed, TransformFuture, FromDataFuture};
/// use rocket::http::Status;
///
@ -218,8 +220,8 @@ pub type FromDataFuture<'fut, T, E> = BoxFuture<'fut, Outcome<T, E>>;
/// let mut stream = data.open().take(NAME_LIMIT);
/// let mut string = String::with_capacity((NAME_LIMIT / 2) as usize);
/// let outcome = match stream.read_to_string(&mut string).await {
/// Ok(_) => Success(string),
/// Err(e) => Failure((Status::InternalServerError, NameError::Io(e)))
/// Ok(_) => Outcome::Success(string),
/// Err(e) => Outcome::Failure((Status::InternalServerError, NameError::Io(e)))
/// };
///
/// // Returning `Borrowed` here means we get `Borrowed` in `from_data`.
@ -237,11 +239,11 @@ pub type FromDataFuture<'fut, T, E> = BoxFuture<'fut, Outcome<T, E>>;
/// // Perform a crude, inefficient parse.
/// let splits: Vec<&str> = string.split(" ").collect();
/// if splits.len() != 2 || splits.iter().any(|s| s.is_empty()) {
/// return Failure((Status::UnprocessableEntity, NameError::Parse));
/// return Outcome::Failure((Status::UnprocessableEntity, NameError::Parse));
/// }
///
/// // Return successfully.
/// Success(Name { first: splits[0], last: splits[1] })
/// Outcome::Success(Name { first: splits[0], last: splits[1] })
/// })
/// }
/// }
@ -418,17 +420,18 @@ impl<'a> FromTransformedData<'a> for Data {
}
}
/// A simple, less complex variant of [`FromTransformedData`].
/// A varaint of [`FromTransformedData`] for data guards that don't require
/// transformations.
///
/// When transformation of incoming data isn't required, data guards should
/// implement this trait instead of [`FromTransformedData`]. Any type that implements
/// `FromData` automatically implements `FromTransformedData`. For a description of
/// data guards, see the [`FromTransformedData`] documentation.
/// implement this trait instead of [`FromTransformedData`]. Any type that
/// implements `FromData` automatically implements `FromTransformedData`. For a
/// description of data guards, see the [`FromTransformedData`] documentation.
///
/// ## Async Trait
///
/// [`FromData`] is an _async_ trait. Implementations of `FromData` must
/// be decorated with an attribute of `#[rocket::async_trait]`:
/// [`FromData`] is an _async_ trait. Implementations of `FromData` must be
/// decorated with an attribute of `#[rocket::async_trait]`:
///
/// ```rust
/// use rocket::request::Request;
@ -482,8 +485,8 @@ impl<'a> FromTransformedData<'a> for Data {
/// #
/// use std::io::Read;
///
/// use rocket::{Request, Data, Outcome, Outcome::*};
/// use rocket::data::{self, FromData, FromDataFuture};
/// use rocket::{Request, Data};
/// use rocket::data::{self, Outcome, FromData, FromDataFuture};
/// use rocket::http::{Status, ContentType};
/// use rocket::tokio::io::AsyncReadExt;
///
@ -494,34 +497,34 @@ impl<'a> FromTransformedData<'a> for Data {
/// impl FromData for Person {
/// type Error = String;
///
/// async fn from_data(req: &Request<'_>, data: Data) -> data::Outcome<Self, String> {
/// async fn from_data(req: &Request<'_>, data: Data) -> Outcome<Self, String> {
/// // Ensure the content type is correct before opening the data.
/// let person_ct = ContentType::new("application", "x-person");
/// if req.content_type() != Some(&person_ct) {
/// return Forward(data);
/// return Outcome::Forward(data);
/// }
///
/// // Read the data into a String.
/// let mut string = String::new();
/// let mut reader = data.open().take(LIMIT);
/// if let Err(e) = reader.read_to_string(&mut string).await {
/// return Failure((Status::InternalServerError, format!("{:?}", e)));
/// return Outcome::Failure((Status::InternalServerError, format!("{:?}", e)));
/// }
///
/// // Split the string into two pieces at ':'.
/// let (name, age) = match string.find(':') {
/// Some(i) => (string[..i].to_string(), &string[(i + 1)..]),
/// None => return Failure((Status::UnprocessableEntity, "':'".into()))
/// None => return Outcome::Failure((Status::UnprocessableEntity, "':'".into()))
/// };
///
/// // Parse the age.
/// let age: u16 = match age.parse() {
/// Ok(age) => age,
/// Err(_) => return Failure((Status::UnprocessableEntity, "Age".into()))
/// Err(_) => return Outcome::Failure((Status::UnprocessableEntity, "Age".into()))
/// };
///
/// // Return successfully.
/// Success(Person { name, age })
/// Outcome::Success(Person { name, age })
/// }
/// }
/// # #[post("/person", data = "<person>")]

View File

@ -307,7 +307,6 @@ pub use self::info_kind::{Info, Kind};
/// # use std::future::Future;
/// # use std::pin::Pin;
/// # use std::time::{Duration, SystemTime};
/// # use rocket::Outcome;
/// # use rocket::{Request, Data, Response};
/// # use rocket::fairing::{Fairing, Info, Kind};
/// # use rocket::http::Status;
@ -359,8 +358,8 @@ pub use self::info_kind::{Info, Kind};
///
/// async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, ()> {
/// match *request.local_cache(|| TimerStart(None)) {
/// TimerStart(Some(time)) => Outcome::Success(StartTime(time)),
/// TimerStart(None) => Outcome::Failure((Status::InternalServerError, ())),
/// TimerStart(Some(time)) => request::Outcome::Success(StartTime(time)),
/// TimerStart(None) => request::Outcome::Failure((Status::InternalServerError, ())),
/// }
/// }
/// }

View File

@ -114,7 +114,7 @@ pub type HandlerFuture<'r> = BoxFuture<'r, Outcome<'r>>;
/// }
/// }
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// rocket::ignite()
/// .mount("/", routes![custom_handler])

View File

@ -61,7 +61,7 @@
//! "Hello, world!"
//! }
//!
//! #[rocket::launch]
//! #[launch]
//! fn rocket() -> rocket::Rocket {
//! rocket::ignite().mount("/", routes![hello])
//! }
@ -104,7 +104,6 @@ pub mod data;
pub mod handler;
pub mod fairing;
pub mod error;
pub mod shutdown;
// Reexport of HTTP everything.
pub mod http {
@ -117,6 +116,7 @@ pub mod http {
pub use rocket_http::*;
}
mod shutdown;
mod router;
mod rocket;
mod codegen;
@ -124,15 +124,14 @@ mod catcher;
mod ext;
#[doc(inline)] pub use crate::response::Response;
#[doc(inline)] pub use crate::handler::{Handler, ErrorHandler};
#[doc(hidden)] pub use crate::codegen::{StaticRouteInfo, StaticCatchInfo};
#[doc(inline)] pub use crate::outcome::Outcome;
#[doc(inline)] pub use crate::data::Data;
#[doc(inline)] pub use crate::config::Config;
pub use crate::router::Route;
pub use crate::request::{Request, State};
pub use crate::catcher::Catcher;
pub use crate::rocket::{Cargo, Rocket};
pub use crate::shutdown::Shutdown;
/// Alias to [`Rocket::ignite()`] Creates a new instance of `Rocket`.
pub fn ignite() -> Rocket {

View File

@ -9,9 +9,9 @@
//! processing next.
//!
//! The `Outcome` type is the return type of many of the core Rocket traits,
//! including [`FromRequest`](crate::request::FromRequest), [`FromTransformedData`]
//! [`Responder`]. It is also the return type of request handlers via the
//! [`Response`](crate::response::Response) type.
//! including [`FromRequest`](crate::request::FromRequest),
//! [`FromTransformedData`] [`Responder`]. It is also the return type of request
//! handlers via the [`Response`](crate::response::Response) type.
//!
//! [`FromTransformedData`]: crate::data::FromTransformedData
//! [`Responder`]: crate::response::Responder
@ -21,17 +21,20 @@
//! 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
//! [`FromTransformedData`] trait will be matched against the type expected by the user.
//! For example, consider the following handler:
//! [`FromTransformedData`] trait will be matched against the type expected by
//! the user. For example, consider the following handler:
//!
//! ```rust,ignore
//! ```rust
//! # use rocket::post;
//! # type S = rocket::data::Data;
//! #[post("/", data = "<my_val>")]
//! fn hello(my_val: S) -> ... { }
//! fn hello(my_val: S) { /* ... */ }
//! ```
//!
//! The [`FromTransformedData`] 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`.
//! The [`FromTransformedData`] 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`.
//!
//! # Failure
//!
@ -45,16 +48,19 @@
//! or `Option<S>` in request handlers. For example, if a user's handler looks
//! like:
//!
//! ```rust,ignore
//! ```rust
//! # use rocket::post;
//! # type S = rocket::data::Data;
//! # type E = std::convert::Infallible;
//! #[post("/", data = "<my_val>")]
//! fn hello(my_val: Result<S, E>) -> ... { }
//! fn hello(my_val: Result<S, E>) { /* ... */ }
//! ```
//!
//! The [`FromTransformedData`] implementation for the type `S` returns an `Outcome` with a
//! `Success(S)` and `Failure(E)`. If `from_data` returns a `Failure`, the
//! `Failure` 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.
//! The [`FromTransformedData`] implementation for the type `S` returns an
//! `Outcome` with a `Success(S)` and `Failure(E)`. If `from_data` returns a
//! `Failure`, the `Failure` 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.
//!
//! # Forward
//!
@ -66,19 +72,21 @@
//! next available request handler. For example, consider the following request
//! handler:
//!
//! ```rust,ignore
//! ```rust
//! # use rocket::post;
//! # type S = rocket::data::Data;
//! #[post("/", data = "<my_val>")]
//! fn hello(my_val: S) -> ... { }
//! fn hello(my_val: S) { /* ... */ }
//! ```
//!
//! The [`FromTransformedData`] implementation for the type `S` returns an `Outcome` with a
//! `Success(S)`, `Failure(E)`, and `Forward(F)`. If the `Outcome` is a
//! `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
//! 404 catcher. Similar to `Failure`s, users can catch `Forward`s by requesting
//! a type of `Option<S>`. If an `Outcome` is a `Forward`, the `Option` will be
//! `None`.
//! The [`FromTransformedData`] implementation for the type `S` returns an
//! `Outcome` with a `Success(S)`, `Failure(E)`, and `Forward(F)`. If the
//! `Outcome` is a `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 404 catcher. Similar to `Failure`s, users can catch
//! `Forward`s by requesting a type of `Option<S>`. If an `Outcome` is a
//! `Forward`, the `Option` will be `None`.
use std::fmt;
@ -618,6 +626,8 @@ impl<'a, S: Send + 'a, E: Send + 'a, F: Send + 'a> Outcome<S, E, F> {
/// Because of the early return, `try_outcome!` can only be used in methods that
/// return [`Outcome`].
///
/// [`Outcome`]: crate::outcome::Outcome
///
/// ## Example
///
/// ```rust,no_run

View File

@ -189,9 +189,8 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// ```rust
/// # #[macro_use] extern crate rocket;
/// #
/// use rocket::Outcome;
/// use rocket::http::Status;
/// use rocket::request::{self, Request, FromRequest};
/// use rocket::request::{self, Outcome, Request, FromRequest};
///
/// struct ApiKey(String);
///
@ -211,7 +210,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// impl<'a, 'r> FromRequest<'a, 'r> for ApiKey {
/// type Error = ApiKeyError;
///
/// async fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
/// async fn from_request(req: &'a Request<'r>) -> Outcome<Self, Self::Error> {
/// let keys: Vec<_> = req.headers().get("x-api-key").collect();
/// match keys.len() {
/// 0 => Outcome::Failure((Status::BadRequest, ApiKeyError::Missing)),
@ -244,8 +243,8 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// ```rust
/// # #[macro_use] extern crate rocket;
/// # #[cfg(feature = "private-cookies")] mod inner {
/// # use rocket::outcome::{IntoOutcome, Outcome};
/// # use rocket::request::{self, FromRequest, Request};
/// # use rocket::outcome::IntoOutcome;
/// # use rocket::request::{self, Outcome, FromRequest, Request};
/// # struct User { id: String, is_admin: bool }
/// # struct Database;
/// # impl Database {
@ -256,7 +255,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// # #[rocket::async_trait]
/// # impl<'a, 'r> FromRequest<'a, 'r> for Database {
/// # type Error = ();
/// # async fn from_request(request: &'a Request<'r>) -> request::Outcome<Database, ()> {
/// # async fn from_request(request: &'a Request<'r>) -> Outcome<Database, ()> {
/// # Outcome::Success(Database)
/// # }
/// # }
@ -267,7 +266,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// impl<'a, 'r> FromRequest<'a, 'r> for User {
/// type Error = ();
///
/// async fn from_request(request: &'a Request<'r>) -> request::Outcome<User, ()> {
/// async fn from_request(request: &'a Request<'r>) -> Outcome<User, ()> {
/// let db = try_outcome!(request.guard::<Database>().await);
/// request.cookies()
/// .get_private("user_id")
@ -281,7 +280,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// impl<'a, 'r> FromRequest<'a, 'r> for Admin {
/// type Error = ();
///
/// async fn from_request(request: &'a Request<'r>) -> request::Outcome<Admin, ()> {
/// async fn from_request(request: &'a Request<'r>) -> Outcome<Admin, ()> {
/// // This will unconditionally query the database!
/// let user = try_outcome!(request.guard::<User>().await);
/// if user.is_admin {
@ -308,8 +307,8 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// ```rust
/// # #[macro_use] extern crate rocket;
/// # #[cfg(feature = "private-cookies")] mod inner {
/// # use rocket::outcome::{IntoOutcome, Outcome};
/// # use rocket::request::{self, FromRequest, Request};
/// # use rocket::outcome::IntoOutcome;
/// # use rocket::request::{self, Outcome, FromRequest, Request};
/// # struct User { id: String, is_admin: bool }
/// # struct Database;
/// # impl Database {
@ -320,7 +319,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// # #[rocket::async_trait]
/// # impl<'a, 'r> FromRequest<'a, 'r> for Database {
/// # type Error = ();
/// # async fn from_request(request: &'a Request<'r>) -> request::Outcome<Database, ()> {
/// # async fn from_request(request: &'a Request<'r>) -> Outcome<Database, ()> {
/// # Outcome::Success(Database)
/// # }
/// # }
@ -331,7 +330,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// impl<'a, 'r> FromRequest<'a, 'r> for &'a User {
/// type Error = std::convert::Infallible;
///
/// async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
/// async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
/// // This closure will execute at most once per request, regardless of
/// // the number of times the `User` guard is executed.
/// let user_result = request.local_cache_async(async {
@ -350,7 +349,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// impl<'a, 'r> FromRequest<'a, 'r> for Admin<'a> {
/// type Error = std::convert::Infallible;
///
/// async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
/// async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
/// let user = try_outcome!(request.guard::<&User>().await);
/// if user.is_admin {
/// Outcome::Success(Admin { user })

View File

@ -10,10 +10,11 @@ use crate::http::Status;
/// This type can be used as a request guard to retrieve the state Rocket is
/// managing for some type `T`. This allows for the sharing of state across any
/// number of handlers. A value for the given type must previously have been
/// registered to be managed by Rocket via
/// [`Rocket::manage()`]. The type being managed must be
/// thread safe and sendable across thread boundaries. In other words, it must
/// implement [`Send`] + [`Sync`] + `'static`.
/// registered to be managed by Rocket via [`Rocket::manage()`]. The type being
/// managed must be thread safe and sendable across thread boundaries. In other
/// words, it must implement [`Send`] + [`Sync`] + `'static`.
///
/// [`Rocket::manage()`]: crate::Rocket::manage()
///
/// # Example
///
@ -41,7 +42,7 @@ use crate::http::Status;
/// state.inner().user_val.as_str()
/// }
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// rocket::ignite()
/// .mount("/", routes![index, raw_config_value])

View File

@ -25,7 +25,7 @@ use crate::error::{LaunchError, LaunchErrorKind};
use crate::fairing::{Fairing, Fairings};
use crate::logger::PaintExt;
use crate::ext::AsyncReadExt;
use crate::shutdown::{ShutdownHandle, ShutdownHandleManaged};
use crate::shutdown::{Shutdown, ShutdownManaged};
use crate::http::{Method, Status, Header};
use crate::http::private::{Listener, Connection, Incoming};
@ -42,7 +42,7 @@ pub struct Rocket {
catchers: HashMap<u16, Catcher>,
pub(crate) managed_state: Container,
fairings: Fairings,
shutdown_handle: ShutdownHandle,
shutdown_handle: Shutdown,
shutdown_receiver: Option<mpsc::Receiver<()>>,
}
@ -122,7 +122,7 @@ impl Rocket {
catchers: HashMap::new(),
managed_state: Container::new(),
fairings: Fairings::new(),
shutdown_handle: ShutdownHandle(mpsc::channel(1).0),
shutdown_handle: Shutdown(mpsc::channel(1).0),
shutdown_receiver: None,
}
}
@ -652,8 +652,8 @@ impl Rocket {
let managed_state = Container::new();
let (shutdown_sender, shutdown_receiver) = mpsc::channel(1);
let shutdown_handle = ShutdownHandle(shutdown_sender);
managed_state.set(ShutdownHandleManaged(shutdown_handle.clone()));
let shutdown_handle = Shutdown(shutdown_sender);
managed_state.set(ShutdownManaged(shutdown_handle.clone()));
Rocket {
config, managed_state, shutdown_handle,
@ -693,7 +693,7 @@ impl Rocket {
/// "Hello!"
/// }
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// rocket::ignite().mount("/hello", routes![hi])
/// }
@ -752,7 +752,7 @@ impl Rocket {
/// format!("I couldn't find '{}'. Try something else?", req.uri())
/// }
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// rocket::ignite().register(catchers![internal_error, not_found])
/// }
@ -790,7 +790,7 @@ impl Rocket {
/// format!("The stateful value is: {}", state.0)
/// }
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// rocket::ignite()
/// .mount("/", routes![index])
@ -821,7 +821,7 @@ impl Rocket {
/// use rocket::Rocket;
/// use rocket::fairing::AdHoc;
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// rocket::ignite()
/// .attach(AdHoc::on_launch("Launch Message", |_| {
@ -896,9 +896,8 @@ impl Rocket {
self.inspect().await.config()
}
/// Returns a [`ShutdownHandle`], which can be used to gracefully terminate
/// the instance of Rocket. In routes, you should use the [`ShutdownHandle`]
/// request guard.
/// Returns a handle which can be used to gracefully terminate this instance
/// of Rocket. In routes, use the [`Shutdown`] request guard.
///
/// # Example
///
@ -907,7 +906,7 @@ impl Rocket {
/// #
/// # rocket::async_test(async {
/// let mut rocket = rocket::ignite();
/// let handle = rocket.inspect().await.shutdown_handle();
/// let handle = rocket.inspect().await.shutdown();
///
/// # if false {
/// thread::spawn(move || {
@ -922,7 +921,7 @@ impl Rocket {
/// # });
/// ```
#[inline(always)]
pub fn shutdown_handle(&self) -> ShutdownHandle {
pub fn shutdown(&self) -> Shutdown {
self.shutdown_handle.clone()
}
@ -943,16 +942,17 @@ impl Rocket {
/// Returns a `Future` that drives the server, listening for and dispatching
/// requests to mounted routes and catchers. The `Future` completes when the
/// server is shut down via a [`ShutdownHandle`], encounters a fatal error,
/// or if the the `ctrlc` configuration option is set, when `Ctrl+C` is
/// pressed.
/// server is shut down via [`Shutdown`], encounters a fatal error, or if
/// the the `ctrlc` configuration option is set, when `Ctrl+C` is pressed.
///
/// # Error
///
/// If there is a problem starting the application, an [`Error`] is
/// returned. Note that a value of type `Error` panics if dropped
/// without first being inspected. See the [`Error`] documentation for
/// more information.
/// returned. Note that a value of type `Error` panics if dropped without
/// first being inspected. See the [`Error`] documentation for more
/// information.
///
/// [`Error`]: crate::error::Error
///
/// # Example
///
@ -1126,7 +1126,7 @@ impl Cargo {
/// use rocket::Rocket;
/// use rocket::fairing::AdHoc;
///
/// #[rocket::launch]
/// #[launch]
/// fn rocket() -> rocket::Rocket {
/// rocket::ignite()
/// .attach(AdHoc::on_launch("Config Printer", |cargo| {

View File

@ -17,7 +17,7 @@ type Selector = Method;
pub(crate) fn dummy_handler<'r>(
r: &'r Request<'_>, _: crate::Data
) -> BoxFuture<'r, crate::handler::Outcome<'r>> {
crate::Outcome::from(r, ()).pin()
crate::outcome::Outcome::from(r, ()).pin()
}
#[derive(Default)]

View File

@ -1,13 +1,12 @@
use crate::request::{FromRequest, Outcome, Request};
use tokio::sync::mpsc;
/// A `ShutdownHandle` can be used to instruct a Rocket server to gracefully
/// shut down. Once a server shutdown has been requested manually by calling
/// [`ShutdownHandle::shutdown()`] or automatically by `Ctrl-C` being pressed
/// (if enabled), Rocket will finish handling any pending requests and return to
/// the caller of [`Rocket::serve()`] or [`Rocket::launch()`].
/// A request guard to gracefully shutdown a Rocket server.
///
/// A server shutdown is manually requested by calling [`Shutdown::shutdown()`]
/// or, if enabled, by pressing `Ctrl-C`. Rocket will finish handling any
/// pending requests and return `Ok()` to the caller of [`Rocket::launch()`].
///
/// [`Rocket::serve()`]: crate::Rocket::serve()
/// [`Rocket::launch()`]: crate::Rocket::launch()
///
/// # Example
@ -15,10 +14,10 @@ use tokio::sync::mpsc;
/// ```rust,no_run
/// # #[macro_use] extern crate rocket;
/// #
/// use rocket::shutdown::ShutdownHandle;
/// use rocket::Shutdown;
///
/// #[get("/shutdown")]
/// fn shutdown(handle: ShutdownHandle) -> &'static str {
/// fn shutdown(handle: Shutdown) -> &'static str {
/// handle.shutdown();
/// "Shutting down..."
/// }
@ -35,9 +34,9 @@ use tokio::sync::mpsc;
/// }
/// ```
#[derive(Debug, Clone)]
pub struct ShutdownHandle(pub(crate) mpsc::Sender<()>);
pub struct Shutdown(pub(crate) mpsc::Sender<()>);
impl ShutdownHandle {
impl Shutdown {
/// Notify Rocket to shut down gracefully. This function returns
/// immediately; pending requests will continue to run until completion
/// before the actual shutdown occurs.
@ -51,14 +50,14 @@ impl ShutdownHandle {
}
#[crate::async_trait]
impl<'a, 'r> FromRequest<'a, 'r> for ShutdownHandle {
impl<'a, 'r> FromRequest<'a, 'r> for Shutdown {
type Error = std::convert::Infallible;
#[inline]
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
Outcome::Success(request.state.managed.get::<ShutdownHandleManaged>().0.clone())
Outcome::Success(request.state.managed.get::<ShutdownManaged>().0.clone())
}
}
// Use this type in managed state to avoid placing `ShutdownHandle` in it.
pub(crate) struct ShutdownHandleManaged(pub ShutdownHandle);
// Use this type in managed state to avoid placing `Shutdown` in it.
pub(crate) struct ShutdownManaged(pub Shutdown);

View File

@ -61,7 +61,7 @@ fn not_found(request: &Request<'_>) -> Html<String> {
Html(html)
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/hello", routes![get_hello, post_hello])

View File

@ -32,7 +32,7 @@ fn index(cookies: Cookies<'_>) -> Template {
Template::render("index", &context)
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![submit, index]).attach(Template::fairing())
}

View File

@ -61,7 +61,7 @@ fn token(token: State<'_, Token>) -> String {
format!("{}", token.0)
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/", routes![hello, token])

View File

@ -35,7 +35,7 @@ fn sink(sink: Result<Form<FormInput<'_>>, FormError<'_>>) -> String {
}
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![sink]).mount("/", StaticFiles::from("static/"))
}

View File

@ -75,7 +75,7 @@ fn user_page(username: &RawStr) -> String {
format!("This is {}'s page.", username)
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/", routes![user_page, login])

View File

@ -65,7 +65,7 @@ fn wow_helper(
Ok(())
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/", routes![index, hello, about])

View File

@ -12,7 +12,7 @@ fn hi(name: String) -> String {
name
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![hello, hi])
}

View File

@ -68,7 +68,7 @@ fn not_found() -> JsonValue {
})
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/message", routes![new, update, get])

View File

@ -17,7 +17,7 @@ fn pop(queue: State<'_, LogChannel>) -> Option<String> {
queue.0.pop().ok()
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/", routes![push, pop])

View File

@ -1,14 +1,12 @@
extern crate rocket;
#[cfg(test)]
mod tests;
use std::env;
use rocket::{Request, Handler, Route, Data, Catcher, try_outcome};
use rocket::{Request, Route, Data, Catcher, try_outcome};
use rocket::http::{Status, RawStr};
use rocket::response::{Responder, status::Custom};
use rocket::handler::{Outcome, HandlerFuture, CatcherFuture};
use rocket::handler::{Handler, Outcome, HandlerFuture, CatcherFuture};
use rocket::outcome::IntoOutcome;
use rocket::http::Method::*;
use rocket::tokio::fs::File;
@ -82,8 +80,6 @@ impl CustomHandler {
}
}
// FIXME: Will this work?
#[rocket::async_trait]
impl Handler for CustomHandler {
async fn handle<'r, 's: 'r>(&'s self, req: &'r Request<'_>, data: Data) -> Outcome<'r> {

View File

@ -22,7 +22,7 @@ fn create(data: MsgPack<Message<'_>>) -> String {
data.contents.to_string()
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/message", routes![get, create])
}

View File

@ -24,7 +24,7 @@ fn login() -> &'static str {
"Hi! That user doesn't exist. Maybe you need to log in?"
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![root, user, login])
}

View File

@ -48,7 +48,7 @@ fn index() -> &'static str {
"
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![index, upload, retrieve])
}

View File

@ -30,7 +30,7 @@ fn hello_20(person: LenientForm<Person>) -> String {
format!("20 years old? Hi, {}!", person.name)
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![hello, hello_20])
}

View File

@ -14,7 +14,7 @@ fn hi(name: String, age: &RawStr) -> String {
format!("Hi {}! Your age ({}) is kind of funky.", name, age)
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![hi, hello])
}

View File

@ -30,7 +30,7 @@ fn hello(db_conn: State<'_, DbConn>) -> Result<String, Debug<Error>> {
.map_err(Debug)
}
#[rocket::launch]
#[launch]
fn rocket() -> Rocket {
// Open a new in-memory SQLite database.
let conn = Connection::open_in_memory().expect("in memory db");

View File

@ -15,7 +15,7 @@ fn index() -> &'static str {
"Upload your text files by POSTing them to /upload."
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![index, upload])
}

View File

@ -14,7 +14,7 @@ fn login() -> &'static str {
"Hi! Please log in before continuing."
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![root, login])
}

View File

@ -20,7 +20,7 @@ fn header_count(header_count: HeaderCount) -> String {
format!("Your request contained {} headers!", header_count.0)
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![header_count])
}

View File

@ -76,7 +76,7 @@ async fn r_async(_g1: Guard3, _g2: Guard4) {
// This exists only to run the request guards.
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
.manage(Atomics::default())

View File

@ -78,7 +78,7 @@ fn index() -> Redirect {
Redirect::to(uri!(login_page))
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
.attach(Template::fairing())

View File

@ -22,7 +22,7 @@ fn count(hit_count: State<'_, HitCount>) -> String {
hit_count.0.load(Ordering::Relaxed).to_string()
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/", routes![index, count])

View File

@ -20,7 +20,7 @@ async fn file() -> Option<Stream<File>> {
File::open(FILENAME).await.map(Stream::from).ok()
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![root, file])
}

View File

@ -32,7 +32,7 @@ fn not_found(req: &Request<'_>) -> Template {
Template::render("error/404", &map)
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/", routes![index, get])

View File

@ -7,7 +7,7 @@ fn hello() -> &'static str {
"Hello, world!"
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![hello])
}

View File

@ -101,7 +101,7 @@ async fn run_db_migrations(mut rocket: Rocket) -> Result<Rocket, Rocket> {
}
}
#[rocket::launch]
#[launch]
fn rocket() -> Rocket {
rocket::ignite()
.attach(DbConn::fairing())

View File

@ -33,7 +33,7 @@ fn people(id: Uuid) -> Result<String, String> {
.ok_or_else(|| format!("Person not found for UUID: {}", id))?)
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![people])
}

View File

@ -52,7 +52,7 @@ And finally, create a skeleton Rocket application to work off of in
```rust
#[macro_use] extern crate rocket;
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
}
@ -109,7 +109,7 @@ to them. To mount the `index` route, modify the main function so that it reads:
# #[macro_use] extern crate rocket;
# #[get("/")] fn index() { }
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![index])
}
@ -283,7 +283,7 @@ Ensure that the route is mounted at the root path:
# #[get("/")] fn index() {}
# #[post("/")] fn upload() {}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![index, upload])
}
@ -345,7 +345,7 @@ Make sure that the route is mounted at the root path:
# #[post("/")] fn upload() {}
# #[get("/<id>")] fn retrieve(id: String) {}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![index, upload, retrieve])
}

View File

@ -167,7 +167,7 @@ requests via the `launch` method. The method starts up the server and waits for
incoming requests. When a request arrives, Rocket finds the matching route and
dispatches the request to the route's handler.
We typically use `#[rocket::launch]`, which generates a `main` function.
We typically use `#[launch]`, which generates a `main` function.
Our complete _Hello, world!_ application thus looks like:
```rust
@ -178,7 +178,7 @@ fn world() -> &'static str {
"Hello, world!"
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/hello", routes![world])
}
@ -242,7 +242,7 @@ You can find async-ready libraries on [crates.io](https://crates.io) with the
! note
Rocket 0.5 uses the tokio (0.2) runtime. The runtime is started for you if you
use `#[rocket::launch]` or `#[rocket::main]`, but you can still `launch()` a
use `#[launch]` or `#[rocket::main]`, but you can still `launch()` a
rocket instance on a custom-built `Runtime`.
### Cooperative Multitasking

View File

@ -221,7 +221,7 @@ fn user_int(id: isize) { /* ... */ }
#[get("/user/<id>", rank = 3)]
fn user_str(id: &RawStr) { /* ... */ }
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![user, user_int, user_str])
}

View File

@ -294,7 +294,7 @@ use rocket_contrib::databases::diesel;
#[database("sqlite_logs")]
struct LogsDbConn(diesel::SqliteConnection);
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().attach(LogsDbConn::fairing())
}

View File

@ -49,7 +49,8 @@ example, the following snippet attached two fairings, `req_fairing` and
`res_fairing`, to a new Rocket instance:
```rust
#[rocket::launch]
# use rocket::launch;
#[launch]
fn rocket() -> rocket::Rocket {
# let req_fairing = rocket::fairing::AdHoc::on_request("example", |_, _| Box::pin(async {}));
# let res_fairing = rocket::fairing::AdHoc::on_response("example", |_, _| Box::pin(async {}));

View File

@ -123,7 +123,7 @@ fn hello() -> &'static str {
"Hello, world!"
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![hello])
}

View File

@ -204,7 +204,7 @@ async fn assets(asset: PathBuf, assets_dir: State<'_, AssetsDir>) -> Option<Name
NamedFile::open(Path::new(&assets_dir.0).join(asset)).await.ok()
}
#[rocket::launch]
#[launch]
fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/", routes![assets])