mirror of https://github.com/rwf2/Rocket.git
Add '#[rocket::launch]' attribute.
The attribute is applied everywhere it can be across the codebase and is the newly preferred method for launching an application. This commit also makes '#[rocket::main]` stricter by warning when it is applied to functions other than 'main'.
This commit is contained in:
parent
c7c371910b
commit
12308b403f
|
@ -10,8 +10,6 @@ Rocket is a web framework for Rust (nightly) with a focus on ease-of-use,
|
|||
expressibility, and speed. Here's an example of a complete Rocket application:
|
||||
|
||||
```rust
|
||||
#![feature(proc_macro_hygiene)]
|
||||
|
||||
#[macro_use] extern crate rocket;
|
||||
|
||||
#[get("/<name>/<age>")]
|
||||
|
@ -19,8 +17,9 @@ fn hello(name: String, age: u8) -> String {
|
|||
format!("Hello, {} year old named {}!", age, name)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
rocket::ignite().mount("/hello", routes![hello]).launch();
|
||||
#[launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/hello", routes![hello])
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -62,12 +62,9 @@
|
|||
//! #[database("sqlite_logs")]
|
||||
//! struct LogsDbConn(diesel::SqliteConnection);
|
||||
//!
|
||||
//! #[rocket::main]
|
||||
//! async fn main() {
|
||||
//! rocket::ignite()
|
||||
//! .attach(LogsDbConn::fairing())
|
||||
//! .launch()
|
||||
//! .await;
|
||||
//! #[rocket::launch]
|
||||
//! fn rocket() -> rocket::Rocket {
|
||||
//! rocket::ignite().attach(LogsDbConn::fairing())
|
||||
//! }
|
||||
//! # } fn main() {}
|
||||
//! ```
|
||||
|
@ -152,8 +149,8 @@
|
|||
//! use std::collections::HashMap;
|
||||
//! use rocket::config::{Config, Environment, Value};
|
||||
//!
|
||||
//! #[rocket::main]
|
||||
//! async fn main() {
|
||||
//! #[rocket::launch]
|
||||
//! fn rocket() -> rocket::Rocket {
|
||||
//! let mut database_config = HashMap::new();
|
||||
//! let mut databases = HashMap::new();
|
||||
//!
|
||||
|
@ -167,7 +164,7 @@
|
|||
//! .finalize()
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! rocket::custom(config).launch().await;
|
||||
//! rocket::custom(config)
|
||||
//! }
|
||||
//! # } fn main() {}
|
||||
//! ```
|
||||
|
@ -266,8 +263,8 @@
|
|||
//! #[database("my_db")]
|
||||
//! struct MyDatabase(diesel::SqliteConnection);
|
||||
//!
|
||||
//! #[rocket::main]
|
||||
//! async fn main() {
|
||||
//! #[rocket::launch]
|
||||
//! fn rocket() -> rocket::Rocket {
|
||||
//! # let mut db_config = HashMap::new();
|
||||
//! # let mut databases = HashMap::new();
|
||||
//! #
|
||||
|
@ -280,10 +277,7 @@
|
|||
//! # .finalize()
|
||||
//! # .unwrap();
|
||||
//! #
|
||||
//! rocket::custom(config)
|
||||
//! .attach(MyDatabase::fairing())
|
||||
//! .launch()
|
||||
//! .await;
|
||||
//! rocket::custom(config).attach(MyDatabase::fairing())
|
||||
//! }
|
||||
//! # } fn main() {}
|
||||
//! ```
|
||||
|
|
|
@ -130,19 +130,14 @@ impl std::ops::BitOr for Options {
|
|||
/// `/public` path, allowing `index.html` files to be used to respond to
|
||||
/// requests for a directory (the default), you might write the following:
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # extern crate rocket;
|
||||
/// # extern crate rocket_contrib;
|
||||
/// use rocket_contrib::serve::StaticFiles;
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false {
|
||||
/// rocket::ignite()
|
||||
/// .mount("/public", StaticFiles::from("/static"))
|
||||
/// .launch()
|
||||
/// .await;
|
||||
/// # }
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite().mount("/public", StaticFiles::from("/static"))
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
@ -158,19 +153,15 @@ impl std::ops::BitOr for Options {
|
|||
/// For example, to serve files in the `static` subdirectory of your crate at
|
||||
/// `/`, you might write:
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # extern crate rocket;
|
||||
/// # extern crate rocket_contrib;
|
||||
/// use rocket_contrib::serve::StaticFiles;
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false {
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite()
|
||||
/// .mount("/", StaticFiles::from(concat!(env!("CARGO_MANIFEST_DIR"), "/static")))
|
||||
/// .launch()
|
||||
/// .await;
|
||||
/// # }
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Clone)]
|
||||
|
@ -195,37 +186,27 @@ impl StaticFiles {
|
|||
/// Serve the static files in the `/www/public` local directory on path
|
||||
/// `/static`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # extern crate rocket;
|
||||
/// # extern crate rocket_contrib;
|
||||
/// use rocket_contrib::serve::StaticFiles;
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false {
|
||||
/// rocket::ignite()
|
||||
/// .mount("/static", StaticFiles::from("/www/public"))
|
||||
/// .launch()
|
||||
/// .await;
|
||||
/// # }
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite().mount("/static", StaticFiles::from("/www/public"))
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Exactly as before, but set the rank for generated routes to `30`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # extern crate rocket;
|
||||
/// # extern crate rocket_contrib;
|
||||
/// use rocket_contrib::serve::StaticFiles;
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false {
|
||||
/// rocket::ignite()
|
||||
/// .mount("/static", StaticFiles::from("/www/public").rank(30))
|
||||
/// .launch()
|
||||
/// .await;
|
||||
/// # }
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite().mount("/static", StaticFiles::from("/www/public").rank(30))
|
||||
/// }
|
||||
/// ```
|
||||
pub fn from<P: AsRef<Path>>(path: P) -> Self {
|
||||
|
@ -243,21 +224,17 @@ impl StaticFiles {
|
|||
/// the same files on `/pub` with a route rank of -1 while also serving
|
||||
/// index files and dot files.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # extern crate rocket;
|
||||
/// # extern crate rocket_contrib;
|
||||
/// use rocket_contrib::serve::{StaticFiles, Options};
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false {
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// let options = Options::Index | Options::DotFiles;
|
||||
/// rocket::ignite()
|
||||
/// .mount("/static", StaticFiles::from("/www/public"))
|
||||
/// .mount("/pub", StaticFiles::new("/www/public", options).rank(-1))
|
||||
/// .launch()
|
||||
/// .await;
|
||||
/// # }
|
||||
/// }
|
||||
/// ```
|
||||
pub fn new<P: AsRef<Path>>(path: P, options: Options) -> Self {
|
||||
|
|
|
@ -1,83 +1,126 @@
|
|||
use proc_macro::{TokenStream, Span};
|
||||
use devise::{syn, Result};
|
||||
use devise::{syn, Spanned, Result};
|
||||
|
||||
use crate::proc_macro2::TokenStream as TokenStream2;
|
||||
use crate::syn_ext::syn_to_diag;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Kind {
|
||||
Main,
|
||||
Test,
|
||||
trait EntryAttr {
|
||||
/// Whether the attribute requires the attributed function to be `async`.
|
||||
const REQUIRES_ASYNC: bool;
|
||||
|
||||
/// Return a new or rewritten function, using block as the main execution.
|
||||
fn function(f: &syn::ItemFn, body: &syn::Block) -> Result<TokenStream2>;
|
||||
}
|
||||
|
||||
impl Kind {
|
||||
// The name of the attribute, used for error messages
|
||||
fn attr_name(&self) -> &'static str {
|
||||
match self {
|
||||
Kind::Main => "main",
|
||||
Kind::Test => "async_test",
|
||||
}
|
||||
}
|
||||
struct Main;
|
||||
|
||||
// Attributes to decorate the generated function with
|
||||
fn attrs(&self) -> Option<TokenStream2> {
|
||||
match self {
|
||||
Kind::Main => None,
|
||||
Kind::Test => Some(quote!{ #[test] }),
|
||||
}
|
||||
}
|
||||
impl EntryAttr for Main {
|
||||
const REQUIRES_ASYNC: bool = true;
|
||||
|
||||
// The path to the function to call
|
||||
fn fn_path(&self) -> TokenStream2 {
|
||||
match self {
|
||||
Kind::Main => quote! { rocket :: async_main },
|
||||
Kind::Test => quote! { rocket :: async_test },
|
||||
fn function(f: &syn::ItemFn, block: &syn::Block) -> Result<TokenStream2> {
|
||||
let (attrs, vis, mut sig) = (&f.attrs, &f.vis, f.sig.clone());
|
||||
if sig.ident != "main" {
|
||||
Span::call_site()
|
||||
.warning("attribute is typically applied to `main` function")
|
||||
.span_note(sig.span(), "this function is not `main`")
|
||||
.emit();
|
||||
}
|
||||
|
||||
sig.asyncness = None;
|
||||
Ok(quote_spanned!(block.span().into() => #(#attrs)* #vis #sig {
|
||||
::rocket::async_main(async move #block)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_input(input: TokenStream, attr_name: &str) -> Result<syn::ItemFn> {
|
||||
let function: syn::ItemFn = syn::parse(input).map_err(syn_to_diag)
|
||||
.map_err(|diag| diag.help(format!("`#[{}]` can only be applied to async functions", attr_name)))?;
|
||||
struct Test;
|
||||
|
||||
if function.sig.asyncness.is_none() {
|
||||
return Err(Span::call_site().error(format!("`#[{}]` can only be applied to async functions", attr_name)))
|
||||
impl EntryAttr for Test {
|
||||
const REQUIRES_ASYNC: bool = true;
|
||||
|
||||
fn function(f: &syn::ItemFn, block: &syn::Block) -> Result<TokenStream2> {
|
||||
let (attrs, vis, mut sig) = (&f.attrs, &f.vis, f.sig.clone());
|
||||
sig.asyncness = None;
|
||||
Ok(quote_spanned!(block.span().into() => #(#attrs)* #[test] #vis #sig {
|
||||
::rocket::async_test(async move #block)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
struct Launch;
|
||||
|
||||
impl EntryAttr for Launch {
|
||||
const REQUIRES_ASYNC: bool = false;
|
||||
|
||||
fn function(f: &syn::ItemFn, block: &syn::Block) -> Result<TokenStream2> {
|
||||
if f.sig.ident == "main" {
|
||||
return Err(Span::call_site()
|
||||
.error("attribute cannot be applied to `main` function")
|
||||
.note("this attribute generates a `main` function")
|
||||
.span_note(f.sig.span(), "this function cannot be `main`"));
|
||||
}
|
||||
|
||||
let ty = match &f.sig.output {
|
||||
syn::ReturnType::Type(_, ty) => ty,
|
||||
_ => return Err(Span::call_site()
|
||||
.error("attribute can only be applied to functions that return a value")
|
||||
.span_note(f.sig.span(), "this function must return a value"))
|
||||
};
|
||||
|
||||
let rocket = quote_spanned!(ty.span().into() => {
|
||||
let ___rocket: #ty = #block;
|
||||
let ___rocket: ::rocket::Rocket = ___rocket;
|
||||
___rocket
|
||||
});
|
||||
|
||||
let (vis, mut sig) = (&f.vis, f.sig.clone());
|
||||
sig.ident = syn::Ident::new("main", sig.ident.span());
|
||||
sig.output = syn::ReturnType::Default;
|
||||
sig.asyncness = None;
|
||||
|
||||
Ok(quote_spanned!(block.span().into() =>
|
||||
#[allow(dead_code)] #f
|
||||
|
||||
#vis #sig {
|
||||
::rocket::async_main(async move { let _ = #rocket.launch().await; })
|
||||
}
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_input<A: EntryAttr>(input: TokenStream) -> Result<syn::ItemFn> {
|
||||
let function: syn::ItemFn = syn::parse(input)
|
||||
.map_err(syn_to_diag)
|
||||
.map_err(|d| d.help("attribute can only be applied to functions"))?;
|
||||
|
||||
if A::REQUIRES_ASYNC && function.sig.asyncness.is_none() {
|
||||
return Err(Span::call_site()
|
||||
.error("attribute can only be applied to `async` functions")
|
||||
.span_note(function.sig.span(), "this function must be `async`"));
|
||||
}
|
||||
|
||||
if !function.sig.inputs.is_empty() {
|
||||
return Err(Span::call_site().error(format!("`#[{}]` can only be applied to functions with no parameters", attr_name)));
|
||||
return Err(Span::call_site()
|
||||
.error("attribute can only be applied to functions without arguments")
|
||||
.span_note(function.sig.span(), "this function must take no arguments"));
|
||||
}
|
||||
|
||||
Ok(function)
|
||||
}
|
||||
|
||||
fn _async_entry(_args: TokenStream, input: TokenStream, kind: Kind) -> Result<TokenStream> {
|
||||
let function = parse_input(input, kind.attr_name())?;
|
||||
|
||||
let attrs = &function.attrs;
|
||||
let vis = &function.vis;
|
||||
let name = &function.sig.ident;
|
||||
let output = &function.sig.output;
|
||||
let body = &function.block;
|
||||
|
||||
let test_attr = kind.attrs();
|
||||
let fn_path = kind.fn_path();
|
||||
|
||||
Ok(quote! {
|
||||
#test_attr
|
||||
#(#attrs)*
|
||||
#vis fn #name() #output {
|
||||
#fn_path (async move {
|
||||
#body
|
||||
})
|
||||
}
|
||||
}.into())
|
||||
fn _async_entry<A: EntryAttr>(_args: TokenStream, input: TokenStream) -> Result<TokenStream> {
|
||||
let function = parse_input::<A>(input)?;
|
||||
A::function(&function, &function.block).map(|t| t.into())
|
||||
}
|
||||
|
||||
pub fn async_test_attribute(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
_async_entry(args, input, Kind::Test).unwrap_or_else(|d| { d.emit(); TokenStream::new() })
|
||||
_async_entry::<Test>(args, input).unwrap_or_else(|d| { d.emit(); TokenStream::new() })
|
||||
}
|
||||
|
||||
pub fn main_attribute(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
_async_entry(args, input, Kind::Main).unwrap_or_else(|d| { d.emit(); TokenStream::new() })
|
||||
_async_entry::<Main>(args, input).unwrap_or_else(|d| { d.emit(); quote!(fn main() {}).into() })
|
||||
}
|
||||
|
||||
pub fn launch_attribute(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
_async_entry::<Launch>(args, input).unwrap_or_else(|d| { d.emit(); quote!(fn main() {}).into() })
|
||||
}
|
||||
|
|
|
@ -405,16 +405,24 @@ pub fn catch(args: TokenStream, input: TokenStream) -> TokenStream {
|
|||
emit!(attribute::catch::catch_attribute(args, input))
|
||||
}
|
||||
|
||||
/// FIXME: Document.
|
||||
#[proc_macro_attribute]
|
||||
pub fn async_test(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
emit!(attribute::async_entry::async_test_attribute(args, input))
|
||||
}
|
||||
|
||||
/// FIXME: Document.
|
||||
#[proc_macro_attribute]
|
||||
pub fn main(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
emit!(attribute::async_entry::main_attribute(args, input))
|
||||
}
|
||||
|
||||
/// FIXME: Document.
|
||||
#[proc_macro_attribute]
|
||||
pub fn launch(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
emit!(attribute::async_entry::launch_attribute(args, input))
|
||||
}
|
||||
|
||||
/// Derive for the [`FromFormValue`] trait.
|
||||
///
|
||||
/// The [`FromFormValue`] derive can be applied to enums with nullary
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
#![allow(dead_code, unused_variables)]
|
||||
|
||||
mod a {
|
||||
// async launch that is async.
|
||||
#[rocket::launch]
|
||||
async fn rocket() -> rocket::Rocket {
|
||||
let _ = rocket::ignite().launch().await;
|
||||
rocket::ignite()
|
||||
}
|
||||
|
||||
async fn use_it() {
|
||||
let rocket: rocket::Rocket = rocket().await;
|
||||
}
|
||||
}
|
||||
|
||||
mod b {
|
||||
// async launch that isn't async.
|
||||
#[rocket::launch]
|
||||
async fn main2() -> rocket::Rocket {
|
||||
rocket::ignite()
|
||||
}
|
||||
|
||||
async fn use_it() {
|
||||
let rocket: rocket::Rocket = main2().await;
|
||||
}
|
||||
}
|
||||
|
||||
mod c {
|
||||
// non-async launch.
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite()
|
||||
}
|
||||
|
||||
fn use_it() {
|
||||
let rocket: rocket::Rocket = rocket();
|
||||
}
|
||||
}
|
||||
|
||||
mod d {
|
||||
// main with async, is async.
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket::ignite().launch().await;
|
||||
}
|
||||
}
|
||||
|
||||
mod e {
|
||||
// main with async, isn't async.
|
||||
#[rocket::main]
|
||||
async fn main() { }
|
||||
}
|
||||
|
||||
mod f {
|
||||
// main with async, is async, with termination return.
|
||||
#[rocket::main]
|
||||
async fn main() -> Result<(), String> {
|
||||
let result = rocket::ignite().launch().await;
|
||||
result.map_err(|e| e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
mod g {
|
||||
// main with async, isn't async, with termination return.
|
||||
#[rocket::main]
|
||||
async fn main() -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// main with async, is async, with termination return.
|
||||
#[rocket::main]
|
||||
async fn main() -> Result<(), String> {
|
||||
let result = rocket::ignite().launch().await;
|
||||
result.map_err(|e| e.to_string())
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
// rocket::main
|
||||
|
||||
mod main_a {
|
||||
#[rocket::main]
|
||||
fn foo() { }
|
||||
//~^^ ERROR `async`
|
||||
}
|
||||
|
||||
mod main_b {
|
||||
#[rocket::main]
|
||||
async fn foo() { }
|
||||
//~^^ WARNING `main`
|
||||
}
|
||||
|
||||
mod main_d {
|
||||
#[rocket::main]
|
||||
fn main() {
|
||||
//~^^ ERROR `async`
|
||||
let _ = rocket::ignite().launch().await;
|
||||
}
|
||||
}
|
||||
|
||||
mod main_f {
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
//~^ ERROR mismatched types
|
||||
rocket::ignite()
|
||||
}
|
||||
}
|
||||
|
||||
// rocket::launch
|
||||
|
||||
mod launch_a {
|
||||
#[rocket::launch]
|
||||
async fn rocket() -> String {
|
||||
//~^ ERROR mismatched types
|
||||
let _ = rocket::ignite().launch().await;
|
||||
rocket::ignite()
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
||||
mod launch_b {
|
||||
#[rocket::launch]
|
||||
async fn rocket() -> rocket::Rocket {
|
||||
let _ = rocket::ignite().launch().await;
|
||||
"hi".to_string()
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
||||
mod launch_c {
|
||||
#[rocket::launch]
|
||||
fn main() -> rocket::Rocket {
|
||||
//~^^ ERROR `main`
|
||||
rocket::ignite()
|
||||
}
|
||||
}
|
||||
|
||||
mod launch_d {
|
||||
#[rocket::launch]
|
||||
async fn rocket() {
|
||||
//~^^ ERROR functions that return
|
||||
let _ = rocket::ignite().launch().await;
|
||||
rocket::ignite()
|
||||
}
|
||||
}
|
||||
|
||||
mod launch_e {
|
||||
#[rocket::launch]
|
||||
fn rocket() {
|
||||
//~^^ ERROR functions that return
|
||||
rocket::ignite()
|
||||
}
|
||||
}
|
||||
|
||||
mod launch_f {
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
let _ = rocket::ignite().launch().await;
|
||||
//~^ ERROR only allowed inside `async`
|
||||
rocket::ignite()
|
||||
}
|
||||
}
|
||||
|
||||
mod launch_g {
|
||||
#[rocket::launch]
|
||||
fn main() -> &'static str {
|
||||
//~^^ ERROR `main`
|
||||
let _ = rocket::ignite().launch().await;
|
||||
"hi"
|
||||
}
|
||||
}
|
||||
|
||||
mod launch_h {
|
||||
#[rocket::launch]
|
||||
async fn main() -> rocket::Rocket {
|
||||
//~^^ ERROR `main`
|
||||
rocket::ignite()
|
||||
}
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() -> rocket::Rocket {
|
||||
//~^ ERROR invalid return type
|
||||
rocket::ignite()
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
error: attribute can only be applied to `async` functions
|
||||
--> $DIR/async-entry.rs:6:5
|
||||
|
|
||||
6 | #[rocket::main]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: this function must be `async`
|
||||
--> $DIR/async-entry.rs:7:5
|
||||
|
|
||||
7 | fn foo() { }
|
||||
| ^^^^^^^^
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: attribute is typically applied to `main` function
|
||||
--> $DIR/async-entry.rs:12:5
|
||||
|
|
||||
12 | #[rocket::main]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: this function is not `main`
|
||||
--> $DIR/async-entry.rs:13:5
|
||||
|
|
||||
13 | async fn foo() { }
|
||||
| ^^^^^^^^^^^^^^
|
||||
= note: this warning originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: attribute can only be applied to `async` functions
|
||||
--> $DIR/async-entry.rs:18:5
|
||||
|
|
||||
18 | #[rocket::main]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: this function must be `async`
|
||||
--> $DIR/async-entry.rs:19:5
|
||||
|
|
||||
19 | fn main() {
|
||||
| ^^^^^^^^^
|
||||
= 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:55:5
|
||||
|
|
||||
55 | #[rocket::launch]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this attribute generates a `main` function
|
||||
note: this function cannot be `main`
|
||||
--> $DIR/async-entry.rs:56:5
|
||||
|
|
||||
56 | 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:63:5
|
||||
|
|
||||
63 | #[rocket::launch]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: this function must return a value
|
||||
--> $DIR/async-entry.rs:64:5
|
||||
|
|
||||
64 | 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:72:5
|
||||
|
|
||||
72 | #[rocket::launch]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: this function must return a value
|
||||
--> $DIR/async-entry.rs:73:5
|
||||
|
|
||||
73 | 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:89:5
|
||||
|
|
||||
89 | #[rocket::launch]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this attribute generates a `main` function
|
||||
note: this function cannot be `main`
|
||||
--> $DIR/async-entry.rs:90:5
|
||||
|
|
||||
90 | 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:98:5
|
||||
|
|
||||
98 | #[rocket::launch]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this attribute generates a `main` function
|
||||
note: this function cannot be `main`
|
||||
--> $DIR/async-entry.rs:99:5
|
||||
|
|
||||
99 | 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:82:17
|
||||
|
|
||||
81 | fn rocket() -> rocket::Rocket {
|
||||
| ------ this is not `async`
|
||||
82 | let _ = rocket::ignite().launch().await;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-entry.rs:40:9
|
||||
|
|
||||
40 | rocket::ignite()
|
||||
| ^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found struct `rocket::rocket::Rocket`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-entry.rs:49:9
|
||||
|
|
||||
49 | "hi".to_string()
|
||||
| ^^^^^^^^^^^^^^^^ expected struct `rocket::rocket::Rocket`, found struct `std::string::String`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-entry.rs:27:21
|
||||
|
|
||||
27 | async fn main() {
|
||||
| ^ expected `()` because of default return type
|
||||
| _____________________|
|
||||
| |
|
||||
28 | | //~^ ERROR mismatched types
|
||||
29 | | rocket::ignite()
|
||||
30 | | }
|
||||
| | ^- help: try adding a semicolon: `;`
|
||||
| |_____|
|
||||
| expected `()`, found struct `rocket::rocket::Rocket`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-entry.rs:37:26
|
||||
|
|
||||
37 | 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:106:20
|
||||
|
|
||||
106 | async fn main() -> rocket::Rocket {
|
||||
| ^^^^^^^^^^^^^^ `main` can only return types that implement `std::process::Termination`
|
||||
|
|
||||
= help: consider using `()`, or a `Result`
|
||||
|
||||
error: aborting due to 13 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308, E0728.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
|
@ -35,7 +35,7 @@ use yansi::Color::*;
|
|||
/// Catchers should rarely be used directly. Instead, they are typically
|
||||
/// declared using the `catch` decorator, as follows:
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// #![feature(proc_macro_hygiene)]
|
||||
///
|
||||
/// #[macro_use] extern crate rocket;
|
||||
|
@ -52,11 +52,9 @@ use yansi::Color::*;
|
|||
/// format!("I couldn't find '{}'. Try something else?", req.uri())
|
||||
/// }
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false { // We don't actually want to launch the server in an example.
|
||||
/// rocket::ignite().register(catchers![internal_error, not_found]).launch().await;
|
||||
/// # }
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite().register(catchers![internal_error, not_found])
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
|
|
@ -41,7 +41,7 @@ pub type HandlerFuture<'r> = BoxFuture<'r, Outcome<'r>>;
|
|||
///
|
||||
/// Such a handler might be written and used as follows:
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # #[derive(Copy, Clone)] enum Kind { Simple, Intermediate, Complex, }
|
||||
/// use rocket::{Request, Data, Route, http::Method};
|
||||
/// use rocket::handler::{self, Handler, Outcome, HandlerFuture};
|
||||
|
@ -65,14 +65,9 @@ pub type HandlerFuture<'r> = BoxFuture<'r, Outcome<'r>>;
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false {
|
||||
/// rocket::ignite()
|
||||
/// .mount("/", CustomHandler(Kind::Simple))
|
||||
/// .launch()
|
||||
/// .await;
|
||||
/// # }
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite().mount("/", CustomHandler(Kind::Simple))
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
@ -92,7 +87,7 @@ pub type HandlerFuture<'r> = BoxFuture<'r, Outcome<'r>>;
|
|||
/// The previous example could have been implemented using a combination of
|
||||
/// managed state and a static route, as follows:
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// #
|
||||
|
@ -114,15 +109,11 @@ pub type HandlerFuture<'r> = BoxFuture<'r, Outcome<'r>>;
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false {
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite()
|
||||
/// .mount("/", routes![custom_handler])
|
||||
/// .manage(Kind::Simple)
|
||||
/// .launch()
|
||||
/// .await;
|
||||
/// # }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
//! See the [guide](https://rocket.rs/v0.5/guide) for more information on how to
|
||||
//! write Rocket applications. Here's a simple example to get you started:
|
||||
//!
|
||||
//! ```rust
|
||||
//! ```rust,no_run
|
||||
//! #![feature(proc_macro_hygiene)]
|
||||
//!
|
||||
//! #[macro_use] extern crate rocket;
|
||||
|
@ -67,11 +67,9 @@
|
|||
//! "Hello, world!"
|
||||
//! }
|
||||
//!
|
||||
//! #[rocket::main]
|
||||
//! async fn main() {
|
||||
//! # if false { // We don't actually want to launch the server in an example.
|
||||
//! rocket::ignite().mount("/", routes![hello]).launch().await;
|
||||
//! # }
|
||||
//! #[rocket::launch]
|
||||
//! fn rocket() -> rocket::Rocket {
|
||||
//! rocket::ignite().mount("/", routes![hello])
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
|
|
|
@ -21,7 +21,7 @@ use crate::http::Status;
|
|||
/// like to initialize at start-up and later access it in several handlers. The
|
||||
/// following example does just this:
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// use rocket::State;
|
||||
|
@ -42,19 +42,11 @@ use crate::http::Status;
|
|||
/// state.inner().user_val.as_str()
|
||||
/// }
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// let config = MyConfig {
|
||||
/// user_val: "user input".to_string()
|
||||
/// };
|
||||
///
|
||||
/// # if false { // We don't actually want to launch the server in an example.
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite()
|
||||
/// .mount("/", routes![index, raw_config_value])
|
||||
/// .manage(config)
|
||||
/// .launch()
|
||||
/// .await;
|
||||
/// # }
|
||||
/// .manage(MyConfig { user_val: "user input".to_string() })
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
|
|
@ -44,8 +44,8 @@ const FLASH_COOKIE_DELIM: char = ':';
|
|||
///
|
||||
/// # Example
|
||||
///
|
||||
/// The following complete Rocket application illustrates the use of a `Flash`
|
||||
/// message on both the request and response sides.
|
||||
/// The following routes illustrate the use of a `Flash` message on both the
|
||||
/// request and response sides.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
|
@ -68,13 +68,6 @@ const FLASH_COOKIE_DELIM: char = ':';
|
|||
/// flash.map(|msg| format!("{}: {}", msg.name(), msg.msg()))
|
||||
/// .unwrap_or_else(|| "Welcome!".to_string())
|
||||
/// }
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false { // We don't actually want to launch the server in an example.
|
||||
/// rocket::ignite().mount("/", routes![login, index]).launch().await;
|
||||
/// # }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// On the response side (in `login`), a `Flash` error message is set if some
|
||||
|
|
|
@ -647,7 +647,7 @@ impl Rocket {
|
|||
/// generation facilities. Requests to the `/hello/world` URI will be
|
||||
/// dispatched to the `hi` route.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// #
|
||||
|
@ -656,12 +656,9 @@ impl Rocket {
|
|||
/// "Hello!"
|
||||
/// }
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false { // We don't actually want to launch the server in an example.
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite().mount("/hello", routes![hi])
|
||||
/// # .launch().await;
|
||||
/// # }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
@ -704,7 +701,7 @@ impl Rocket {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// use rocket::Request;
|
||||
|
@ -719,13 +716,9 @@ impl Rocket {
|
|||
/// format!("I couldn't find '{}'. Try something else?", req.uri())
|
||||
/// }
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false { // We don't actually want to launch the server in an example.
|
||||
/// rocket::ignite()
|
||||
/// .register(catchers![internal_error, not_found])
|
||||
/// # .launch().await;
|
||||
/// # }
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite().register(catchers![internal_error, not_found])
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
|
@ -750,7 +743,7 @@ impl Rocket {
|
|||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// use rocket::State;
|
||||
|
@ -762,15 +755,11 @@ impl Rocket {
|
|||
/// format!("The stateful value is: {}", state.0)
|
||||
/// }
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false { // We don't actually want to launch the server in an example.
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite()
|
||||
/// .mount("/", routes![index])
|
||||
/// .manage(MyValue(10))
|
||||
/// .launch()
|
||||
/// .await;
|
||||
/// # }
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
|
@ -793,22 +782,18 @@ impl Rocket {
|
|||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// use rocket::Rocket;
|
||||
/// use rocket::fairing::AdHoc;
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false { // We don't actually want to launch the server in an example.
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite()
|
||||
/// .attach(AdHoc::on_launch("Launch Message", |_| {
|
||||
/// println!("Rocket is launching!");
|
||||
/// }))
|
||||
/// .launch()
|
||||
/// .await;
|
||||
/// # }
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
|
@ -1126,22 +1111,18 @@ impl Manifest {
|
|||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// use rocket::Rocket;
|
||||
/// use rocket::fairing::AdHoc;
|
||||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false { // We don't actually want to launch the server in an example.
|
||||
/// #[rocket::launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite()
|
||||
/// .attach(AdHoc::on_launch("Config Printer", |manifest| {
|
||||
/// println!("Rocket launch config: {:?}", manifest.config());
|
||||
/// }))
|
||||
/// .launch()
|
||||
/// .await;
|
||||
/// # }
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
|
|
|
@ -12,7 +12,7 @@ use tokio::sync::mpsc;
|
|||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// #
|
||||
|
@ -26,13 +26,13 @@ use tokio::sync::mpsc;
|
|||
///
|
||||
/// #[rocket::main]
|
||||
/// async fn main() {
|
||||
/// # if false {
|
||||
/// rocket::ignite()
|
||||
/// let result = rocket::ignite()
|
||||
/// .mount("/", routes![shutdown])
|
||||
/// .launch()
|
||||
/// .await
|
||||
/// .expect("server failed unexpectedly");
|
||||
/// # }
|
||||
/// .await;
|
||||
///
|
||||
/// // If the server shut down (by visting `/shutdown`), `result` is `Ok`.
|
||||
/// result.expect("server failed unexpectedly");
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// This example's illustration is the Rocket.toml file.
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket::ignite().launch().await;
|
||||
}
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket { rocket::ignite() }
|
||||
|
|
|
@ -63,10 +63,9 @@ fn not_found(request: &Request<'_>) -> Html<String> {
|
|||
Html(html)
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket::ignite()
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite()
|
||||
.mount("/hello", routes![get_hello, post_hello])
|
||||
.register(catchers![not_found])
|
||||
.launch().await;
|
||||
}
|
||||
|
|
|
@ -5,11 +5,7 @@ use rocket::local::Client;
|
|||
async fn test<H>(method: Method, uri: &str, header: H, status: Status, body: String)
|
||||
where H: Into<Header<'static>>
|
||||
{
|
||||
let rocket = rocket::ignite()
|
||||
.mount("/hello", routes![super::get_hello, super::post_hello])
|
||||
.register(catchers![super::not_found]);
|
||||
|
||||
let client = Client::new(rocket).await.unwrap();
|
||||
let client = Client::new(super::rocket()).await.unwrap();
|
||||
let mut response = client.req(method, uri).header(header).dispatch().await;
|
||||
assert_eq!(response.status(), status);
|
||||
assert_eq!(response.body_string().await, Some(body));
|
||||
|
|
|
@ -34,11 +34,7 @@ fn index(cookies: Cookies<'_>) -> Template {
|
|||
Template::render("index", &context)
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![submit, index]).attach(Template::fairing())
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ fn token(token: State<'_, Token>) -> String {
|
|||
format!("{}", token.0)
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite()
|
||||
.mount("/", routes![hello, token])
|
||||
|
@ -93,8 +94,3 @@ fn rocket() -> rocket::Rocket {
|
|||
})
|
||||
}))
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -41,11 +41,7 @@ fn index() -> Option<NamedFile> {
|
|||
NamedFile::open("static/index.html").ok()
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![index, sink])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -76,12 +76,8 @@ fn user_page(username: &RawStr) -> String {
|
|||
format!("This is {}'s page.", username)
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite()
|
||||
.mount("/", routes![files::index, files::files, user_page, login])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ fn wow_helper(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite()
|
||||
.mount("/", routes![index, hello, about])
|
||||
|
@ -76,8 +77,3 @@ fn rocket() -> rocket::Rocket {
|
|||
engines.handlebars.register_helper("wow", Box::new(wow_helper));
|
||||
}))
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
#![feature(proc_macro_hygiene)]
|
||||
|
||||
#[cfg(test)] mod tests;
|
||||
|
||||
use rocket::{get, routes};
|
||||
|
||||
#[get("/")]
|
||||
#[rocket::get("/")]
|
||||
fn hello() -> &'static str {
|
||||
"Hello, Rust 2018!"
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket::ignite().mount("/", routes![hello]).launch().await;
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", rocket::routes![hello])
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use rocket::{self, routes, local::Client};
|
||||
use rocket::{self, local::Client};
|
||||
|
||||
#[rocket::async_test]
|
||||
async fn hello_world() {
|
||||
let rocket = rocket::ignite().mount("/", routes![super::hello]);
|
||||
let client = Client::new(rocket).await.unwrap();
|
||||
let client = Client::new(super::rocket()).await.unwrap();
|
||||
let mut response = client.get("/").dispatch().await;
|
||||
assert_eq!(response.body_string().await, Some("Hello, Rust 2018!".into()));
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ fn hi(name: String) -> String {
|
|||
name
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket::ignite().mount("/", routes![hello, hi]).launch().await;
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![hello, hi])
|
||||
}
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
use rocket::local::Client;
|
||||
use rocket::http::Status;
|
||||
|
||||
async fn client() -> Client {
|
||||
Client::new(rocket::ignite().mount("/", routes![super::hello, super::hi])).await.unwrap()
|
||||
}
|
||||
|
||||
async fn test(uri: String, expected: String) {
|
||||
let client = client().await;
|
||||
let client = Client::new(super::rocket()).await.unwrap();
|
||||
assert_eq!(client.get(&uri).dispatch().await.body_string().await, Some(expected));
|
||||
}
|
||||
|
||||
async fn test_404(uri: &'static str) {
|
||||
let client = client().await;
|
||||
let client = Client::new(super::rocket()).await.unwrap();
|
||||
assert_eq!(client.get(uri).dispatch().await.status(), Status::NotFound);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(proc_macro_hygiene)]
|
||||
|
||||
#[macro_use] extern crate rocket;
|
||||
|
||||
#[cfg(test)] mod tests;
|
||||
|
@ -9,7 +7,7 @@ fn hello() -> &'static str {
|
|||
"Hello, world!"
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket::ignite().mount("/", routes![hello]).launch().await;
|
||||
#[launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![hello])
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@ use rocket::local::Client;
|
|||
|
||||
#[rocket::async_test]
|
||||
async fn hello_world() {
|
||||
let rocket = rocket::ignite().mount("/", routes![super::hello]);
|
||||
let client = Client::new(rocket).await.unwrap();
|
||||
let client = Client::new(super::rocket()).await.unwrap();
|
||||
let mut response = client.get("/").dispatch().await;
|
||||
assert_eq!(response.body_string().await, Some("Hello, world!".into()));
|
||||
}
|
||||
|
|
|
@ -69,14 +69,10 @@ fn not_found() -> JsonValue {
|
|||
})
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite()
|
||||
.mount("/message", routes![new, update, get])
|
||||
.register(catchers![not_found])
|
||||
.manage(Mutex::new(HashMap::<ID, String>::new()))
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -19,13 +19,9 @@ fn pop(queue: State<'_, LogChannel>) -> Option<String> {
|
|||
queue.0.pop().ok()
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite()
|
||||
.mount("/", routes![push, pop])
|
||||
.manage(LogChannel(SegQueue::new()))
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ impl Handler for CustomHandler {
|
|||
}
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
let always_forward = Route::ranked(1, Get, "/", forward);
|
||||
let hello = Route::ranked(2, Get, "/", hi);
|
||||
|
@ -117,8 +118,3 @@ fn rocket() -> rocket::Rocket {
|
|||
.mount("/custom", CustomHandler::new("some data here"))
|
||||
.register(vec![not_found_catcher])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -23,11 +23,7 @@ fn create(data: MsgPack<Message<'_>>) -> String {
|
|||
data.contents.to_string()
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/message", routes![get, create])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ fn login() -> &'static str {
|
|||
"Hi! That user doesn't exist. Maybe you need to log in?"
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket::ignite().mount("/", routes![root, user, login]).launch().await;
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![root, user, login])
|
||||
}
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
use rocket::local::Client;
|
||||
use rocket::http::Status;
|
||||
|
||||
async fn client() -> Client {
|
||||
let rocket = rocket::ignite()
|
||||
.mount("/", routes![super::root, super::user, super::login]);
|
||||
Client::new(rocket).await.unwrap()
|
||||
|
||||
}
|
||||
|
||||
async fn test_200(uri: &str, expected_body: &str) {
|
||||
let client = client().await;
|
||||
let client = Client::new(super::rocket()).await.unwrap();
|
||||
let mut response = client.get(uri).dispatch().await;
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
assert_eq!(response.body_string().await, Some(expected_body.to_string()));
|
||||
}
|
||||
|
||||
async fn test_303(uri: &str, expected_location: &str) {
|
||||
let client = client().await;
|
||||
let client = Client::new(super::rocket()).await.unwrap();
|
||||
let response = client.get(uri).dispatch().await;
|
||||
let location_headers: Vec<_> = response.headers().get("Location").collect();
|
||||
assert_eq!(response.status(), Status::SeeOther);
|
||||
|
|
|
@ -51,11 +51,7 @@ fn index() -> &'static str {
|
|||
"
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![index, upload, retrieve])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -32,11 +32,7 @@ fn hello_20(person: LenientForm<Person>) -> String {
|
|||
format!("20 years old? Hi, {}!", person.name)
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![hello, hello_20])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ fn hi(name: String, age: &RawStr) -> String {
|
|||
format!("Hi {}! Your age ({}) is kind of funky.", name, age)
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket::ignite().mount("/", routes![hi, hello]).launch().await;
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![hi, hello])
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use rocket::local::Client;
|
||||
|
||||
async fn test(uri: String, expected: String) {
|
||||
let rocket = rocket::ignite().mount("/", routes![super::hello, super::hi]);
|
||||
let client = Client::new(rocket).await.unwrap();
|
||||
let client = Client::new(super::rocket()).await.unwrap();
|
||||
let mut response = client.get(&uri).dispatch().await;
|
||||
assert_eq!(response.body_string().await, Some(expected));
|
||||
}
|
||||
|
|
|
@ -2,15 +2,12 @@
|
|||
|
||||
#[macro_use] extern crate rocket;
|
||||
|
||||
use rusqlite::types::ToSql;
|
||||
|
||||
#[cfg(test)] mod tests;
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
||||
use rocket::{Rocket, State, response::Debug};
|
||||
|
||||
use rusqlite::{Connection, Error};
|
||||
use rusqlite::{Connection, Error, types::ToSql};
|
||||
|
||||
type DbConn = Mutex<Connection>;
|
||||
|
||||
|
@ -35,6 +32,7 @@ fn hello(db_conn: State<'_, DbConn>) -> Result<String, Debug<Error>> {
|
|||
.map_err(Debug)
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> Rocket {
|
||||
// Open a new in-memory SQLite database.
|
||||
let conn = Connection::open_in_memory().expect("in memory db");
|
||||
|
@ -47,8 +45,3 @@ fn rocket() -> Rocket {
|
|||
.manage(Mutex::new(conn))
|
||||
.mount("/", routes![hello])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -17,11 +17,7 @@ fn index() -> &'static str {
|
|||
"Upload your text files by POSTing them to /upload."
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![index, upload])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ fn login() -> &'static str {
|
|||
"Hi! Please log in before continuing."
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket::ignite().mount("/", routes![root, login]).launch().await;
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![root, login])
|
||||
}
|
||||
|
|
|
@ -22,15 +22,11 @@ fn header_count(header_count: HeaderCount) -> String {
|
|||
format!("Your request contained {} headers!", header_count.0)
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![header_count])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use rocket::local::Client;
|
||||
|
|
|
@ -78,13 +78,9 @@ async fn r_async(_g1: Guard3, _g2: Guard4) {
|
|||
// This exists only to run the request guards.
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite()
|
||||
.manage(Atomics::default())
|
||||
.mount("/", routes![r_sync, r_async])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -80,13 +80,9 @@ fn index() -> Redirect {
|
|||
Redirect::to(uri!(login_page))
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite()
|
||||
.attach(Template::fairing())
|
||||
.mount("/", routes![index, user_index, login, logout, login_user, login_page])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -24,13 +24,9 @@ fn count(hit_count: State<'_, HitCount>) -> String {
|
|||
hit_count.0.load(Ordering::Relaxed).to_string()
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite()
|
||||
.mount("/", routes![index, count])
|
||||
.manage(HitCount(AtomicUsize::new(0)))
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -5,11 +5,7 @@ extern crate rocket_contrib;
|
|||
|
||||
use rocket_contrib::serve::StaticFiles;
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", StaticFiles::from("static"))
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -22,11 +22,7 @@ async fn file() -> Option<Stream<File>> {
|
|||
File::open(FILENAME).await.map(Stream::from).ok()
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![root, file])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -35,14 +35,10 @@ fn not_found(req: &Request<'_>) -> Template {
|
|||
Template::render("error/404", &map)
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite()
|
||||
.mount("/", routes![index, get])
|
||||
.attach(Template::fairing())
|
||||
.register(catchers![not_found])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -7,15 +7,11 @@ fn hello() -> &'static str {
|
|||
"Hello, world!"
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![hello])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::rocket;
|
||||
|
|
|
@ -9,7 +9,7 @@ fn hello() -> &'static str {
|
|||
"Hello, world!"
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket::ignite().mount("/", routes![hello]).launch().await;
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![hello])
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@ use rocket::local::Client;
|
|||
|
||||
#[rocket::async_test]
|
||||
async fn hello_world() {
|
||||
let rocket = rocket::ignite().mount("/", routes![super::hello]);
|
||||
let client = Client::new(rocket).await.unwrap();
|
||||
let client = Client::new(super::rocket()).await.unwrap();
|
||||
let mut response = client.get("/").dispatch().await;
|
||||
assert_eq!(response.body_string().await, Some("Hello, world!".into()));
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ async fn run_db_migrations(mut rocket: Rocket) -> Result<Rocket, Rocket> {
|
|||
}
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> Rocket {
|
||||
rocket::ignite()
|
||||
.attach(DbConn::fairing())
|
||||
|
@ -113,8 +114,3 @@ fn rocket() -> Rocket {
|
|||
.mount("/todo", routes![new, toggle, delete])
|
||||
.attach(Template::fairing())
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -33,11 +33,7 @@ fn people(id: Uuid) -> Result<String, String> {
|
|||
.ok_or_else(|| format!("Person not found for UUID: {}", id))?)
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![people])
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let _ = rocket().launch().await;
|
||||
}
|
||||
|
|
|
@ -238,9 +238,9 @@ 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::main]`, but you can still `launch()` a rocket
|
||||
instance on a custom-built `Runtime`.
|
||||
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
|
||||
rocket instance on a custom-built `Runtime`.
|
||||
|
||||
### Cooperative Multitasking
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ fn main() {
|
|||
```
|
||||
|
||||
Notice the `rank` parameters in `user_int` and `user_str`. If we run this
|
||||
application with the routes mounted at the root path, as is done in `main`
|
||||
application with the routes mounted at the root path, as is done in `rocket()`
|
||||
above, requests to `/user/<id>` (such as `/user/123`, `/user/Bob`, and so on)
|
||||
will be routed as follows:
|
||||
|
||||
|
|
|
@ -47,8 +47,6 @@ margin = 9
|
|||
[[sections]]
|
||||
title = "Hello, Rocket!"
|
||||
code = '''
|
||||
#![feature(proc_macro_hygiene)]
|
||||
|
||||
#[macro_use] extern crate rocket;
|
||||
|
||||
#[get("/hello/<name>/<age>")]
|
||||
|
@ -56,8 +54,9 @@ code = '''
|
|||
format!("Hello, {} year old named {}!", age, name)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
rocket::ignite().mount("/", routes![hello]).launch();
|
||||
#[launch]
|
||||
fn rocket() -> rocket::Rocket {
|
||||
rocket::ignite().mount("/", routes![hello])
|
||||
}
|
||||
'''
|
||||
text = '''
|
||||
|
|
|
@ -136,22 +136,23 @@ fn not_found() -> T { ... }
|
|||
name = "Launching"
|
||||
content = '''
|
||||
Launching a Rocket application is the funnest part! For Rocket to begin
|
||||
dispatching requests to routes, the routes need to be _mounted_. After mounting,
|
||||
the application needs to be _launched_. These two steps, usually done in `main`,
|
||||
look like:
|
||||
dispatching requests to routes, routes need to be _mounted_. After mounting, the
|
||||
application needs to be _launched_. These two steps, usually done in a `rocket`
|
||||
function, look like:
|
||||
|
||||
```rust
|
||||
rocket::ignite()
|
||||
.mount("/base", routes![index, another])
|
||||
.launch();
|
||||
#[launch]
|
||||
fn rocket() -> Rocket {
|
||||
rocket::ignite().mount("/base", routes![index, another])
|
||||
}
|
||||
```
|
||||
|
||||
The `mount` call takes a base path and a set of routes via the `routes!` macro.
|
||||
The base path (`/base` above) is prepended to the path of every route in the
|
||||
list. This effectively namespaces the routes, allowing for easier composition.
|
||||
|
||||
The `launch` call starts the server. In development, Rocket prints useful
|
||||
information to the console to let you know everything is okay.
|
||||
list. This namespaces the routes, allowing for composition. The `#[launch]`
|
||||
attribute creates a `main` function that starts the server. In development,
|
||||
Rocket prints useful information to the console to let you know everything is
|
||||
okay.
|
||||
|
||||
```sh
|
||||
🚀 Rocket has launched from http://localhost:8000
|
||||
|
|
Loading…
Reference in New Issue