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,
}
}