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 = (); type Error = ();
async fn from_request(request: &'a #request::Request<'r>) -> #request::Outcome<Self, ()> { 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 guard = request.guard::<::rocket::State<'_, #pool_type>>();
let pool = ::rocket::try_outcome!(guard.await).0.clone(); let pool = ::rocket::try_outcome!(guard.await).0.clone();
#spawn_blocking(move || { #spawn_blocking(move || {
match pool.get() { match pool.get() {
Ok(conn) => Outcome::Success(#guard_type(conn)), Ok(conn) => #request::Outcome::Success(#guard_type(conn)),
Err(_) => Outcome::Failure((Status::ServiceUnavailable, ())), Err(_) => #request::Outcome::Failure((Status::ServiceUnavailable, ())),
} }
}).await.expect("failed to spawn a blocking task to get a pooled connection") }).await.expect("failed to spawn a blocking task to get a pooled connection")
} }

View File

@ -60,7 +60,7 @@
//! #[database("sqlite_logs")] //! #[database("sqlite_logs")]
//! struct LogsDbConn(diesel::SqliteConnection); //! struct LogsDbConn(diesel::SqliteConnection);
//! //!
//! #[rocket::launch] //! #[launch]
//! fn rocket() -> rocket::Rocket { //! fn rocket() -> rocket::Rocket {
//! rocket::ignite().attach(LogsDbConn::fairing()) //! rocket::ignite().attach(LogsDbConn::fairing())
//! } //! }
@ -138,14 +138,14 @@
//! The example below does just this: //! The example below does just this:
//! //!
//! ```rust //! ```rust
//! extern crate rocket; //! #[macro_use] extern crate rocket;
//! //!
//! # #[cfg(feature = "diesel_sqlite_pool")] //! # #[cfg(feature = "diesel_sqlite_pool")]
//! # mod test { //! # mod test {
//! use std::collections::HashMap; //! use std::collections::HashMap;
//! use rocket::config::{Config, Environment, Value}; //! use rocket::config::{Config, Environment, Value};
//! //!
//! #[rocket::launch] //! #[launch]
//! fn rocket() -> rocket::Rocket { //! fn rocket() -> rocket::Rocket {
//! let mut database_config = HashMap::new(); //! let mut database_config = HashMap::new();
//! let mut databases = HashMap::new(); //! let mut databases = HashMap::new();
@ -246,7 +246,7 @@
//! together, a use of the `#[database]` attribute looks as follows: //! together, a use of the `#[database]` attribute looks as follows:
//! //!
//! ```rust //! ```rust
//! # extern crate rocket; //! # #[macro_use] extern crate rocket;
//! # #[macro_use] extern crate rocket_contrib; //! # #[macro_use] extern crate rocket_contrib;
//! # //! #
//! # #[cfg(feature = "diesel_sqlite_pool")] //! # #[cfg(feature = "diesel_sqlite_pool")]
@ -259,7 +259,7 @@
//! #[database("my_db")] //! #[database("my_db")]
//! struct MyDatabase(diesel::SqliteConnection); //! struct MyDatabase(diesel::SqliteConnection);
//! //!
//! #[rocket::launch] //! #[launch]
//! fn rocket() -> rocket::Rocket { //! fn rocket() -> rocket::Rocket {
//! # let mut db_config = HashMap::new(); //! # let mut db_config = HashMap::new();
//! # let mut databases = 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: /// requests for a directory (the default), you might write the following:
/// ///
/// ```rust,no_run /// ```rust,no_run
/// # extern crate rocket; /// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib; /// # extern crate rocket_contrib;
/// use rocket_contrib::serve::StaticFiles; /// use rocket_contrib::serve::StaticFiles;
/// ///
/// #[rocket::launch] /// #[launch]
/// fn rocket() -> rocket::Rocket { /// fn rocket() -> rocket::Rocket {
/// rocket::ignite().mount("/public", StaticFiles::from("/static")) /// 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: /// the `static` subdirectory of your crate at `/`, you might write:
/// ///
/// ```rust,no_run /// ```rust,no_run
/// # extern crate rocket; /// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib; /// # extern crate rocket_contrib;
/// use rocket_contrib::serve::StaticFiles; /// use rocket_contrib::serve::StaticFiles;
/// ///
/// #[rocket::launch] /// #[launch]
/// fn rocket() -> rocket::Rocket { /// fn rocket() -> rocket::Rocket {
/// rocket::ignite() /// rocket::ignite()
/// .mount("/", StaticFiles::from(concat!(env!("CARGO_MANIFEST_DIR"), "/static"))) /// .mount("/", StaticFiles::from(concat!(env!("CARGO_MANIFEST_DIR"), "/static")))
@ -187,11 +187,11 @@ impl StaticFiles {
/// `/static`. /// `/static`.
/// ///
/// ```rust,no_run /// ```rust,no_run
/// # extern crate rocket; /// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib; /// # extern crate rocket_contrib;
/// use rocket_contrib::serve::StaticFiles; /// use rocket_contrib::serve::StaticFiles;
/// ///
/// #[rocket::launch] /// #[launch]
/// fn rocket() -> rocket::Rocket { /// fn rocket() -> rocket::Rocket {
/// rocket::ignite().mount("/static", StaticFiles::from("/www/public")) /// 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`. /// Exactly as before, but set the rank for generated routes to `30`.
/// ///
/// ```rust,no_run /// ```rust,no_run
/// # extern crate rocket; /// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib; /// # extern crate rocket_contrib;
/// use rocket_contrib::serve::StaticFiles; /// use rocket_contrib::serve::StaticFiles;
/// ///
/// #[rocket::launch] /// #[launch]
/// fn rocket() -> rocket::Rocket { /// fn rocket() -> rocket::Rocket {
/// rocket::ignite().mount("/static", StaticFiles::from("/www/public").rank(30)) /// rocket::ignite().mount("/static", StaticFiles::from("/www/public").rank(30))
/// } /// }
@ -225,11 +225,11 @@ impl StaticFiles {
/// index files and dot files. /// index files and dot files.
/// ///
/// ```rust,no_run /// ```rust,no_run
/// # extern crate rocket; /// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib; /// # extern crate rocket_contrib;
/// use rocket_contrib::serve::{StaticFiles, Options}; /// use rocket_contrib::serve::{StaticFiles, Options};
/// ///
/// #[rocket::launch] /// #[launch]
/// fn rocket() -> rocket::Rocket { /// fn rocket() -> rocket::Rocket {
/// let options = Options::Index | Options::DotFiles; /// let options = Options::Index | Options::DotFiles;
/// rocket::ignite() /// rocket::ignite()

View File

@ -1,4 +1,4 @@
use rocket::{Request, State, Outcome}; use rocket::{Request, State};
use rocket::http::Status; use rocket::http::Status;
use rocket::request::{self, FromRequest}; 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, ()> { async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, ()> {
request.guard::<State<'_, ContextManager>>().await request.guard::<State<'_, ContextManager>>().await
.succeeded() .succeeded()
.and_then(|cm| Some(Outcome::Success(Metadata(cm.inner())))) .and_then(|cm| Some(request::Outcome::Success(Metadata(cm.inner()))))
.unwrap_or_else(|| { .unwrap_or_else(|| {
error_!("Uninitialized template context: missing fairing."); error_!("Uninitialized template context: missing fairing.");
info_!("To use templates, you must attach `Template::fairing()`."); info_!("To use templates, you must attach `Template::fairing()`.");
info_!("See the `Template` documentation for more information."); 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, response => rocket::response,
handler => rocket::handler, handler => rocket::handler,
log => rocket::logger, log => rocket::logger,
Outcome => rocket::Outcome, Outcome => rocket::outcome::Outcome,
FromTransformedData => rocket::data::FromTransformedData, FromTransformedData => rocket::data::FromTransformedData,
Transform => rocket::data::Transform, Transform => rocket::data::Transform,
Query => rocket::request::Query, Query => rocket::request::Query,
FromFormValue => rocket::request::FromFormValue, FromFormValue => rocket::request::FromFormValue,
Request => rocket::Request, Request => rocket::request::Request,
Response => rocket::response::Response, Response => rocket::response::Response,
Data => rocket::Data, Data => rocket::data::Data,
StaticRouteInfo => rocket::StaticRouteInfo, StaticRouteInfo => rocket::StaticRouteInfo,
SmallVec => rocket::http::private::SmallVec, SmallVec => rocket::http::private::SmallVec,
HandlerFuture => rocket::handler::HandlerFuture, HandlerFuture => rocket::handler::HandlerFuture,
@ -322,7 +322,7 @@ macro_rules! route_attribute {
/// [`routes!`]: macro.routes.html /// [`routes!`]: macro.routes.html
/// [`uri!`]: macro.uri.html /// [`uri!`]: macro.uri.html
/// [`Origin`]: ../rocket/http/uri/struct.Origin.html /// [`Origin`]: ../rocket/http/uri/struct.Origin.html
/// [`Outcome`]: ../rocket/enum.Outcome.html /// [`Outcome`]: ../rocket/outcome/enum.Outcome.html
/// [`Response`]: ../rocket/struct.Response.html /// [`Response`]: ../rocket/struct.Response.html
/// [`FromRequest` Outcomes]: ../rocket/request/trait.FromRequest.html#outcomes /// [`FromRequest` Outcomes]: ../rocket/request/trait.FromRequest.html#outcomes
/// [`FromTransformedData` Outcomes]: ../rocket/data/trait.FromTransformedData.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)) 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 /// 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 /// route, a colon, and one argument for each dynamic parameter (parameters in
/// `<>`) in the route's path and query. /// `<>`) in the route's path and query.

View File

@ -1,6 +1,6 @@
#[macro_use] extern crate rocket; #[macro_use] extern crate rocket;
use rocket::{Request, Data, Outcome::*}; use rocket::{Request, Data};
use rocket::local::blocking::Client; use rocket::local::blocking::Client;
use rocket::request::Form; use rocket::request::Form;
use rocket::data::{self, FromData}; use rocket::data::{self, FromData};
@ -24,10 +24,10 @@ impl FromData for Simple {
let mut string = String::new(); let mut string = String::new();
let mut stream = data.open().take(64); let mut stream = data.open().take(64);
if let Err(_) = stream.read_to_string(&mut string).await { 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 std::path::PathBuf;
use rocket::{Request, Outcome::*};
use rocket::http::ext::Normalize; use rocket::http::ext::Normalize;
use rocket::local::blocking::Client; use rocket::local::blocking::Client;
use rocket::data::{self, Data, FromData}; use rocket::data::{self, Data, FromData};
use rocket::request::Form; use rocket::request::{Request, Form};
use rocket::http::{Status, RawStr, ContentType}; use rocket::http::{Status, RawStr, ContentType};
use rocket::tokio::io::AsyncReadExt; use rocket::tokio::io::AsyncReadExt;
@ -32,7 +31,7 @@ impl FromData for Simple {
let mut string = String::new(); let mut string = String::new();
let mut stream = data.open().take(64); let mut stream = data.open().take(64);
stream.read_to_string(&mut string).await.unwrap(); 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) = 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 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 attribute generates a `main` function
note: this function cannot be `main` 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) = 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 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 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) = 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 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 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) = 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 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 attribute generates a `main` function
note: this function cannot be `main` 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) = 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 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 attribute generates a `main` function
note: this function cannot be `main` 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) = 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 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` | ------ this is not `async`
76 | let _ = rocket::ignite().launch().await; 75 | let _ = rocket::ignite().launch().await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
error[E0308]: mismatched types 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` | ^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found struct `rocket::Rocket`
error[E0308]: mismatched types 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` | ^^^^^^^^^^^^^^^^ expected struct `rocket::Rocket`, found struct `std::string::String`
error[E0308]: mismatched types error[E0308]: mismatched types
@ -132,26 +132,25 @@ error[E0308]: mismatched types
| ^ expected `()` because of default return type | ^ expected `()` because of default return type
| _____________________| | _____________________|
| | | |
27 | | 27 | | rocket::ignite()
28 | | rocket::ignite() 28 | | }
29 | | }
| | ^- help: try adding a semicolon: `;` | | ^- help: try adding a semicolon: `;`
| |_____| | |_____|
| expected `()`, found struct `rocket::Rocket` | expected `()`, found struct `rocket::Rocket`
error[E0308]: mismatched types 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 struct `rocket::Rocket`, found struct `std::string::String`
| expected due to this | expected due to this
error[E0277]: `main` has invalid return type `rocket::Rocket` 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` | ^^^^^^^^^^^^^^ `main` can only return types that implement `std::process::Termination`
| |
= help: consider using `()`, or a `Result` = 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 } 28 | fn foo() -> usize { 0 }
| ^^^^^ the trait `rocket::response::Responder<'_, '_>` is not implemented for `usize` | ^^^^^ 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 error: attribute cannot be applied to `main` function
--- note: this attribute generates a `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) = 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` 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 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) = 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 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 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) = 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 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 error: attribute cannot be applied to `main` function
--- note: this attribute generates a `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) = 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` 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 error: attribute cannot be applied to `main` function
--- note: this attribute generates a `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) = 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` 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 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` | ------ this is not `async`
76 | let _ = rocket::ignite().launch().await; 75 | let _ = rocket::ignite().launch().await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
error[E0308]: mismatched types 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` | ^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found struct `rocket::rocket::Rocket`
error[E0308]: mismatched types 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` | ^^^^^^^^^^^^^^^^ expected struct `rocket::rocket::Rocket`, found struct `std::string::String`
error[E0308]: mismatched types error[E0308]: mismatched types
@ -126,26 +126,25 @@ error[E0308]: mismatched types
| ^ expected `()` because of default return type | ^ expected `()` because of default return type
| _____________________| | _____________________|
| | | |
27 | | 27 | | rocket::ignite()
28 | | rocket::ignite() 28 | | }
29 | | }
| | ^- help: try adding a semicolon: `;` | | ^- help: try adding a semicolon: `;`
| |_____| | |_____|
| expected `()`, found struct `rocket::rocket::Rocket` | expected `()`, found struct `rocket::rocket::Rocket`
error[E0308]: mismatched types 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 struct `rocket::rocket::Rocket`, found struct `std::string::String`
| expected due to this | expected due to this
error[E0277]: `main` has invalid return type `rocket::rocket::Rocket` 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` | ^^^^^^^^^^^^^^ `main` can only return types that implement `std::process::Termination`
| |
= help: consider using `()`, or a `Result` = 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 } 28 | fn foo() -> usize { 0 }
| ^^^^^ the trait `rocket::response::Responder<'_, '_>` is not implemented for `usize` | ^^^^^ 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 { mod main_f {
#[rocket::main] #[rocket::main]
async fn main() { async fn main() {
rocket::ignite() rocket::ignite()
} }
} }
// rocket::launch // launch
mod launch_a { mod launch_a {
#[rocket::launch] #[rocket::launch]

View File

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

View File

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

View File

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

View File

@ -9,9 +9,9 @@
//! processing next. //! processing next.
//! //!
//! The `Outcome` type is the return type of many of the core Rocket traits, //! The `Outcome` type is the return type of many of the core Rocket traits,
//! including [`FromRequest`](crate::request::FromRequest), [`FromTransformedData`] //! including [`FromRequest`](crate::request::FromRequest),
//! [`Responder`]. It is also the return type of request handlers via the //! [`FromTransformedData`] [`Responder`]. It is also the return type of request
//! [`Response`](crate::response::Response) type. //! handlers via the [`Response`](crate::response::Response) type.
//! //!
//! [`FromTransformedData`]: crate::data::FromTransformedData //! [`FromTransformedData`]: crate::data::FromTransformedData
//! [`Responder`]: crate::response::Responder //! [`Responder`]: crate::response::Responder
@ -21,17 +21,20 @@
//! A successful `Outcome<S, E, F>`, `Success(S)`, is returned from functions //! A successful `Outcome<S, E, F>`, `Success(S)`, is returned from functions
//! that complete successfully. The meaning of a `Success` outcome depends on //! that complete successfully. The meaning of a `Success` outcome depends on
//! the context. For instance, the `Outcome` of the `from_data` method of the //! 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. //! [`FromTransformedData`] trait will be matched against the type expected by
//! For example, consider the following handler: //! the user. For example, consider the following handler:
//! //!
//! ```rust,ignore //! ```rust
//! # use rocket::post;
//! # type S = rocket::data::Data;
//! #[post("/", data = "<my_val>")] //! #[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 //! The [`FromTransformedData`] implementation for the type `S` returns an
//! `Success(S)`. If `from_data` returns a `Success`, the `Success` value will //! `Outcome` with a `Success(S)`. If `from_data` returns a `Success`, the
//! be unwrapped and the value will be used as the value of `my_val`. //! `Success` value will be unwrapped and the value will be used as the value of
//! `my_val`.
//! //!
//! # Failure //! # Failure
//! //!
@ -45,16 +48,19 @@
//! or `Option<S>` in request handlers. For example, if a user's handler looks //! or `Option<S>` in request handlers. For example, if a user's handler looks
//! like: //! like:
//! //!
//! ```rust,ignore //! ```rust
//! # use rocket::post;
//! # type S = rocket::data::Data;
//! # type E = std::convert::Infallible;
//! #[post("/", data = "<my_val>")] //! #[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 //! The [`FromTransformedData`] implementation for the type `S` returns an
//! `Success(S)` and `Failure(E)`. If `from_data` returns a `Failure`, the //! `Outcome` with a `Success(S)` and `Failure(E)`. If `from_data` returns a
//! `Failure` value will be unwrapped and the value will be used as the `Err` //! `Failure`, the `Failure` value will be unwrapped and the value will be used
//! value of `my_val` while a `Success` will be unwrapped and used the `Ok` //! as the `Err` value of `my_val` while a `Success` will be unwrapped and used
//! value. //! the `Ok` value.
//! //!
//! # Forward //! # Forward
//! //!
@ -66,19 +72,21 @@
//! next available request handler. For example, consider the following request //! next available request handler. For example, consider the following request
//! handler: //! handler:
//! //!
//! ```rust,ignore //! ```rust
//! # use rocket::post;
//! # type S = rocket::data::Data;
//! #[post("/", data = "<my_val>")] //! #[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 //! The [`FromTransformedData`] implementation for the type `S` returns an
//! `Success(S)`, `Failure(E)`, and `Forward(F)`. If the `Outcome` is a //! `Outcome` with a `Success(S)`, `Failure(E)`, and `Forward(F)`. If the
//! `Forward`, the `hello` handler isn't called. Instead, the incoming request //! `Outcome` is a `Forward`, the `hello` handler isn't called. Instead, the
//! is forwarded, or passed on to, the next matching route, if any. Ultimately, //! incoming request is forwarded, or passed on to, the next matching route, if
//! if there are no non-forwarding routes, forwarded requests are handled by the //! any. Ultimately, if there are no non-forwarding routes, forwarded requests
//! 404 catcher. Similar to `Failure`s, users can catch `Forward`s by requesting //! are handled by the 404 catcher. Similar to `Failure`s, users can catch
//! a type of `Option<S>`. If an `Outcome` is a `Forward`, the `Option` will be //! `Forward`s by requesting a type of `Option<S>`. If an `Outcome` is a
//! `None`. //! `Forward`, the `Option` will be `None`.
use std::fmt; 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 /// Because of the early return, `try_outcome!` can only be used in methods that
/// return [`Outcome`]. /// return [`Outcome`].
/// ///
/// [`Outcome`]: crate::outcome::Outcome
///
/// ## Example /// ## Example
/// ///
/// ```rust,no_run /// ```rust,no_run

View File

@ -189,9 +189,8 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// ```rust /// ```rust
/// # #[macro_use] extern crate rocket; /// # #[macro_use] extern crate rocket;
/// # /// #
/// use rocket::Outcome;
/// use rocket::http::Status; /// use rocket::http::Status;
/// use rocket::request::{self, Request, FromRequest}; /// use rocket::request::{self, Outcome, Request, FromRequest};
/// ///
/// struct ApiKey(String); /// 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 { /// impl<'a, 'r> FromRequest<'a, 'r> for ApiKey {
/// type Error = ApiKeyError; /// 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(); /// let keys: Vec<_> = req.headers().get("x-api-key").collect();
/// match keys.len() { /// match keys.len() {
/// 0 => Outcome::Failure((Status::BadRequest, ApiKeyError::Missing)), /// 0 => Outcome::Failure((Status::BadRequest, ApiKeyError::Missing)),
@ -244,8 +243,8 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// ```rust /// ```rust
/// # #[macro_use] extern crate rocket; /// # #[macro_use] extern crate rocket;
/// # #[cfg(feature = "private-cookies")] mod inner { /// # #[cfg(feature = "private-cookies")] mod inner {
/// # use rocket::outcome::{IntoOutcome, Outcome}; /// # use rocket::outcome::IntoOutcome;
/// # use rocket::request::{self, FromRequest, Request}; /// # use rocket::request::{self, Outcome, FromRequest, Request};
/// # struct User { id: String, is_admin: bool } /// # struct User { id: String, is_admin: bool }
/// # struct Database; /// # struct Database;
/// # impl Database { /// # impl Database {
@ -256,7 +255,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// # #[rocket::async_trait] /// # #[rocket::async_trait]
/// # impl<'a, 'r> FromRequest<'a, 'r> for Database { /// # impl<'a, 'r> FromRequest<'a, 'r> for Database {
/// # type Error = (); /// # 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) /// # 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 { /// impl<'a, 'r> FromRequest<'a, 'r> for User {
/// type Error = (); /// 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); /// let db = try_outcome!(request.guard::<Database>().await);
/// request.cookies() /// request.cookies()
/// .get_private("user_id") /// .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 { /// impl<'a, 'r> FromRequest<'a, 'r> for Admin {
/// type Error = (); /// 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! /// // This will unconditionally query the database!
/// let user = try_outcome!(request.guard::<User>().await); /// let user = try_outcome!(request.guard::<User>().await);
/// if user.is_admin { /// if user.is_admin {
@ -308,8 +307,8 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// ```rust /// ```rust
/// # #[macro_use] extern crate rocket; /// # #[macro_use] extern crate rocket;
/// # #[cfg(feature = "private-cookies")] mod inner { /// # #[cfg(feature = "private-cookies")] mod inner {
/// # use rocket::outcome::{IntoOutcome, Outcome}; /// # use rocket::outcome::IntoOutcome;
/// # use rocket::request::{self, FromRequest, Request}; /// # use rocket::request::{self, Outcome, FromRequest, Request};
/// # struct User { id: String, is_admin: bool } /// # struct User { id: String, is_admin: bool }
/// # struct Database; /// # struct Database;
/// # impl Database { /// # impl Database {
@ -320,7 +319,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
/// # #[rocket::async_trait] /// # #[rocket::async_trait]
/// # impl<'a, 'r> FromRequest<'a, 'r> for Database { /// # impl<'a, 'r> FromRequest<'a, 'r> for Database {
/// # type Error = (); /// # 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) /// # 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 { /// impl<'a, 'r> FromRequest<'a, 'r> for &'a User {
/// type Error = std::convert::Infallible; /// 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 /// // This closure will execute at most once per request, regardless of
/// // the number of times the `User` guard is executed. /// // the number of times the `User` guard is executed.
/// let user_result = request.local_cache_async(async { /// 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> { /// impl<'a, 'r> FromRequest<'a, 'r> for Admin<'a> {
/// type Error = std::convert::Infallible; /// 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); /// let user = try_outcome!(request.guard::<&User>().await);
/// if user.is_admin { /// if user.is_admin {
/// Outcome::Success(Admin { user }) /// 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 /// 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 /// 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 /// number of handlers. A value for the given type must previously have been
/// registered to be managed by Rocket via /// registered to be managed by Rocket via [`Rocket::manage()`]. The type being
/// [`Rocket::manage()`]. The type being managed must be /// managed must be thread safe and sendable across thread boundaries. In other
/// thread safe and sendable across thread boundaries. In other words, it must /// words, it must implement [`Send`] + [`Sync`] + `'static`.
/// implement [`Send`] + [`Sync`] + `'static`. ///
/// [`Rocket::manage()`]: crate::Rocket::manage()
/// ///
/// # Example /// # Example
/// ///
@ -41,7 +42,7 @@ use crate::http::Status;
/// state.inner().user_val.as_str() /// state.inner().user_val.as_str()
/// } /// }
/// ///
/// #[rocket::launch] /// #[launch]
/// fn rocket() -> rocket::Rocket { /// fn rocket() -> rocket::Rocket {
/// rocket::ignite() /// rocket::ignite()
/// .mount("/", routes![index, raw_config_value]) /// .mount("/", routes![index, raw_config_value])

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -61,7 +61,7 @@ fn token(token: State<'_, Token>) -> String {
format!("{}", token.0) format!("{}", token.0)
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite() rocket::ignite()
.mount("/", routes![hello, token]) .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 { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![sink]).mount("/", StaticFiles::from("static/")) 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) format!("This is {}'s page.", username)
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite() rocket::ignite()
.mount("/", routes![user_page, login]) .mount("/", routes![user_page, login])

View File

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

View File

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

View File

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

View File

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

View File

@ -1,14 +1,12 @@
extern crate rocket;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
use std::env; 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::http::{Status, RawStr};
use rocket::response::{Responder, status::Custom}; 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::outcome::IntoOutcome;
use rocket::http::Method::*; use rocket::http::Method::*;
use rocket::tokio::fs::File; use rocket::tokio::fs::File;
@ -82,8 +80,6 @@ impl CustomHandler {
} }
} }
// FIXME: Will this work?
#[rocket::async_trait] #[rocket::async_trait]
impl Handler for CustomHandler { impl Handler for CustomHandler {
async fn handle<'r, 's: 'r>(&'s self, req: &'r Request<'_>, data: Data) -> Outcome<'r> { 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() data.contents.to_string()
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/message", routes![get, create]) 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?" "Hi! That user doesn't exist. Maybe you need to log in?"
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![root, user, login]) rocket::ignite().mount("/", routes![root, user, login])
} }

View File

@ -48,7 +48,7 @@ fn index() -> &'static str {
" "
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![index, upload, retrieve]) 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) format!("20 years old? Hi, {}!", person.name)
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![hello, hello_20]) 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) format!("Hi {}! Your age ({}) is kind of funky.", name, age)
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![hi, hello]) 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) .map_err(Debug)
} }
#[rocket::launch] #[launch]
fn rocket() -> Rocket { fn rocket() -> Rocket {
// Open a new in-memory SQLite database. // Open a new in-memory SQLite database.
let conn = Connection::open_in_memory().expect("in memory db"); 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." "Upload your text files by POSTing them to /upload."
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![index, upload]) rocket::ignite().mount("/", routes![index, upload])
} }

View File

@ -14,7 +14,7 @@ fn login() -> &'static str {
"Hi! Please log in before continuing." "Hi! Please log in before continuing."
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![root, login]) 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) format!("Your request contained {} headers!", header_count.0)
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![header_count]) 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. // This exists only to run the request guards.
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite() rocket::ignite()
.manage(Atomics::default()) .manage(Atomics::default())

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@ fn hello() -> &'static str {
"Hello, world!" "Hello, world!"
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![hello]) 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 { fn rocket() -> Rocket {
rocket::ignite() rocket::ignite()
.attach(DbConn::fairing()) .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))?) .ok_or_else(|| format!("Person not found for UUID: {}", id))?)
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![people]) rocket::ignite().mount("/", routes![people])
} }

View File

@ -52,7 +52,7 @@ And finally, create a skeleton Rocket application to work off of in
```rust ```rust
#[macro_use] extern crate rocket; #[macro_use] extern crate rocket;
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite() 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; # #[macro_use] extern crate rocket;
# #[get("/")] fn index() { } # #[get("/")] fn index() { }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![index]) rocket::ignite().mount("/", routes![index])
} }
@ -283,7 +283,7 @@ Ensure that the route is mounted at the root path:
# #[get("/")] fn index() {} # #[get("/")] fn index() {}
# #[post("/")] fn upload() {} # #[post("/")] fn upload() {}
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![index, upload]) rocket::ignite().mount("/", routes![index, upload])
} }
@ -345,7 +345,7 @@ Make sure that the route is mounted at the root path:
# #[post("/")] fn upload() {} # #[post("/")] fn upload() {}
# #[get("/<id>")] fn retrieve(id: String) {} # #[get("/<id>")] fn retrieve(id: String) {}
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![index, upload, retrieve]) 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 incoming requests. When a request arrives, Rocket finds the matching route and
dispatches the request to the route's handler. 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: Our complete _Hello, world!_ application thus looks like:
```rust ```rust
@ -178,7 +178,7 @@ fn world() -> &'static str {
"Hello, world!" "Hello, world!"
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/hello", routes![world]) 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 ! note
Rocket 0.5 uses the tokio (0.2) runtime. The runtime is started for you if you 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`. rocket instance on a custom-built `Runtime`.
### Cooperative Multitasking ### Cooperative Multitasking

View File

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

View File

@ -294,7 +294,7 @@ use rocket_contrib::databases::diesel;
#[database("sqlite_logs")] #[database("sqlite_logs")]
struct LogsDbConn(diesel::SqliteConnection); struct LogsDbConn(diesel::SqliteConnection);
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().attach(LogsDbConn::fairing()) 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: `res_fairing`, to a new Rocket instance:
```rust ```rust
#[rocket::launch] # use rocket::launch;
#[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
# let req_fairing = rocket::fairing::AdHoc::on_request("example", |_, _| Box::pin(async {})); # let req_fairing = rocket::fairing::AdHoc::on_request("example", |_, _| Box::pin(async {}));
# let res_fairing = rocket::fairing::AdHoc::on_response("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!" "Hello, world!"
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite().mount("/", routes![hello]) 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() NamedFile::open(Path::new(&assets_dir.0).join(asset)).await.ok()
} }
#[rocket::launch] #[launch]
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite() rocket::ignite()
.mount("/", routes![assets]) .mount("/", routes![assets])