rocket/
phase.rs

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