mirror of https://github.com/rwf2/Rocket.git
Remove 'rocket::inspect()', 'Cargo'.
This commit reverts most ofdea940c7
andd89c7024
. The "fix" is to run attach fairings on a new thread. If a runtime is already running, it is used. Otherwise, the future is executed in a single-threaded executor.
This commit is contained in:
parent
491b229582
commit
ec9b5816a8
|
@ -72,10 +72,12 @@ pub fn database_attr(attr: TokenStream, input: TokenStream) -> Result<TokenStrea
|
|||
let request = quote!(::rocket::request);
|
||||
|
||||
let request_guard_type = quote_spanned! { span =>
|
||||
/// The request guard type.
|
||||
#vis struct #guard_type(#databases::Connection<Self, #conn_type>);
|
||||
};
|
||||
|
||||
let pool = quote_spanned!(span => #databases::ConnectionPool<Self, #conn_type>);
|
||||
let conn = quote_spanned!(span => #databases::Connection<Self, #conn_type>);
|
||||
|
||||
Ok(quote! {
|
||||
#request_guard_type
|
||||
|
||||
|
@ -83,26 +85,26 @@ pub fn database_attr(attr: TokenStream, input: TokenStream) -> Result<TokenStrea
|
|||
/// Returns a fairing that initializes the associated database
|
||||
/// connection pool.
|
||||
pub fn fairing() -> impl ::rocket::fairing::Fairing {
|
||||
<#databases::ConnectionPool<Self, #conn_type>>::fairing(#fairing_name, #name)
|
||||
<#pool>::fairing(#fairing_name, #name)
|
||||
}
|
||||
|
||||
/// Retrieves a connection of type `Self` from the `rocket`
|
||||
/// instance. Returns `Some` as long as `Self::fairing()` has been
|
||||
/// attached.
|
||||
pub async fn get_one(cargo: &::rocket::Cargo) -> Option<Self> {
|
||||
<#databases::ConnectionPool<Self, #conn_type>>::get_one(cargo).await.map(Self)
|
||||
pub async fn get_one(__rocket: &::rocket::Rocket) -> Option<Self> {
|
||||
<#pool>::get_one(&__rocket).await.map(Self)
|
||||
}
|
||||
|
||||
/// Runs the provided closure on a thread from a threadpool. The
|
||||
/// closure will be passed an `&mut r2d2::PooledConnection`.
|
||||
/// `.await`ing the return value of this function yields the value
|
||||
/// returned by the closure.
|
||||
pub async fn run<F, R>(&self, f: F) -> R
|
||||
pub async fn run<F, R>(&self, __f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut #conn_type) -> R + Send + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
self.0.run(f).await
|
||||
self.0.run(__f).await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,8 +112,8 @@ pub fn database_attr(attr: TokenStream, input: TokenStream) -> Result<TokenStrea
|
|||
impl<'a, 'r> #request::FromRequest<'a, 'r> for #guard_type {
|
||||
type Error = ();
|
||||
|
||||
async fn from_request(req: &'a #request::Request<'r>) -> #request::Outcome<Self, ()> {
|
||||
<#databases::Connection<Self, #conn_type>>::from_request(req).await.map(Self)
|
||||
async fn from_request(__r: &'a #request::Request<'r>) -> #request::Outcome<Self, ()> {
|
||||
<#conn>::from_request(__r).await.map(Self)
|
||||
}
|
||||
}
|
||||
}.into())
|
||||
|
|
|
@ -198,7 +198,7 @@
|
|||
//! Returns a fairing that initializes the associated database connection
|
||||
//! pool.
|
||||
//!
|
||||
//! * `async fn get_one(&Cargo) -> Option<Self>`
|
||||
//! * `async fn get_one(&Rocket) -> Option<Self>`
|
||||
//!
|
||||
//! Retrieves a connection wrapper from the configured pool. Returns `Some`
|
||||
//! as long as `Self::fairing()` has been attached.
|
||||
|
@ -405,7 +405,7 @@ use self::r2d2::ManageConnection;
|
|||
/// timeout = 5
|
||||
/// ```
|
||||
///
|
||||
/// ...`Config::from("my_database", cargo)` would return the following struct:
|
||||
/// ...`Config::from("my_database", rocket)` would return the following struct:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use rocket_contrib::databases::Config;
|
||||
|
@ -455,32 +455,29 @@ impl Config {
|
|||
///
|
||||
/// use rocket_contrib::databases::Config;
|
||||
///
|
||||
/// fn pool(cargo: &rocket::Cargo) {
|
||||
/// let config = Config::from("my_db", cargo).unwrap();
|
||||
/// fn pool(rocket: &rocket::Rocket) {
|
||||
/// let config = Config::from("my_db", rocket).unwrap();
|
||||
/// assert_eq!(config.url, "db/db.sqlite");
|
||||
/// assert_eq!(config.pool_size, 25);
|
||||
///
|
||||
/// let config = Config::from("my_other_db", cargo).unwrap();
|
||||
/// let config = Config::from("my_other_db", rocket).unwrap();
|
||||
/// assert_eq!(config.url, "mysql://root:root@localhost/database");
|
||||
/// assert_eq!(config.pool_size, cargo.config().workers as u32);
|
||||
/// assert_eq!(config.pool_size, rocket.config().workers as u32);
|
||||
///
|
||||
/// let config = Config::from("unknown_db", cargo);
|
||||
/// let config = Config::from("unknown_db", rocket);
|
||||
/// assert!(config.is_err())
|
||||
/// }
|
||||
/// #
|
||||
/// # rocket::async_test(async {
|
||||
/// # let config = Figment::from(rocket::Config::default()).merge(toml);
|
||||
/// # let mut rocket = rocket::custom(config);
|
||||
/// # let cargo = rocket.inspect().await;
|
||||
/// # pool(cargo);
|
||||
/// # });
|
||||
/// # let rocket = rocket::custom(config);
|
||||
/// # pool(&rocket);
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn from(db_name: &str, cargo: &rocket::Cargo) -> Result<Config, figment::Error> {
|
||||
pub fn from(db_name: &str, rocket: &rocket::Rocket) -> Result<Config, figment::Error> {
|
||||
let db_key = format!("databases.{}", db_name);
|
||||
let key = |name: &str| format!("{}.{}", db_key, name);
|
||||
Figment::from(cargo.figment())
|
||||
.merge(Serialized::default(&key("pool_size"), cargo.config().workers))
|
||||
Figment::from(rocket.figment())
|
||||
.merge(Serialized::default(&key("pool_size"), rocket.config().workers))
|
||||
.merge(Serialized::default(&key("timeout"), 5))
|
||||
.extract_inner::<Self>(&db_key)
|
||||
}
|
||||
|
@ -578,8 +575,8 @@ impl<T> From<r2d2::Error> for Error<T> {
|
|||
/// type Manager = foo::ConnectionManager;
|
||||
/// type Error = foo::Error;
|
||||
///
|
||||
/// fn pool(db_name: &str, cargo: &rocket::Cargo) -> PoolResult<Self> {
|
||||
/// let config = Config::from(db_name, cargo)?;
|
||||
/// fn pool(db_name: &str, rocket: &rocket::Rocket) -> PoolResult<Self> {
|
||||
/// let config = Config::from(db_name, rocket)?;
|
||||
/// let manager = foo::ConnectionManager::new(&config.url).map_err(Error::Custom)?;
|
||||
/// Ok(r2d2::Pool::builder().max_size(config.pool_size).build(manager)?)
|
||||
/// }
|
||||
|
@ -607,7 +604,7 @@ pub trait Poolable: Send + Sized + 'static {
|
|||
|
||||
/// Creates an `r2d2` connection pool for `Manager::Connection`, returning
|
||||
/// the pool on success.
|
||||
fn pool(db_name: &str, cargo: &rocket::Cargo) -> PoolResult<Self>;
|
||||
fn pool(db_name: &str, rocket: &rocket::Rocket) -> PoolResult<Self>;
|
||||
}
|
||||
|
||||
/// A type alias for the return type of [`Poolable::pool()`].
|
||||
|
@ -619,8 +616,8 @@ impl Poolable for diesel::SqliteConnection {
|
|||
type Manager = diesel::r2d2::ConnectionManager<diesel::SqliteConnection>;
|
||||
type Error = std::convert::Infallible;
|
||||
|
||||
fn pool(db_name: &str, cargo: &rocket::Cargo) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, cargo)?;
|
||||
fn pool(db_name: &str, rocket: &rocket::Rocket) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, rocket)?;
|
||||
let manager = diesel::r2d2::ConnectionManager::new(&config.url);
|
||||
Ok(r2d2::Pool::builder().max_size(config.pool_size).build(manager)?)
|
||||
}
|
||||
|
@ -631,8 +628,8 @@ impl Poolable for diesel::PgConnection {
|
|||
type Manager = diesel::r2d2::ConnectionManager<diesel::PgConnection>;
|
||||
type Error = std::convert::Infallible;
|
||||
|
||||
fn pool(db_name: &str, cargo: &rocket::Cargo) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, cargo)?;
|
||||
fn pool(db_name: &str, rocket: &rocket::Rocket) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, rocket)?;
|
||||
let manager = diesel::r2d2::ConnectionManager::new(&config.url);
|
||||
Ok(r2d2::Pool::builder().max_size(config.pool_size).build(manager)?)
|
||||
}
|
||||
|
@ -643,8 +640,8 @@ impl Poolable for diesel::MysqlConnection {
|
|||
type Manager = diesel::r2d2::ConnectionManager<diesel::MysqlConnection>;
|
||||
type Error = std::convert::Infallible;
|
||||
|
||||
fn pool(db_name: &str, cargo: &rocket::Cargo) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, cargo)?;
|
||||
fn pool(db_name: &str, rocket: &rocket::Rocket) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, rocket)?;
|
||||
let manager = diesel::r2d2::ConnectionManager::new(&config.url);
|
||||
Ok(r2d2::Pool::builder().max_size(config.pool_size).build(manager)?)
|
||||
}
|
||||
|
@ -656,8 +653,8 @@ impl Poolable for postgres::Client {
|
|||
type Manager = r2d2_postgres::PostgresConnectionManager<postgres::tls::NoTls>;
|
||||
type Error = postgres::Error;
|
||||
|
||||
fn pool(db_name: &str, cargo: &rocket::Cargo) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, cargo)?;
|
||||
fn pool(db_name: &str, rocket: &rocket::Rocket) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, rocket)?;
|
||||
let url = config.url.parse().map_err(Error::Custom)?;
|
||||
let manager = r2d2_postgres::PostgresConnectionManager::new(url, postgres::tls::NoTls);
|
||||
Ok(r2d2::Pool::builder().max_size(config.pool_size).build(manager)?)
|
||||
|
@ -669,8 +666,8 @@ impl Poolable for mysql::Conn {
|
|||
type Manager = r2d2_mysql::MysqlConnectionManager;
|
||||
type Error = std::convert::Infallible;
|
||||
|
||||
fn pool(db_name: &str, cargo: &rocket::Cargo) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, cargo)?;
|
||||
fn pool(db_name: &str, rocket: &rocket::Rocket) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, rocket)?;
|
||||
let opts = mysql::OptsBuilder::from_opts(&config.url);
|
||||
let manager = r2d2_mysql::MysqlConnectionManager::new(opts);
|
||||
Ok(r2d2::Pool::builder().max_size(config.pool_size).build(manager)?)
|
||||
|
@ -682,8 +679,8 @@ impl Poolable for rusqlite::Connection {
|
|||
type Manager = r2d2_sqlite::SqliteConnectionManager;
|
||||
type Error = std::convert::Infallible;
|
||||
|
||||
fn pool(db_name: &str, cargo: &rocket::Cargo) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, cargo)?;
|
||||
fn pool(db_name: &str, rocket: &rocket::Rocket) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, rocket)?;
|
||||
let manager = r2d2_sqlite::SqliteConnectionManager::file(&*config.url);
|
||||
Ok(r2d2::Pool::builder().max_size(config.pool_size).build(manager)?)
|
||||
}
|
||||
|
@ -695,8 +692,8 @@ impl Poolable for memcache::Client {
|
|||
// Unused, but we might want it in the future without a breaking change.
|
||||
type Error = memcache::MemcacheError;
|
||||
|
||||
fn pool(db_name: &str, cargo: &rocket::Cargo) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, cargo)?;
|
||||
fn pool(db_name: &str, rocket: &rocket::Rocket) -> PoolResult<Self> {
|
||||
let config = Config::from(db_name, rocket)?;
|
||||
let manager = r2d2_memcache::MemcacheConnectionManager::new(&*config.url);
|
||||
Ok(r2d2::Pool::builder().max_size(config.pool_size).build(manager)?)
|
||||
}
|
||||
|
@ -759,15 +756,14 @@ macro_rules! dberr {
|
|||
|
||||
impl<K: 'static, C: Poolable> ConnectionPool<K, C> {
|
||||
pub fn fairing(fairing_name: &'static str, db: &'static str) -> impl Fairing {
|
||||
AdHoc::on_attach(fairing_name, move |mut rocket| async move {
|
||||
let cargo = rocket.inspect().await;
|
||||
let config = match Config::from(db, cargo) {
|
||||
AdHoc::on_attach(fairing_name, move |rocket| async move {
|
||||
let config = match Config::from(db, &rocket) {
|
||||
Ok(config) => config,
|
||||
Err(e) => dberr!("config", db, "{}", e, rocket),
|
||||
};
|
||||
|
||||
let pool_size = config.pool_size;
|
||||
match C::pool(db, cargo) {
|
||||
match C::pool(db, &rocket) {
|
||||
Ok(pool) => Ok(rocket.manage(ConnectionPool::<K, C> {
|
||||
pool, config,
|
||||
semaphore: Arc::new(Semaphore::new(pool_size as usize)),
|
||||
|
@ -805,16 +801,16 @@ impl<K: 'static, C: Poolable> ConnectionPool<K, C> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn get_one(cargo: &rocket::Cargo) -> Option<Connection<K, C>> {
|
||||
match cargo.state::<Self>() {
|
||||
pub async fn get_one(rocket: &rocket::Rocket) -> Option<Connection<K, C>> {
|
||||
match rocket.state::<Self>() {
|
||||
Some(pool) => pool.get().await.ok(),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn get_pool(cargo: &rocket::Cargo) -> Option<Self> {
|
||||
cargo.state::<Self>().map(|pool| pool.clone())
|
||||
pub async fn get_pool(rocket: &rocket::Rocket) -> Option<Self> {
|
||||
rocket.state::<Self>().map(|pool| pool.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||
|
||||
use rocket::http::uncased::UncasedStr;
|
||||
use rocket::fairing::{Fairing, Info, Kind};
|
||||
use rocket::{Cargo, Request, Response};
|
||||
use rocket::{Rocket, Request, Response};
|
||||
|
||||
use crate::helmet::*;
|
||||
|
||||
|
@ -201,9 +201,9 @@ impl Fairing for SpaceHelmet {
|
|||
self.apply(res);
|
||||
}
|
||||
|
||||
fn on_launch(&self, cargo: &Cargo) {
|
||||
if cargo.config().tls_enabled()
|
||||
&& cargo.figment().profile() != rocket::Config::DEBUG_PROFILE
|
||||
fn on_launch(&self, rocket: &Rocket) {
|
||||
if rocket.config().tls_enabled()
|
||||
&& rocket.figment().profile() != rocket::Config::DEBUG_PROFILE
|
||||
&& !self.is_enabled::<Hsts>()
|
||||
{
|
||||
warn_!("Space Helmet: deploying with TLS without enabling HSTS.");
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
//! * [${database}_pool](databases) - Database Configuration and Pooling
|
||||
//! * [helmet](helmet) - Fairing for Security and Privacy Headers
|
||||
//!
|
||||
//! The recommend way to include features from this crate via Cargo in your
|
||||
//! The recommend way to include features from this crate via Rocket in your
|
||||
//! project is by adding a `[dependencies.rocket_contrib]` section to your
|
||||
//! `Cargo.toml` file, setting `default-features` to false, and specifying
|
||||
//! features manually. For example, to use the JSON module, you would add:
|
||||
|
|
|
@ -187,7 +187,7 @@ impl std::ops::BitOr for Options {
|
|||
/// ## Relative Paths
|
||||
///
|
||||
/// In the example above, `/static` is an absolute path. If your static files
|
||||
/// are stored relative to your crate and your project is managed by Cargo, use
|
||||
/// are stored relative to your crate and your project is managed by Rocket, use
|
||||
/// the [`crate_relative!`] macro to obtain a path that is relative to your
|
||||
/// crate's root. For example, to serve files in the `static` subdirectory of
|
||||
/// your crate at `/`, you might write:
|
||||
|
|
|
@ -138,10 +138,10 @@ impl Fairing for TemplateFairing {
|
|||
/// The user's callback, if any was supplied, is called to customize the
|
||||
/// template engines. In debug mode, the `ContextManager::new` method
|
||||
/// initializes a directory watcher for auto-reloading of templates.
|
||||
async fn on_attach(&self, mut rocket: Rocket) -> Result<Rocket, Rocket> {
|
||||
async fn on_attach(&self, rocket: Rocket) -> Result<Rocket, Rocket> {
|
||||
use rocket::figment::{Source, value::magic::RelativePathBuf};
|
||||
|
||||
let configured_dir = rocket.figment().await
|
||||
let configured_dir = rocket.figment()
|
||||
.extract_inner::<RelativePathBuf>("template_dir")
|
||||
.map(|path| path.relative());
|
||||
|
||||
|
@ -173,7 +173,7 @@ impl Fairing for TemplateFairing {
|
|||
|
||||
#[cfg(debug_assertions)]
|
||||
async fn on_request(&self, req: &mut rocket::Request<'_>, _data: &mut rocket::Data) {
|
||||
let cm = req.guard::<rocket::State<'_, ContextManager>>().await
|
||||
let cm = req.managed_state::<ContextManager>()
|
||||
.expect("Template ContextManager registered in on_attach");
|
||||
|
||||
cm.reload_if_needed(&*self.custom_callback);
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
//! can be any type that implements [`Serialize`] from [`serde`] and would
|
||||
//! serialize to an `Object` value.
|
||||
//!
|
||||
//! In debug mode (without the `--release` flag passed to `cargo`), templates
|
||||
//! In debug mode (without the `--release` flag passed to `rocket`), templates
|
||||
//! will be automatically reloaded from disk if any changes have been made to
|
||||
//! the templates directory since the previous request. In release builds,
|
||||
//! template reloading is disabled to improve performance and cannot be enabled.
|
||||
|
@ -140,7 +140,7 @@ use serde_json::{Value, to_value};
|
|||
use std::borrow::Cow;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use rocket::Cargo;
|
||||
use rocket::Rocket;
|
||||
use rocket::request::Request;
|
||||
use rocket::fairing::Fairing;
|
||||
use rocket::response::{self, Content, Responder};
|
||||
|
@ -337,14 +337,14 @@ impl Template {
|
|||
///
|
||||
/// # context.insert("test", "test");
|
||||
/// # #[allow(unused_variables)]
|
||||
/// let template = Template::show(client.cargo(), "index", context);
|
||||
/// let template = Template::show(client.rocket(), "index", context);
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn show<S, C>(cargo: &Cargo, name: S, context: C) -> Option<String>
|
||||
pub fn show<S, C>(rocket: &Rocket, name: S, context: C) -> Option<String>
|
||||
where S: Into<Cow<'static, str>>, C: Serialize
|
||||
{
|
||||
let ctxt = cargo.state::<ContextManager>().map(ContextManager::context).or_else(|| {
|
||||
let ctxt = rocket.state::<ContextManager>().map(ContextManager::context).or_else(|| {
|
||||
warn!("Uninitialized template context: missing fairing.");
|
||||
info!("To use templates, you must attach `Template::fairing()`.");
|
||||
info!("See the `Template` documentation for more information.");
|
||||
|
|
|
@ -33,18 +33,21 @@ mod rusqlite_integration_test {
|
|||
.merge(("databases", map!["test_db" => &options]))
|
||||
.merge(("databases", map!["test_db_2" => &options]));
|
||||
|
||||
let mut rocket = rocket::custom(config)
|
||||
let rocket = rocket::custom(config)
|
||||
.attach(SqliteDb::fairing())
|
||||
.attach(SqliteDb2::fairing());
|
||||
|
||||
let conn = SqliteDb::get_one(rocket.inspect().await).await
|
||||
let conn = SqliteDb::get_one(&rocket).await
|
||||
.expect("unable to get connection");
|
||||
|
||||
// Rusqlite's `transaction()` method takes `&mut self`; this tests that
|
||||
// the &mut method can be called inside the closure passed to `run()`.
|
||||
conn.run(|conn| {
|
||||
let tx = conn.transaction().unwrap();
|
||||
let _: i32 = tx.query_row("SELECT 1", &[] as &[&dyn ToSql], |row| row.get(0)).expect("get row");
|
||||
let _: i32 = tx.query_row(
|
||||
"SELECT 1", &[] as &[&dyn ToSql], |row| row.get(0)
|
||||
).expect("get row");
|
||||
|
||||
tx.commit().expect("committed transaction");
|
||||
}).await;
|
||||
}
|
||||
|
|
|
@ -44,20 +44,19 @@ mod templates_tests {
|
|||
const ESCAPED_EXPECTED: &'static str
|
||||
= "\nh_start\ntitle: _test_\nh_end\n\n\n<script />\n\nfoot\n";
|
||||
|
||||
#[rocket::async_test]
|
||||
async fn test_tera_templates() {
|
||||
let mut rocket = rocket();
|
||||
let cargo = rocket.inspect().await;
|
||||
#[test]
|
||||
fn test_tera_templates() {
|
||||
let rocket = rocket();
|
||||
let mut map = HashMap::new();
|
||||
map.insert("title", "_test_");
|
||||
map.insert("content", "<script />");
|
||||
|
||||
// Test with a txt file, which shouldn't escape.
|
||||
let template = Template::show(cargo, "tera/txt_test", &map);
|
||||
let template = Template::show(&rocket, "tera/txt_test", &map);
|
||||
assert_eq!(template, Some(UNESCAPED_EXPECTED.into()));
|
||||
|
||||
// Now with an HTML file, which should.
|
||||
let template = Template::show(cargo, "tera/html_test", &map);
|
||||
let template = Template::show(&rocket, "tera/html_test", &map);
|
||||
assert_eq!(template, Some(ESCAPED_EXPECTED.into()));
|
||||
}
|
||||
|
||||
|
@ -89,16 +88,15 @@ mod templates_tests {
|
|||
const EXPECTED: &'static str
|
||||
= "Hello _test_!\n\n<main> <script /> hi </main>\nDone.\n\n";
|
||||
|
||||
#[rocket::async_test]
|
||||
async fn test_handlebars_templates() {
|
||||
let mut rocket = rocket();
|
||||
let cargo = rocket.inspect().await;
|
||||
#[test]
|
||||
fn test_handlebars_templates() {
|
||||
let rocket = rocket();
|
||||
let mut map = HashMap::new();
|
||||
map.insert("title", "_test_");
|
||||
map.insert("content", "<script /> hi");
|
||||
|
||||
// Test with a txt file, which shouldn't escape.
|
||||
let template = Template::show(cargo, "hbs/test", &map);
|
||||
let template = Template::show(&rocket, "hbs/test", &map);
|
||||
assert_eq!(template, Some(EXPECTED.into()));
|
||||
}
|
||||
|
||||
|
@ -148,7 +146,7 @@ mod templates_tests {
|
|||
}
|
||||
|
||||
// verify that the initial content is correct
|
||||
let initial_rendered = Template::show(client.cargo(), RELOAD_TEMPLATE, ());
|
||||
let initial_rendered = Template::show(client.rocket(), RELOAD_TEMPLATE, ());
|
||||
assert_eq!(initial_rendered, Some(INITIAL_TEXT.into()));
|
||||
|
||||
// write a change to the file
|
||||
|
@ -159,7 +157,7 @@ mod templates_tests {
|
|||
client.get("/").dispatch();
|
||||
|
||||
// if the new content is correct, we are done
|
||||
let new_rendered = Template::show(client.cargo(), RELOAD_TEMPLATE, ());
|
||||
let new_rendered = Template::show(client.rocket(), RELOAD_TEMPLATE, ());
|
||||
if new_rendered == Some(NEW_TEXT.into()) {
|
||||
write_file(&reload_path, INITIAL_TEXT);
|
||||
return;
|
||||
|
|
|
@ -92,7 +92,7 @@ fn bench_simple_routing(b: &mut Bencher) {
|
|||
|
||||
// Hold all of the requests we're going to make during the benchmark.
|
||||
let mut requests = vec![];
|
||||
for route in client.cargo().routes() {
|
||||
for route in client.rocket().routes() {
|
||||
let request = client.req(route.method, route.uri.path());
|
||||
requests.push(request);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
//! ## Extracting Configuration Parameters
|
||||
//!
|
||||
//! Rocket exposes the active [`Figment`] via [`Rocket::figment()`] and
|
||||
//! [`Cargo::figment()`]. Any value that implements [`Deserialize`] can be
|
||||
//! [`Rocket::figment()`]. Any value that implements [`Deserialize`] can be
|
||||
//! extracted from the figment:
|
||||
//!
|
||||
//! ```rust
|
||||
|
@ -27,7 +27,7 @@
|
|||
//!
|
||||
//! [`Figment`]: figment::Figment
|
||||
//! [`Rocket::figment()`]: crate::Rocket::figment()
|
||||
//! [`Cargo::figment()`]: crate::Cargo::figment()
|
||||
//! [`Rocket::figment()`]: crate::Rocket::figment()
|
||||
//! [`Deserialize`]: serde::Deserialize
|
||||
//!
|
||||
//! ## Custom Providers
|
||||
|
|
|
@ -130,7 +130,7 @@ impl Data {
|
|||
/// In a fairing:
|
||||
///
|
||||
/// ```
|
||||
/// use rocket::{Cargo, Rocket, Request, Data, Response};
|
||||
/// use rocket::{Rocket, Request, Data, Response};
|
||||
/// use rocket::fairing::{Fairing, Info, Kind};
|
||||
/// # struct MyType;
|
||||
///
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::sync::Mutex;
|
|||
|
||||
use futures::future::{Future, BoxFuture};
|
||||
|
||||
use crate::{Cargo, Rocket, Request, Response, Data};
|
||||
use crate::{Rocket, Request, Response, Data};
|
||||
use crate::fairing::{Fairing, Kind, Info};
|
||||
|
||||
/// A ad-hoc fairing that can be created from a function or closure.
|
||||
|
@ -67,7 +67,7 @@ enum AdHocKind {
|
|||
-> BoxFuture<'static, Result<Rocket, Rocket>> + Send + 'static>>>),
|
||||
|
||||
/// An ad-hoc **launch** fairing. Called just before Rocket launches.
|
||||
Launch(Mutex<Option<Box<dyn FnOnce(&Cargo) + Send + 'static>>>),
|
||||
Launch(Mutex<Option<Box<dyn FnOnce(&Rocket) + Send + 'static>>>),
|
||||
|
||||
/// An ad-hoc **request** fairing. Called when a request is received.
|
||||
Request(Box<dyn for<'a> Fn(&'a mut Request<'_>, &'a Data)
|
||||
|
@ -124,9 +124,8 @@ impl AdHoc {
|
|||
pub fn config<'de, T>() -> AdHoc
|
||||
where T: serde::Deserialize<'de> + Send + Sync + 'static
|
||||
{
|
||||
AdHoc::on_attach(std::any::type_name::<T>(), |mut rocket| async {
|
||||
let figment = rocket.figment().await;
|
||||
let app_config = match figment.extract::<T>() {
|
||||
AdHoc::on_attach(std::any::type_name::<T>(), |rocket| async {
|
||||
let app_config = match rocket.figment().extract::<T>() {
|
||||
Ok(config) => config,
|
||||
Err(e) => {
|
||||
crate::config::pretty_print_error(e);
|
||||
|
@ -152,7 +151,7 @@ impl AdHoc {
|
|||
/// });
|
||||
/// ```
|
||||
pub fn on_launch<F: Send + 'static>(name: &'static str, f: F) -> AdHoc
|
||||
where F: FnOnce(&Cargo)
|
||||
where F: FnOnce(&Rocket)
|
||||
{
|
||||
AdHoc { name, kind: AdHocKind::Launch(Mutex::new(Some(Box::new(f)))) }
|
||||
}
|
||||
|
@ -240,7 +239,7 @@ impl Fairing for AdHoc {
|
|||
}
|
||||
}
|
||||
|
||||
fn on_launch(&self, state: &Cargo) {
|
||||
fn on_launch(&self, state: &Rocket) {
|
||||
if let AdHocKind::Launch(ref mutex) = self.kind {
|
||||
let mut opt = mutex.lock().expect("AdHoc::Launch lock");
|
||||
let f = opt.take().expect("internal error: `on_launch` one-call invariant broken");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Cargo, Rocket, Request, Response, Data};
|
||||
use crate::{Rocket, Request, Response, Data};
|
||||
use crate::fairing::{Fairing, Kind};
|
||||
use crate::logger::PaintExt;
|
||||
|
||||
|
@ -52,9 +52,9 @@ impl Fairings {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn handle_launch(&self, cargo: &Cargo) {
|
||||
pub fn handle_launch(&self, rocket: &Rocket) {
|
||||
for &i in &self.launch {
|
||||
self.all_fairings[i].on_launch(cargo);
|
||||
self.all_fairings[i].on_launch(rocket);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
//! of other `Fairings` are not jeopardized. For instance, unless it is made
|
||||
//! abundantly clear, a fairing should not rewrite every request.
|
||||
|
||||
use crate::{Cargo, Rocket, Request, Response, Data};
|
||||
use crate::{Rocket, Request, Response, Data};
|
||||
|
||||
mod fairings;
|
||||
mod ad_hoc;
|
||||
|
@ -196,7 +196,7 @@ pub use self::info_kind::{Info, Kind};
|
|||
/// decorated with an attribute of `#[rocket::async_trait]`:
|
||||
///
|
||||
/// ```rust
|
||||
/// use rocket::{Cargo, Rocket, Request, Data, Response};
|
||||
/// use rocket::{Rocket, Request, Data, Response};
|
||||
/// use rocket::fairing::{Fairing, Info, Kind};
|
||||
///
|
||||
/// # struct MyType;
|
||||
|
@ -212,7 +212,7 @@ pub use self::info_kind::{Info, Kind};
|
|||
/// # unimplemented!()
|
||||
/// }
|
||||
///
|
||||
/// fn on_launch(&self, cargo: &Cargo) {
|
||||
/// fn on_launch(&self, rocket: &Rocket) {
|
||||
/// /* ... */
|
||||
/// # unimplemented!()
|
||||
/// }
|
||||
|
@ -420,14 +420,14 @@ pub trait Fairing: Send + Sync + 'static {
|
|||
///
|
||||
/// This method is called just prior to launching the application if
|
||||
/// `Kind::Launch` is in the `kind` field of the `Info` structure for this
|
||||
/// fairing. The `Cargo` parameter corresponds to the application that
|
||||
/// fairing. The `Rocket` parameter corresponds to the application that
|
||||
/// will be launched.
|
||||
///
|
||||
/// ## Default Implementation
|
||||
///
|
||||
/// The default implementation of this method does nothing.
|
||||
#[allow(unused_variables)]
|
||||
fn on_launch(&self, cargo: &Cargo) {}
|
||||
fn on_launch(&self, rocket: &Rocket) {}
|
||||
|
||||
/// The request callback.
|
||||
///
|
||||
|
@ -469,8 +469,8 @@ impl<T: Fairing> Fairing for std::sync::Arc<T> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn on_launch(&self, cargo: &Cargo) {
|
||||
(self as &T).on_launch(cargo)
|
||||
fn on_launch(&self, rocket: &Rocket) {
|
||||
(self as &T).on_launch(rocket)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! Depend on `rocket` in `Cargo.toml`:
|
||||
//! Depend on `rocket` in `Rocket.toml`:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
|
@ -67,7 +67,7 @@
|
|||
//! * **secrets:** Enables support for [private cookies].
|
||||
//! * **tls:** Enables support for [TLS].
|
||||
//!
|
||||
//! The features can be enabled in `Cargo.toml`:
|
||||
//! The features can be enabled in `Rocket.toml`:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
|
@ -146,7 +146,7 @@ mod ext;
|
|||
#[doc(inline)] pub use crate::catcher::Catcher;
|
||||
pub use crate::router::Route;
|
||||
pub use crate::request::{Request, State};
|
||||
pub use crate::rocket::{Cargo, Rocket};
|
||||
pub use crate::rocket::Rocket;
|
||||
pub use crate::shutdown::Shutdown;
|
||||
|
||||
/// Alias to [`Rocket::ignite()`] Creates a new instance of `Rocket`.
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::borrow::Cow;
|
|||
use parking_lot::RwLock;
|
||||
|
||||
use crate::local::asynchronous::{LocalRequest, LocalResponse};
|
||||
use crate::rocket::{Rocket, Cargo};
|
||||
use crate::rocket::Rocket;
|
||||
use crate::http::{private::cookie, Method};
|
||||
use crate::error::Error;
|
||||
|
||||
|
@ -48,7 +48,7 @@ use crate::error::Error;
|
|||
/// # });
|
||||
/// ```
|
||||
pub struct Client {
|
||||
cargo: Cargo,
|
||||
rocket: Rocket,
|
||||
cookies: RwLock<cookie::CookieJar>,
|
||||
pub(in super) tracked: bool,
|
||||
}
|
||||
|
@ -59,9 +59,8 @@ impl Client {
|
|||
tracked: bool
|
||||
) -> Result<Client, Error> {
|
||||
rocket.prelaunch_check().await?;
|
||||
let cargo = rocket.into_cargo().await;
|
||||
let cookies = RwLock::new(cookie::CookieJar::new());
|
||||
Ok(Client { cargo, tracked, cookies })
|
||||
Ok(Client { rocket, tracked, cookies })
|
||||
}
|
||||
|
||||
// WARNING: This is unstable! Do not use this method outside of Rocket!
|
||||
|
@ -79,8 +78,8 @@ impl Client {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn _cargo(&self) -> &Cargo {
|
||||
&self.cargo
|
||||
pub(crate) fn _rocket(&self) -> &Rocket {
|
||||
&self.rocket
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::cell::RefCell;
|
|||
|
||||
use crate::error::Error;
|
||||
use crate::local::{asynchronous, blocking::{LocalRequest, LocalResponse}};
|
||||
use crate::rocket::{Rocket, Cargo};
|
||||
use crate::rocket::Rocket;
|
||||
use crate::http::Method;
|
||||
|
||||
/// A `blocking` client to construct and dispatch local requests.
|
||||
|
@ -63,8 +63,8 @@ impl Client {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn _cargo(&self) -> &Cargo {
|
||||
self.inner._cargo()
|
||||
fn _rocket(&self) -> &Rocket {
|
||||
self.inner._rocket()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
@ -119,25 +119,7 @@ macro_rules! pub_client_impl {
|
|||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn rocket(&self) -> &Rocket {
|
||||
&*self._cargo()
|
||||
}
|
||||
|
||||
/// Returns a reference to the `Cargo` of the `Rocket` this client is
|
||||
/// creating requests for.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
#[doc = $import]
|
||||
///
|
||||
/// # Client::_test(|client, _, _| {
|
||||
/// let client: &Client = client;
|
||||
/// let cargo = client.cargo();
|
||||
/// # });
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn cargo(&self) -> &Cargo {
|
||||
self._cargo()
|
||||
&*self._rocket()
|
||||
}
|
||||
|
||||
/// Returns a cookie jar containing all of the cookies this client is
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use crate::rocket::Cargo;
|
||||
use crate::rocket::Rocket;
|
||||
use crate::request::{self, FromRequest, Request};
|
||||
use crate::outcome::Outcome;
|
||||
use crate::http::Status;
|
||||
|
@ -92,11 +92,9 @@ use crate::http::Status;
|
|||
/// state.0.to_string()
|
||||
/// }
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut rocket = rocket::ignite().manage(MyManagedState(127));
|
||||
/// let state = State::from(rocket.inspect().await).expect("managing `MyManagedState`");
|
||||
/// let state = State::from(&rocket).expect("managed `MyManagedState`");
|
||||
/// assert_eq!(handler(state), "127");
|
||||
/// # });
|
||||
/// ```
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct State<'r, T: Send + Sync + 'static>(&'r T);
|
||||
|
@ -147,19 +145,16 @@ impl<'r, T: Send + Sync + 'static> State<'r, T> {
|
|||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Unmanaged(usize);
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut rocket = rocket::ignite().manage(Managed(7));
|
||||
/// let cargo = rocket.inspect().await;
|
||||
/// let rocket = rocket::ignite().manage(Managed(7));
|
||||
///
|
||||
/// let state: Option<State<Managed>> = State::from(cargo);
|
||||
/// let state: Option<State<Managed>> = State::from(&rocket);
|
||||
/// assert_eq!(state.map(|s| s.inner()), Some(&Managed(7)));
|
||||
///
|
||||
/// let state: Option<State<Unmanaged>> = State::from(cargo);
|
||||
/// let state: Option<State<Unmanaged>> = State::from(&rocket);
|
||||
/// assert_eq!(state, None);
|
||||
/// # });
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn from(rocket: &'r Cargo) -> Option<Self> {
|
||||
pub fn from(rocket: &'r Rocket) -> Option<Self> {
|
||||
rocket.state().map(State)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ use futures::future::FutureExt;
|
|||
use futures::stream::StreamExt;
|
||||
use futures::future::{Future, BoxFuture};
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
use ref_cast::RefCast;
|
||||
|
||||
use yansi::Paint;
|
||||
use state::Container;
|
||||
|
@ -38,7 +37,6 @@ pub struct Rocket {
|
|||
pub(crate) config: Config,
|
||||
pub(crate) figment: Figment,
|
||||
pub(crate) managed_state: Container,
|
||||
manifest: Vec<PreLaunchOp>,
|
||||
router: Router,
|
||||
default_catcher: Option<Catcher>,
|
||||
catchers: HashMap<u16, Catcher>,
|
||||
|
@ -47,140 +45,9 @@ pub struct Rocket {
|
|||
pub(crate) shutdown_handle: Shutdown,
|
||||
}
|
||||
|
||||
/// An operation that occurs prior to launching a Rocket instance.
|
||||
enum PreLaunchOp {
|
||||
Mount(Origin<'static>, Vec<Route>),
|
||||
Register(Vec<Catcher>),
|
||||
Manage(&'static str, Box<dyn FnOnce(&mut Container) + Send + Sync + 'static>),
|
||||
Attach(Box<dyn Fairing>),
|
||||
}
|
||||
|
||||
/// A frozen view into the contents of an instance of `Rocket`.
|
||||
///
|
||||
/// Obtained via [`Rocket::inspect()`].
|
||||
#[derive(RefCast)]
|
||||
#[repr(transparent)]
|
||||
pub struct Cargo(Rocket);
|
||||
|
||||
// A token returned to force the execution of one method before another.
|
||||
pub(crate) struct Token;
|
||||
|
||||
impl Rocket {
|
||||
#[inline]
|
||||
fn _mount(&mut self, base: Origin<'static>, routes: Vec<Route>) {
|
||||
// info!("[$]🛰 [/m]mounting [b]{}[/]:", log::emoji(), base);
|
||||
// info!("[$]🛰 [/m]mounting [b]{}[/]:", log::emoji(), base);
|
||||
// info!("{}[m]Mounting [b]{}[/]:[/]", log::emoji("🛰 "), base);
|
||||
info!("{}{} {}{}",
|
||||
Paint::emoji("🛰 "),
|
||||
Paint::magenta("Mounting"),
|
||||
Paint::blue(&base),
|
||||
Paint::magenta(":"));
|
||||
|
||||
for route in routes {
|
||||
let old_route = route.clone();
|
||||
let route = route.map_base(|old| format!("{}{}", base, old))
|
||||
.unwrap_or_else(|e| {
|
||||
error_!("Route `{}` has a malformed URI.", old_route);
|
||||
error_!("{}", e);
|
||||
panic!("Invalid route URI.");
|
||||
});
|
||||
|
||||
info_!("{}", route);
|
||||
self.router.add(route);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _register(&mut self, catchers: Vec<Catcher>) {
|
||||
info!("{}{}", Paint::emoji("👾 "), Paint::magenta("Catchers:"));
|
||||
|
||||
for catcher in catchers {
|
||||
info_!("{}", catcher);
|
||||
|
||||
let existing = match catcher.code {
|
||||
Some(code) => self.catchers.insert(code, catcher),
|
||||
None => self.default_catcher.replace(catcher)
|
||||
};
|
||||
|
||||
if let Some(existing) = existing {
|
||||
warn_!("Replacing existing '{}' catcher.", existing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
async fn _attach(mut self, fairing: Box<dyn Fairing>) -> Self {
|
||||
// Attach (and run attach-) fairings, which requires us to move `self`.
|
||||
trace_!("Running attach fairing: {:?}", fairing.info());
|
||||
let mut fairings = mem::replace(&mut self.fairings, Fairings::new());
|
||||
self = fairings.attach(fairing, self).await;
|
||||
|
||||
// Note that `self.fairings` may now be non-empty! Move them to the end.
|
||||
fairings.append(self.fairings);
|
||||
self.fairings = fairings;
|
||||
self
|
||||
}
|
||||
|
||||
// Create a "dummy" instance of `Rocket` to use while mem-swapping `self`.
|
||||
fn dummy() -> Rocket {
|
||||
Rocket {
|
||||
config: Config::debug_default(),
|
||||
figment: Figment::from(Config::debug_default()),
|
||||
manifest: vec![],
|
||||
router: Router::new(),
|
||||
default_catcher: None,
|
||||
catchers: HashMap::new(),
|
||||
managed_state: Container::new(),
|
||||
fairings: Fairings::new(),
|
||||
shutdown_handle: Shutdown(mpsc::channel(1).0),
|
||||
shutdown_receiver: None,
|
||||
}
|
||||
}
|
||||
|
||||
// Instead of requiring the user to individually `await` each call to
|
||||
// `attach()`, some operations are queued in `self.pending`. Functions that
|
||||
// want to provide read access to any data from the Cargo, such as
|
||||
// `inspect()`, need to apply those pending operations first.
|
||||
//
|
||||
// This function returns a future that executes those pending operations,
|
||||
// requiring only a single `await` at the call site. After completion,
|
||||
// `self.pending` will be empty and `self.manifest` will reflect all pending
|
||||
// changes.
|
||||
async fn actualize_manifest(&mut self) {
|
||||
// Note: attach fairings may add more ops to the `manifest`! We
|
||||
// process them as a stack to maintain proper ordering.
|
||||
let mut manifest = mem::replace(&mut self.manifest, vec![]);
|
||||
while !manifest.is_empty() {
|
||||
trace_!("[MANIEST PROGRESS ({} left)]: {:?}", manifest.len(), manifest);
|
||||
match manifest.remove(0) {
|
||||
PreLaunchOp::Manage(_, callback) => callback(&mut self.managed_state),
|
||||
PreLaunchOp::Mount(base, routes) => self._mount(base, routes),
|
||||
PreLaunchOp::Register(catchers) => self._register(catchers),
|
||||
PreLaunchOp::Attach(fairing) => {
|
||||
let rocket = mem::replace(self, Rocket::dummy());
|
||||
*self = rocket._attach(fairing).await;
|
||||
self.manifest.append(&mut manifest);
|
||||
manifest = mem::replace(&mut self.manifest, vec![]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn into_cargo(mut self) -> Cargo {
|
||||
self.actualize_manifest().await;
|
||||
Cargo(self)
|
||||
}
|
||||
|
||||
fn cargo(&self) -> &Cargo {
|
||||
if !self.manifest.is_empty() {
|
||||
panic!("internal error: immutable launch state with manifest");
|
||||
}
|
||||
|
||||
Cargo::ref_cast(self)
|
||||
}
|
||||
}
|
||||
|
||||
// This function tries to hide all of the Hyper-ness from Rocket. It essentially
|
||||
// converts Hyper types into Rocket types, then calls the `dispatch` function,
|
||||
// which knows nothing about Hyper. Because responding depends on the
|
||||
|
@ -506,7 +373,7 @@ impl Rocket {
|
|||
|
||||
// Run the launch fairings.
|
||||
self.fairings.pretty_print_counts();
|
||||
self.fairings.handle_launch(self.cargo());
|
||||
self.fairings.handle_launch(&self);
|
||||
|
||||
// Determine the address and port we actually bound to.
|
||||
self.config.port = listener.local_addr().map(|a| a.port()).unwrap_or(0);
|
||||
|
@ -624,7 +491,6 @@ impl Rocket {
|
|||
config, figment,
|
||||
managed_state,
|
||||
shutdown_handle: Shutdown(shutdown_sender),
|
||||
manifest: vec![],
|
||||
router: Router::new(),
|
||||
default_catcher: None,
|
||||
catchers: HashMap::new(),
|
||||
|
@ -697,7 +563,25 @@ impl Rocket {
|
|||
panic!("Invalid mount point.");
|
||||
}
|
||||
|
||||
self.manifest.push(PreLaunchOp::Mount(base_uri, routes.into()));
|
||||
info!("{}{} {}{}",
|
||||
Paint::emoji("🛰 "),
|
||||
Paint::magenta("Mounting"),
|
||||
Paint::blue(&base_uri),
|
||||
Paint::magenta(":"));
|
||||
|
||||
for route in routes.into() {
|
||||
let old_route = route.clone();
|
||||
let route = route.map_base(|old| format!("{}{}", base, old))
|
||||
.unwrap_or_else(|e| {
|
||||
error_!("Route `{}` has a malformed URI.", old_route);
|
||||
error_!("{}", e);
|
||||
panic!("Invalid route URI.");
|
||||
});
|
||||
|
||||
info_!("{}", route);
|
||||
self.router.add(route);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -726,7 +610,21 @@ impl Rocket {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn register(mut self, catchers: Vec<Catcher>) -> Self {
|
||||
self.manifest.push(PreLaunchOp::Register(catchers));
|
||||
info!("{}{}", Paint::emoji("👾 "), Paint::magenta("Catchers:"));
|
||||
|
||||
for catcher in catchers {
|
||||
info_!("{}", catcher);
|
||||
|
||||
let existing = match catcher.code {
|
||||
Some(code) => self.catchers.insert(code, catcher),
|
||||
None => self.default_catcher.replace(catcher)
|
||||
};
|
||||
|
||||
if let Some(existing) = existing {
|
||||
warn_!("Replacing existing '{}' catcher.", existing);
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -765,14 +663,12 @@ impl Rocket {
|
|||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn manage<T: Send + Sync + 'static>(mut self, state: T) -> Self {
|
||||
pub fn manage<T: Send + Sync + 'static>(self, state: T) -> Self {
|
||||
let type_name = std::any::type_name::<T>();
|
||||
self.manifest.push(PreLaunchOp::Manage(type_name, Box::new(move |managed| {
|
||||
if !managed.set::<T>(state) {
|
||||
if !self.managed_state.set(state) {
|
||||
error!("State for type '{}' is already being managed!", type_name);
|
||||
panic!("Aborting due to duplicately managed state.");
|
||||
}
|
||||
})));
|
||||
|
||||
self
|
||||
}
|
||||
|
@ -798,89 +694,125 @@ impl Rocket {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn attach<F: Fairing>(mut self, fairing: F) -> Self {
|
||||
self.manifest.push(PreLaunchOp::Attach(Box::new(fairing)));
|
||||
let future = async move {
|
||||
let fairing = Box::new(fairing);
|
||||
let mut fairings = mem::replace(&mut self.fairings, Fairings::new());
|
||||
let rocket = fairings.attach(fairing, self).await;
|
||||
(rocket, fairings)
|
||||
};
|
||||
|
||||
let (rocket, mut fairings) = match tokio::runtime::Handle::try_current() {
|
||||
Ok(handle) => {
|
||||
// println!("Using existing runtime...");
|
||||
std::thread::spawn(move || {
|
||||
handle.block_on(future)
|
||||
}).join().unwrap()
|
||||
}
|
||||
Err(_) => {
|
||||
// println!("Using new runtime.");
|
||||
std::thread::spawn(|| {
|
||||
futures::executor::block_on(future)
|
||||
}).join().unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
self = rocket;
|
||||
|
||||
// Note that `self.fairings` may now be non-empty! Move them to the end.
|
||||
fairings.append(self.fairings);
|
||||
self.fairings = fairings;
|
||||
self
|
||||
}
|
||||
|
||||
/// Access the current state of this `Rocket` instance.
|
||||
///
|
||||
/// The `Cargo` type provides methods such as [`Cargo::routes()`]
|
||||
/// and [`Cargo::state()`]. This method is called to get a `Cargo`
|
||||
/// instance.
|
||||
/// Returns an iterator over all of the routes mounted on this instance of
|
||||
/// Rocket.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut rocket = rocket::ignite();
|
||||
/// let config = rocket.inspect().await.config();
|
||||
/// # let _ = config;
|
||||
/// # });
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// use rocket::Rocket;
|
||||
/// use rocket::fairing::AdHoc;
|
||||
///
|
||||
/// #[get("/hello")]
|
||||
/// fn hello() -> &'static str {
|
||||
/// "Hello, world!"
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let mut rocket = rocket::ignite()
|
||||
/// .mount("/", routes![hello])
|
||||
/// .mount("/hi", routes![hello]);
|
||||
///
|
||||
/// for route in rocket.routes() {
|
||||
/// match route.base() {
|
||||
/// "/" => assert_eq!(route.uri.path(), "/hello"),
|
||||
/// "/hi" => assert_eq!(route.uri.path(), "/hi/hello"),
|
||||
/// _ => unreachable!("only /hello, /hi/hello are expected")
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(rocket.routes().count(), 2);
|
||||
/// }
|
||||
/// ```
|
||||
pub async fn inspect(&mut self) -> &Cargo {
|
||||
self.actualize_manifest().await;
|
||||
self.cargo()
|
||||
#[inline(always)]
|
||||
pub fn routes(&self) -> impl Iterator<Item = &Route> + '_ {
|
||||
self.router.routes()
|
||||
}
|
||||
|
||||
/// Returns `Some` of the managed state value for the type `T` if it is
|
||||
/// being managed by `self`. Otherwise, returns `None`.
|
||||
///
|
||||
/// This function is equivalent to `.inspect().await.state()` and is
|
||||
/// provided as a convenience.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #[derive(PartialEq, Debug)]
|
||||
/// struct MyState(&'static str);
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut rocket = rocket::ignite().manage(MyState("hello!"));
|
||||
/// assert_eq!(rocket.state::<MyState>().await, Some(&MyState("hello!")));
|
||||
/// # });
|
||||
/// let rocket = rocket::ignite().manage(MyState("hello!"));
|
||||
/// assert_eq!(rocket.state::<MyState>(), Some(&MyState("hello!")));
|
||||
/// ```
|
||||
pub async fn state<T: Send + Sync + 'static>(&mut self) -> Option<&T> {
|
||||
self.inspect().await.state()
|
||||
#[inline(always)]
|
||||
pub fn state<T: Send + Sync + 'static>(&self) -> Option<&T> {
|
||||
self.managed_state.try_get()
|
||||
}
|
||||
|
||||
/// Returns the figment.
|
||||
///
|
||||
/// This function is equivalent to `.inspect().await.figment()` and is
|
||||
/// provided as a convenience.
|
||||
/// Returns the figment for configured provider.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use rocket::Rocket;
|
||||
/// use rocket::fairing::AdHoc;
|
||||
/// let rocket = rocket::ignite();
|
||||
/// let figment = rocket.figment();
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut rocket = rocket::ignite();
|
||||
/// println!("Rocket config: {:?}", rocket.config().await);
|
||||
/// # });
|
||||
/// let port: u16 = figment.extract_inner("port").unwrap();
|
||||
/// assert_eq!(port, rocket.config().port);
|
||||
/// ```
|
||||
pub async fn figment(&mut self) -> &Figment {
|
||||
self.inspect().await.figment()
|
||||
#[inline(always)]
|
||||
pub fn figment(&self) -> &Figment {
|
||||
&self.figment
|
||||
}
|
||||
|
||||
/// Returns the config.
|
||||
///
|
||||
/// This function is equivalent to `.inspect().await.config()` and is
|
||||
/// provided as a convenience.
|
||||
/// Returns the active configuration.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// use rocket::Rocket;
|
||||
/// use rocket::fairing::AdHoc;
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut rocket = rocket::ignite();
|
||||
/// println!("Rocket config: {:?}", rocket.config().await);
|
||||
/// # });
|
||||
/// #[launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite()
|
||||
/// .attach(AdHoc::on_launch("Config Printer", |rocket| {
|
||||
/// println!("Rocket launch config: {:?}", rocket.config());
|
||||
/// }))
|
||||
/// }
|
||||
/// ```
|
||||
pub async fn config(&mut self) -> &Config {
|
||||
self.inspect().await.config()
|
||||
#[inline(always)]
|
||||
pub fn config(&self) -> &Config {
|
||||
&self.config
|
||||
}
|
||||
|
||||
/// Returns a handle which can be used to gracefully terminate this instance
|
||||
|
@ -888,14 +820,12 @@ impl Rocket {
|
|||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,no_run
|
||||
/// # use std::{thread, time::Duration};
|
||||
/// #
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut rocket = rocket::ignite();
|
||||
/// let handle = rocket.inspect().await.shutdown();
|
||||
/// let handle = rocket.shutdown();
|
||||
///
|
||||
/// # if false {
|
||||
/// thread::spawn(move || {
|
||||
/// thread::sleep(Duration::from_secs(10));
|
||||
/// handle.shutdown();
|
||||
|
@ -904,7 +834,6 @@ impl Rocket {
|
|||
/// // Shuts down after 10 seconds
|
||||
/// let shutdown_result = rocket.launch().await;
|
||||
/// assert!(shutdown_result.is_ok());
|
||||
/// # }
|
||||
/// # });
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
|
@ -915,7 +844,6 @@ impl Rocket {
|
|||
/// Perform "pre-launch" checks: verify that there are no routing colisions
|
||||
/// and that there were no fairing failures.
|
||||
pub(crate) async fn prelaunch_check(&mut self) -> Result<(), Error> {
|
||||
self.actualize_manifest().await;
|
||||
if let Err(e) = self.router.collisions() {
|
||||
return Err(Error::new(ErrorKind::Collision(e)));
|
||||
}
|
||||
|
@ -1007,130 +935,3 @@ impl Rocket {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PreLaunchOp {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
use PreLaunchOp::*;
|
||||
match self {
|
||||
Mount(origin, routes) => f.debug_tuple("PreLaunchOp::Mount")
|
||||
.field(&origin)
|
||||
.field(&routes)
|
||||
.finish(),
|
||||
Register(catchers) => f.debug_tuple("PreLaunchOp::Register")
|
||||
.field(&catchers)
|
||||
.finish(),
|
||||
Manage(name, _) => f.debug_tuple("PreLaunchOp::Manage")
|
||||
.field(&name)
|
||||
.finish(),
|
||||
Attach(fairing) => f.debug_tuple("PreLaunchOp::Attach")
|
||||
.field(&fairing.info())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for Cargo {
|
||||
type Target = Rocket;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Cargo {
|
||||
/// Returns an iterator over all of the routes mounted on this instance of
|
||||
/// Rocket.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// use rocket::Rocket;
|
||||
/// use rocket::fairing::AdHoc;
|
||||
///
|
||||
/// #[get("/hello")]
|
||||
/// fn hello() -> &'static str {
|
||||
/// "Hello, world!"
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut rocket = rocket::ignite()
|
||||
/// .mount("/", routes![hello])
|
||||
/// .mount("/hi", routes![hello]);
|
||||
///
|
||||
/// for route in rocket.inspect().await.routes() {
|
||||
/// match route.base() {
|
||||
/// "/" => assert_eq!(route.uri.path(), "/hello"),
|
||||
/// "/hi" => assert_eq!(route.uri.path(), "/hi/hello"),
|
||||
/// _ => unreachable!("only /hello, /hi/hello are expected")
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(rocket.inspect().await.routes().count(), 2);
|
||||
/// # });
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn routes(&self) -> impl Iterator<Item = &Route> + '_ {
|
||||
self.0.router.routes()
|
||||
}
|
||||
|
||||
/// Returns `Some` of the managed state value for the type `T` if it is
|
||||
/// being managed by `self`. Otherwise, returns `None`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #[derive(PartialEq, Debug)]
|
||||
/// struct MyState(&'static str);
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut rocket = rocket::ignite().manage(MyState("hello!"));
|
||||
///
|
||||
/// let cargo = rocket.inspect().await;
|
||||
/// assert_eq!(cargo.state::<MyState>(), Some(&MyState("hello!")));
|
||||
/// # });
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn state<T: Send + Sync + 'static>(&self) -> Option<&T> {
|
||||
self.0.managed_state.try_get()
|
||||
}
|
||||
|
||||
/// Returns the figment for configured provider.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut rocket = rocket::ignite();
|
||||
/// let figment = rocket.inspect().await.figment();
|
||||
/// # });
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn figment(&self) -> &Figment {
|
||||
&self.0.figment
|
||||
}
|
||||
|
||||
/// Returns the active configuration.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// use rocket::Rocket;
|
||||
/// use rocket::fairing::AdHoc;
|
||||
///
|
||||
/// #[launch]
|
||||
/// fn rocket() -> rocket::Rocket {
|
||||
/// rocket::ignite()
|
||||
/// .attach(AdHoc::on_launch("Config Printer", |cargo| {
|
||||
/// println!("Rocket launch config: {:?}", cargo.config());
|
||||
/// }))
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn config(&self) -> &Config {
|
||||
&self.0.config
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,42 +2,43 @@ use rocket::fairing::AdHoc;
|
|||
|
||||
#[rocket::async_test]
|
||||
async fn test_inspectable_attach_state() {
|
||||
let mut rocket = rocket::ignite()
|
||||
let rocket = rocket::ignite()
|
||||
.attach(AdHoc::on_attach("Add State", |rocket| async {
|
||||
Ok(rocket.manage("Hi!"))
|
||||
}));
|
||||
|
||||
let state = rocket.inspect().await;
|
||||
assert_eq!(state.state::<&'static str>(), Some(&"Hi!"));
|
||||
let state = rocket.state::<&'static str>();
|
||||
assert_eq!(state, Some(&"Hi!"));
|
||||
}
|
||||
|
||||
#[rocket::async_test]
|
||||
async fn test_inspectable_attach_state_in_future_attach() {
|
||||
let mut rocket = rocket::ignite()
|
||||
let rocket = rocket::ignite()
|
||||
.attach(AdHoc::on_attach("Add State", |rocket| async {
|
||||
Ok(rocket.manage("Hi!"))
|
||||
}))
|
||||
.attach(AdHoc::on_attach("Inspect State", |mut rocket| async {
|
||||
let state = rocket.inspect().await;
|
||||
assert_eq!(state.state::<&'static str>(), Some(&"Hi!"));
|
||||
.attach(AdHoc::on_attach("Inspect State", |rocket| async {
|
||||
let state = rocket.state::<&'static str>();
|
||||
assert_eq!(state, Some(&"Hi!"));
|
||||
Ok(rocket)
|
||||
}));
|
||||
|
||||
let _ = rocket.inspect().await;
|
||||
let state = rocket.state::<&'static str>();
|
||||
assert_eq!(state, Some(&"Hi!"));
|
||||
}
|
||||
|
||||
#[rocket::async_test]
|
||||
async fn test_attach_state_is_well_ordered() {
|
||||
let mut rocket = rocket::ignite()
|
||||
.attach(AdHoc::on_attach("Inspect State Pre", |mut rocket| async {
|
||||
let state = rocket.inspect().await;
|
||||
assert_eq!(state.state::<&'static str>(), None);
|
||||
let rocket = rocket::ignite()
|
||||
.attach(AdHoc::on_attach("Inspect State Pre", |rocket| async {
|
||||
let state = rocket.state::<&'static str>();
|
||||
assert_eq!(state, None);
|
||||
Ok(rocket)
|
||||
}))
|
||||
.attach(AdHoc::on_attach("Add State", |rocket| async {
|
||||
Ok(rocket.manage("Hi!"))
|
||||
}));
|
||||
|
||||
let state = rocket.inspect().await;
|
||||
assert_eq!(state.state::<&'static str>(), Some(&"Hi!"));
|
||||
let state = rocket.state::<&'static str>();
|
||||
assert_eq!(state, Some(&"Hi!"));
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
struct A;
|
||||
|
||||
#[rocket::async_test]
|
||||
#[test]
|
||||
#[should_panic]
|
||||
async fn twice_managed_state() {
|
||||
let _ = rocket::ignite().manage(A).manage(A).inspect().await;
|
||||
fn twice_managed_state() {
|
||||
let _ = rocket::ignite().manage(A).manage(A);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use rocket::config::{Config, LogLevel};
|
||||
|
||||
async fn test_config(profile: &str) {
|
||||
let mut rocket = rocket::custom(Config::figment().select(profile));
|
||||
let config = rocket.config().await;
|
||||
fn test_config(profile: &str) {
|
||||
let rocket = rocket::custom(Config::figment().select(profile));
|
||||
let config = rocket.config();
|
||||
match &*profile {
|
||||
"debug" => {
|
||||
assert_eq!(config.address, std::net::Ipv4Addr::LOCALHOST);
|
||||
|
@ -25,12 +25,12 @@ async fn test_config(profile: &str) {
|
|||
}
|
||||
}
|
||||
|
||||
#[rocket::async_test]
|
||||
async fn test_debug_config() {
|
||||
test_config("debug").await
|
||||
#[test]
|
||||
fn test_debug_config() {
|
||||
test_config("debug")
|
||||
}
|
||||
|
||||
#[rocket::async_test]
|
||||
async fn test_release_config() {
|
||||
test_config("release").await
|
||||
#[test]
|
||||
fn test_release_config() {
|
||||
test_config("release")
|
||||
}
|
||||
|
|
|
@ -40,11 +40,11 @@ fn test_index() {
|
|||
|
||||
// Render the template with an empty context.
|
||||
let mut context: HashMap<&str, &str> = HashMap::new();
|
||||
let template = Template::show(client.cargo(), "index", &context).unwrap();
|
||||
let template = Template::show(client.rocket(), "index", &context).unwrap();
|
||||
test_body(None, template);
|
||||
|
||||
// Render the template with a context that contains the message.
|
||||
context.insert("message", "Hello from Rocket!");
|
||||
let template = Template::show(client.cargo(), "index", &context).unwrap();
|
||||
let template = Template::show(client.rocket(), "index", &context).unwrap();
|
||||
test_body(Some(Cookie::new("message", "Hello from Rocket!")), template);
|
||||
}
|
||||
|
|
|
@ -66,9 +66,9 @@ fn rocket() -> rocket::Rocket {
|
|||
rocket::ignite()
|
||||
.mount("/", routes![hello, token])
|
||||
.attach(Counter::default())
|
||||
.attach(AdHoc::on_attach("Token State", |mut rocket| async {
|
||||
.attach(AdHoc::on_attach("Token State", |rocket| async {
|
||||
println!("Adding token managed state...");
|
||||
match rocket.figment().await.extract_inner("token") {
|
||||
match rocket.figment().extract_inner("token") {
|
||||
Ok(value) => Ok(rocket.manage(Token(value))),
|
||||
Err(_) => Err(rocket)
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ fn test_root() {
|
|||
dispatch!(*method, "/", |client, response| {
|
||||
let mut map = std::collections::HashMap::new();
|
||||
map.insert("path", "/");
|
||||
let expected = Template::show(client.cargo(), "error/404", &map).unwrap();
|
||||
let expected = Template::show(client.rocket(), "error/404", &map).unwrap();
|
||||
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
assert_eq!(response.into_string(), Some(expected));
|
||||
|
@ -50,7 +50,7 @@ fn test_name() {
|
|||
parent: "layout",
|
||||
};
|
||||
|
||||
let expected = Template::show(client.cargo(), "index", &context).unwrap();
|
||||
let expected = Template::show(client.rocket(), "index", &context).unwrap();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
assert_eq!(response.into_string(), Some(expected));
|
||||
});
|
||||
|
@ -63,7 +63,7 @@ fn test_404() {
|
|||
let mut map = std::collections::HashMap::new();
|
||||
map.insert("path", "/hello/");
|
||||
|
||||
let expected = Template::show(client.cargo(), "error/404", &map).unwrap();
|
||||
let expected = Template::show(client.rocket(), "error/404", &map).unwrap();
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
assert_eq!(response.into_string(), Some(expected));
|
||||
});
|
||||
|
|
|
@ -8,13 +8,13 @@ fn test() {
|
|||
let client = Client::tracked(rocket()).unwrap();
|
||||
client.get("/sync").dispatch();
|
||||
|
||||
let atomics = client.cargo().state::<Atomics>().unwrap();
|
||||
let atomics = client.rocket().state::<Atomics>().unwrap();
|
||||
assert_eq!(atomics.uncached.load(Ordering::Relaxed), 2);
|
||||
assert_eq!(atomics.cached.load(Ordering::Relaxed), 1);
|
||||
|
||||
client.get("/async").dispatch();
|
||||
|
||||
let atomics = client.cargo().state::<Atomics>().unwrap();
|
||||
let atomics = client.rocket().state::<Atomics>().unwrap();
|
||||
assert_eq!(atomics.uncached.load(Ordering::Relaxed), 4);
|
||||
assert_eq!(atomics.cached.load(Ordering::Relaxed), 2);
|
||||
}
|
||||
|
|
|
@ -25,17 +25,15 @@ fn test_count() {
|
|||
assert_eq!(get_count(&client), 100);
|
||||
}
|
||||
|
||||
#[rocket::async_test]
|
||||
async fn test_raw_state_count() {
|
||||
#[test]
|
||||
fn test_raw_state_count() {
|
||||
use rocket::State;
|
||||
use super::{count, index};
|
||||
|
||||
let mut rocket = super::rocket();
|
||||
let cargo = rocket.inspect().await;
|
||||
|
||||
assert_eq!(count(State::from(cargo).unwrap()), "0");
|
||||
assert!(index(State::from(cargo).unwrap()).0.contains("Visits: 1"));
|
||||
assert_eq!(count(State::from(cargo).unwrap()), "1");
|
||||
let rocket = super::rocket();
|
||||
assert_eq!(count(State::from(&rocket).unwrap()), "0");
|
||||
assert!(index(State::from(&rocket).unwrap()).0.contains("Visits: 1"));
|
||||
assert_eq!(count(State::from(&rocket).unwrap()), "1");
|
||||
}
|
||||
|
||||
// Cargo runs each test in parallel on different threads. We use all of these
|
||||
|
|
|
@ -30,7 +30,7 @@ fn test_root() {
|
|||
dispatch!(*method, "/", |client, response| {
|
||||
let mut map = std::collections::HashMap::new();
|
||||
map.insert("path", "/");
|
||||
let expected = Template::show(client.cargo(), "error/404", &map).unwrap();
|
||||
let expected = Template::show(client.rocket(), "error/404", &map).unwrap();
|
||||
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
assert_eq!(response.into_string(), Some(expected));
|
||||
|
@ -47,7 +47,7 @@ fn test_name() {
|
|||
items: vec!["One", "Two", "Three"]
|
||||
};
|
||||
|
||||
let expected = Template::show(client.cargo(), "index", &context).unwrap();
|
||||
let expected = Template::show(client.rocket(), "index", &context).unwrap();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
assert_eq!(response.into_string(), Some(expected));
|
||||
});
|
||||
|
@ -60,7 +60,7 @@ fn test_404() {
|
|||
let mut map = std::collections::HashMap::new();
|
||||
map.insert("path", "/hello/");
|
||||
|
||||
let expected = Template::show(client.cargo(), "error/404", &map).unwrap();
|
||||
let expected = Template::show(client.rocket(), "error/404", &map).unwrap();
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
assert_eq!(response.into_string(), Some(expected));
|
||||
});
|
||||
|
|
|
@ -95,8 +95,8 @@ async fn index(msg: Option<FlashMessage<'_, '_>>, conn: DbConn) -> Template {
|
|||
Template::render("index", Context::raw(&conn, msg).await)
|
||||
}
|
||||
|
||||
async fn run_db_migrations(mut rocket: Rocket) -> Result<Rocket, Rocket> {
|
||||
DbConn::get_one(rocket.inspect().await).await
|
||||
async fn run_db_migrations(rocket: Rocket) -> Result<Rocket, Rocket> {
|
||||
DbConn::get_one(&rocket).await
|
||||
.expect("database connection")
|
||||
.run(|c| match embedded_migrations::run(c) {
|
||||
Ok(()) => Ok(rocket),
|
||||
|
@ -112,8 +112,8 @@ fn rocket() -> Rocket {
|
|||
rocket::ignite()
|
||||
.attach(DbConn::fairing())
|
||||
.attach(AdHoc::on_attach("Database Migrations", run_db_migrations))
|
||||
.attach(Template::fairing())
|
||||
.mount("/", StaticFiles::from(crate_relative!("/static")))
|
||||
.mount("/", routes![index])
|
||||
.mount("/todo", routes![new, toggle, delete])
|
||||
.attach(Template::fairing())
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ macro_rules! run_test {
|
|||
rocket::async_test(async move {
|
||||
let rocket = super::rocket();
|
||||
let $client = Client::tracked(rocket).await.expect("Rocket client");
|
||||
let db = super::DbConn::get_one($client.cargo()).await;
|
||||
let db = super::DbConn::get_one($client.rocket()).await;
|
||||
let $conn = db.expect("failed to get database connection for testing");
|
||||
Task::delete_all(&$conn).await.expect("failed to delete all tasks for testing");
|
||||
|
||||
|
|
|
@ -190,8 +190,7 @@ ROCKET_DICT={key="abc",val=123}
|
|||
## Extracting Values
|
||||
|
||||
Your application can extract any configuration that implements [`Deserialize`]
|
||||
from the configured provider, which is exposed via [`Rocket::figment()`] and
|
||||
[`Cargo::figment()`]:
|
||||
from the configured provider, which is exposed via [`Rocket::figment()`]:
|
||||
|
||||
```rust
|
||||
# #[macro_use] extern crate rocket;
|
||||
|
@ -201,9 +200,9 @@ use serde::Deserialize;
|
|||
|
||||
|
||||
#[launch]
|
||||
async fn rocket() -> _ {
|
||||
let mut rocket = rocket::ignite();
|
||||
let figment = rocket.figment().await;
|
||||
fn rocket() -> _ {
|
||||
let rocket = rocket::ignite();
|
||||
let figment = rocket.figment();
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Config {
|
||||
|
@ -256,7 +255,6 @@ fn rocket() -> _ {
|
|||
```
|
||||
|
||||
[`Rocket::figment()`]: @api/rocket/struct.Rocket.html#method.figment
|
||||
[`Cargo::figment()`]: @api/rocket/struct.Cargo.html#method.figment
|
||||
|
||||
## Custom Providers
|
||||
|
||||
|
|
Loading…
Reference in New Issue