Split 'AdHoc::on_launch' into two by fallibility.

The new 'AdHoc::try_on_launch()' replaces the previous 'on_launch'. The
new 'on_launch' returns a 'Rocket' directly.
This commit is contained in:
Sergio Benitez 2021-04-07 23:00:11 -07:00
parent 1c70df052c
commit 5931d6704b
5 changed files with 45 additions and 22 deletions

View File

@ -69,7 +69,7 @@ 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_launch(fairing_name, move |rocket| async move {
AdHoc::try_on_launch(fairing_name, move |rocket| async move {
let config = match Config::from(db, &rocket) {
Ok(config) => config,
Err(e) => dberr!("config", db, "{}", e, rocket),

View File

@ -1,6 +1,6 @@
use std::sync::Mutex;
use futures::future::{Future, BoxFuture};
use futures::future::{Future, BoxFuture, FutureExt};
use crate::{Rocket, Request, Response, Data};
use crate::fairing::{Fairing, Kind, Info};
@ -72,8 +72,10 @@ enum AdHocKind {
impl AdHoc {
/// Constructs an `AdHoc` launch fairing named `name`. The function `f` will
/// be called by Rocket just prior to launch. Returning an `Err` aborts
/// launch.
/// be called by Rocket just prior to launch.
///
/// This version of an `AdHoc` launch fairing cannot abort launch. For a
/// fallible version that can, see [`AdHoc::try_on_launch()`].
///
/// # Example
///
@ -82,14 +84,35 @@ impl AdHoc {
///
/// // The no-op launch fairing.
/// let fairing = AdHoc::on_launch("Boom!", |rocket| async move {
/// Ok(rocket)
/// rocket
/// });
/// ```
pub fn on_launch<F, Fut>(name: &'static str, f: F) -> AdHoc
where F: FnOnce(Rocket) -> Fut + Send + 'static,
Fut: Future<Output=Result<Rocket, Rocket>> + Send + 'static,
Fut: Future<Output = Rocket> + Send + 'static,
{
AdHoc { name, kind: AdHocKind::Launch(Once::new(Box::new(|r| Box::pin(f(r))))) }
AdHoc::try_on_launch(name, |rocket| f(rocket).map(Ok))
}
/// Constructs an `AdHoc` launch fairing named `name`. The function `f` will
/// be called by Rocket just prior to launch. Returning an `Err` aborts
/// launch.
///
/// For an infallible version, see [`AdHoc::on_launch()`].
///
/// # Example
///
/// ```rust
/// use rocket::fairing::AdHoc;
///
/// // The no-op try launch fairing.
/// let fairing = AdHoc::try_on_launch("No-Op", |rocket| async { Ok(rocket) });
/// ```
pub fn try_on_launch<F, Fut>(name: &'static str, f: F) -> AdHoc
where F: FnOnce(Rocket) -> Fut + Send + 'static,
Fut: Future<Output = Result<Rocket, Rocket>> + Send + 'static,
{
AdHoc { name, kind: AdHocKind::Launch(Once::new(Box::new(|r| f(r).boxed()))) }
}
/// Constructs an `AdHoc` launch fairing named `name`. The function `f` will
@ -182,7 +205,7 @@ impl AdHoc {
pub fn config<'de, T>() -> AdHoc
where T: serde::Deserialize<'de> + Send + Sync + 'static
{
AdHoc::on_launch(std::any::type_name::<T>(), |rocket| async {
AdHoc::try_on_launch(std::any::type_name::<T>(), |rocket| async {
let app_config = match rocket.figment().extract::<T>() {
Ok(config) => config,
Err(e) => {

View File

@ -3,9 +3,9 @@ use rocket::fairing::AdHoc;
#[rocket::async_test]
async fn test_inspectable_launch_state() -> Result<(), Error> {
let rocket = rocket::ignite()
let rocket = rocket::custom(rocket::Config::debug_default())
.attach(AdHoc::on_launch("Add State", |rocket| async {
Ok(rocket.manage("Hi!"))
rocket.manage("Hi!")
}))
._ignite()
.await?;
@ -17,14 +17,14 @@ async fn test_inspectable_launch_state() -> Result<(), Error> {
#[rocket::async_test]
async fn test_inspectable_launch_state_in_liftoff() -> Result<(), Error> {
let rocket = rocket::ignite()
let rocket = rocket::custom(rocket::Config::debug_default())
.attach(AdHoc::on_launch("Add State", |rocket| async {
Ok(rocket.manage("Hi!"))
rocket.manage("Hi!")
}))
.attach(AdHoc::on_launch("Inspect State", |rocket| async {
let state = rocket.state::<&'static str>();
assert_eq!(state, Some(&"Hi!"));
Ok(rocket)
rocket
}))
.attach(AdHoc::on_liftoff("Inspect State", |rocket| Box::pin(async move {
let state = rocket.state::<&'static str>();
@ -40,19 +40,19 @@ async fn test_inspectable_launch_state_in_liftoff() -> Result<(), Error> {
#[rocket::async_test]
async fn test_launch_state_is_well_ordered() -> Result<(), Error> {
let rocket = rocket::ignite()
let rocket = rocket::custom(rocket::Config::debug_default())
.attach(AdHoc::on_launch("Inspect State Pre", |rocket| async {
let state = rocket.state::<&'static str>();
assert_eq!(state, None);
Ok(rocket)
rocket
}))
.attach(AdHoc::on_launch("Add State", |rocket| async {
Ok(rocket.manage("Hi!"))
rocket.manage("Hi!")
}))
.attach(AdHoc::on_launch("Inspect State", |rocket| async {
let state = rocket.state::<&'static str>();
assert_eq!(state, Some(&"Hi!"));
Ok(rocket)
rocket
}))
._ignite()
.await?;
@ -65,14 +65,14 @@ async fn test_launch_state_is_well_ordered() -> Result<(), Error> {
#[should_panic]
#[rocket::async_test]
async fn negative_test_launch_state() {
let _ = rocket::ignite()
let _ = rocket::custom(rocket::Config::debug_default())
.attach(AdHoc::on_launch("Add State", |rocket| async {
Ok(rocket.manage("Hi!"))
rocket.manage("Hi!")
}))
.attach(AdHoc::on_launch("Inspect State", |rocket| async {
let state = rocket.state::<&'static str>();
assert_ne!(state, Some(&"Hi!"));
Ok(rocket)
rocket
}))
._ignite()
.await;

View File

@ -36,7 +36,7 @@ fn rocket() -> rocket::Rocket {
})
}));
Ok(rocket)
rocket
}))
}

View File

@ -10,6 +10,6 @@ async fn test_await_timer_inside_attach() {
rocket::ignite()
.attach(rocket::fairing::AdHoc::on_launch("1", |rocket| async {
do_async_setup().await;
Ok(rocket)
rocket
}));
}