1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
use state::TypeMap;
use figment::Figment;
use crate::{Catcher, Config, Rocket, Route, Shutdown};
use crate::router::Router;
use crate::fairing::Fairings;
mod private {
pub trait Sealed { }
}
#[doc(hidden)]
pub trait Stateful: private::Sealed {
fn into_state(self) -> State;
fn as_state_ref(&self) -> StateRef<'_>;
}
/// A marker trait for Rocket's launch phases.
///
/// This treat is implemented by the three phase marker types: [`Build`],
/// [`Ignite`], and [`Orbit`], representing the three phases to launch an
/// instance of [`Rocket`]. This trait is _sealed_ and cannot be implemented
/// outside of Rocket.
///
/// For a description of the three phases, see [`Rocket#phases`].
pub trait Phase: private::Sealed {
#[doc(hidden)]
type State: std::fmt::Debug + Stateful + Sync + Send + Unpin;
}
macro_rules! phase {
($(#[$o:meta])* $P:ident ($(#[$i:meta])* $S:ident) { $($fields:tt)* }) => (
$(#[$o])*
pub enum $P { }
impl Phase for $P {
#[doc(hidden)]
type State = $S;
}
$(#[$i])*
#[doc(hidden)]
pub struct $S {
$($fields)*
}
impl Stateful for $S {
fn into_state(self) -> State { State::$P(self) }
fn as_state_ref(&self) -> StateRef<'_> { StateRef::$P(self) }
}
#[doc(hidden)]
impl From<$S> for Rocket<$P> {
fn from(s: $S) -> Self { Rocket(s) }
}
impl private::Sealed for $P {}
impl private::Sealed for $S {}
)
}
macro_rules! phases {
($($(#[$o:meta])* $P:ident ($(#[$i:meta])* $S:ident) { $($fields:tt)* })*) => (
#[doc(hidden)]
pub enum State { $($P($S)),* }
#[doc(hidden)]
pub enum StateRef<'a> { $($P(&'a $S)),* }
$(phase!($(#[$o])* $P ($(#[$i])* $S) { $($fields)* });)*
)
}
phases! {
/// The initial launch [`Phase`]. See [Rocket#build](`Rocket#build`) for
/// phase details.
///
/// An instance of `Rocket` in this phase is typed as [`Rocket<Build>`]: a
/// transient, in-progress build.
Build (#[derive(Default, Debug)] Building) {
pub(crate) routes: Vec<Route>,
pub(crate) catchers: Vec<Catcher>,
pub(crate) fairings: Fairings,
pub(crate) figment: Figment,
pub(crate) state: TypeMap![Send + Sync],
}
/// The second launch [`Phase`]: post-build but pre-orbit. See
/// [Rocket#ignite](`Rocket#ignite`) for details.
///
/// An instance of `Rocket` in this phase is typed as [`Rocket<Ignite>`] and
/// represents a fully built and finalized application server ready for
/// launch into orbit. See [`Rocket#ignite`] for full details.
Ignite (#[derive(Debug)] Igniting) {
pub(crate) router: Router,
pub(crate) fairings: Fairings,
pub(crate) figment: Figment,
pub(crate) config: Config,
pub(crate) state: TypeMap![Send + Sync],
pub(crate) shutdown: Shutdown,
}
/// The final launch [`Phase`]. See [Rocket#orbit](`Rocket#orbit`) for
/// details.
///
/// An instance of `Rocket` in this phase is typed as [`Rocket<Orbit>`] and
/// represents a running application.
Orbit (#[derive(Debug)] Orbiting) {
pub(crate) router: Router,
pub(crate) fairings: Fairings,
pub(crate) figment: Figment,
pub(crate) config: Config,
pub(crate) state: TypeMap![Send + Sync],
pub(crate) shutdown: Shutdown,
}
}