use state::TypeMap;
use figment::Figment;
use crate::listener::Endpoint;
use crate::shutdown::Stages;
use crate::{Catcher, Config, Rocket, Route};
use crate::router::{Router, Finalized};
use crate::fairing::Fairings;
mod private {
pub trait Sealed { }
}
#[doc(hidden)]
pub trait Stateful: private::Sealed {
fn into_state(self) -> State;
fn as_ref(&self) -> StateRef<'_>;
fn as_mut(&mut self) -> StateRefMut<'_>;
}
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_ref(&self) -> StateRef<'_> { StateRef::$P(self) }
fn as_mut(&mut self) -> StateRefMut<'_> { StateRefMut::$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)),* }
#[doc(hidden)]
pub enum StateRefMut<'a> { $($P(&'a mut $S)),* }
$(phase!($(#[$o])* $P ($(#[$i])* $S) { $($fields)* });)*
)
}
phases! {
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],
}
Ignite (#[derive(Debug)] Igniting) {
pub(crate) router: Router<Finalized>,
pub(crate) fairings: Fairings,
pub(crate) figment: Figment,
pub(crate) config: Config,
pub(crate) state: TypeMap![Send + Sync],
pub(crate) shutdown: Stages,
}
Orbit (#[derive(Debug)] Orbiting) {
pub(crate) router: Router<Finalized>,
pub(crate) fairings: Fairings,
pub(crate) figment: Figment,
pub(crate) config: Config,
pub(crate) state: TypeMap![Send + Sync],
pub(crate) shutdown: Stages,
pub(crate) endpoints: Vec<Endpoint>,
}
}