rocket/fairing/
fairings.rs
1use crate::{Rocket, Request, Response, Data, Build, Orbit};
2use crate::fairing::{Fairing, Info, Kind};
3
4#[derive(Default)]
5pub struct Fairings {
6 all_fairings: Vec<Box<dyn Fairing>>,
8 failures: Vec<Info>,
10 num_ignited: usize,
12 ignite: Vec<usize>,
14 liftoff: Vec<usize>,
15 request: Vec<usize>,
16 response: Vec<usize>,
17 shutdown: Vec<usize>,
18}
19
20macro_rules! iter {
21 ($_self:ident . $kind:ident) => ({
22 iter!($_self, $_self.$kind.iter().copied()).map(|v| v.1)
23 });
24 ($_self:ident, $indices:expr) => ({
25 let all_fairings = &$_self.all_fairings;
26 $indices.filter_map(move |i| {
27 let i = i.clone();
28 debug_assert!(all_fairings.get(i).is_some());
29 let f = all_fairings.get(i).map(|f| &**f)?;
30 Some((i, f))
31 })
32 })
33}
34
35impl Fairings {
36 #[inline]
37 pub fn new() -> Fairings {
38 Fairings::default()
39 }
40
41 pub fn active(&self) -> impl Iterator<Item = &usize> {
42 self.ignite.iter()
43 .chain(self.liftoff.iter())
44 .chain(self.request.iter())
45 .chain(self.response.iter())
46 .chain(self.shutdown.iter())
47 }
48
49 pub fn unique_active(&self) -> impl Iterator<Item = usize> {
50 let mut bitmap = vec![false; self.all_fairings.len()];
51 for i in self.active() {
52 bitmap.get_mut(*i).map(|active| *active = true);
53 }
54
55 bitmap.into_iter()
56 .enumerate()
57 .filter_map(|(i, active)| active.then_some(i))
58 }
59
60 pub fn unique_set(&self) -> Vec<&dyn Fairing> {
61 iter!(self, self.unique_active()).map(|v| v.1).collect()
62 }
63
64 pub fn add(&mut self, fairing: Box<dyn Fairing>) {
65 let this = &fairing;
66 let this_info = this.info();
67 if this_info.kind.is(Kind::Singleton) {
68 let ignite_dup = iter!(self.ignite).position(|f| f.type_id() == this.type_id());
79 if let Some(dup_ignite_index) = ignite_dup {
80 if dup_ignite_index < self.num_ignited {
81 self.failures.push(this_info);
82 return;
83 }
84 }
85
86 let remove = |k: usize, from: &mut Vec<usize>| {
88 if let Ok(j) = from.binary_search(&k) {
89 from.remove(j);
90 }
91 };
92
93 let mut dups: Vec<usize> = iter!(self, self.unique_active())
95 .filter(|(_, f)| f.type_id() == this.type_id())
96 .map(|(i, _)| i)
97 .collect();
98
99 dups.sort(); dups.dedup(); dups.reverse();
101 for i in dups {
102 remove(i, &mut self.ignite);
103 remove(i, &mut self.liftoff);
104 remove(i, &mut self.request);
105 remove(i, &mut self.response);
106 remove(i, &mut self.shutdown);
107 }
108 }
109
110 let index = self.all_fairings.len();
111 self.all_fairings.push(fairing);
112 if this_info.kind.is(Kind::Ignite) { self.ignite.push(index); }
113 if this_info.kind.is(Kind::Liftoff) { self.liftoff.push(index); }
114 if this_info.kind.is(Kind::Request) { self.request.push(index); }
115 if this_info.kind.is(Kind::Response) { self.response.push(index); }
116 if this_info.kind.is(Kind::Shutdown) { self.shutdown.push(index); }
117 }
118
119 pub fn append(&mut self, others: &mut Fairings) {
120 for fairing in others.all_fairings.drain(..) {
121 self.add(fairing);
122 }
123 }
124
125 pub async fn handle_ignite(mut rocket: Rocket<Build>) -> Rocket<Build> {
126 while rocket.fairings.num_ignited < rocket.fairings.ignite.len() {
127 let mut fairings = std::mem::replace(&mut rocket.fairings, Fairings::new());
129 for fairing in iter!(fairings.ignite).skip(fairings.num_ignited) {
130 let info = fairing.info();
131 rocket = match fairing.on_ignite(rocket).await {
132 Ok(rocket) => rocket,
133 Err(rocket) => {
134 fairings.failures.push(info);
135 rocket
136 }
137 };
138
139 fairings.num_ignited += 1;
140 }
141
142 fairings.append(&mut rocket.fairings);
145 rocket.fairings = fairings;
146 }
147
148 rocket
149 }
150
151 #[inline(always)]
152 pub async fn handle_liftoff(&self, rocket: &Rocket<Orbit>) {
153 let liftoff_futures = iter!(self.liftoff).map(|f| f.on_liftoff(rocket));
154 futures::future::join_all(liftoff_futures).await;
155 }
156
157 #[inline(always)]
158 pub async fn handle_request(&self, req: &mut Request<'_>, data: &mut Data<'_>) {
159 for fairing in iter!(self.request) {
160 fairing.on_request(req, data).await
161 }
162 }
163
164 #[inline(always)]
165 pub async fn handle_response<'r>(&self, req: &'r Request<'_>, res: &mut Response<'r>) {
166 for fairing in iter!(self.response) {
167 fairing.on_response(req, res).await;
168 }
169 }
170
171 #[inline(always)]
172 pub async fn handle_shutdown(&self, rocket: &Rocket<Orbit>) {
173 let shutdown_futures = iter!(self.shutdown).map(|f| f.on_shutdown(rocket));
174 futures::future::join_all(shutdown_futures).await;
175 }
176
177 pub fn audit(&self) -> Result<(), &[Info]> {
178 match &self.failures[..] {
179 [] => Ok(()),
180 failures => Err(failures)
181 }
182 }
183
184 pub fn filter<F: Fairing>(&self) -> impl Iterator<Item = &F> {
185 iter!(self, self.unique_active())
186 .filter_map(|v| v.1.downcast_ref::<F>())
187 }
188
189 pub fn filter_mut<F: Fairing>(&mut self) -> impl Iterator<Item = &mut F> {
190 let mut bitmap = vec![false; self.all_fairings.len()];
191 for &i in self.active() {
192 let is_target = self.all_fairings.get(i)
193 .and_then(|f| f.downcast_ref::<F>())
194 .is_some();
195
196 bitmap.get_mut(i).map(|target| *target = is_target);
197 }
198
199 self.all_fairings.iter_mut()
200 .enumerate()
201 .filter(move |(i, _)| *bitmap.get(*i).unwrap_or(&false))
202 .filter_map(|(_, f)| f.downcast_mut::<F>())
203 }
204}
205
206impl std::fmt::Debug for Fairings {
207 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
208 fn debug_info<'a>(iter: impl Iterator<Item = &'a dyn Fairing>) -> Vec<Info> {
209 iter.map(|f| f.info()).collect()
210 }
211
212 f.debug_struct("Fairings")
213 .field("launch", &debug_info(iter!(self.ignite)))
214 .field("liftoff", &debug_info(iter!(self.liftoff)))
215 .field("request", &debug_info(iter!(self.request)))
216 .field("response", &debug_info(iter!(self.response)))
217 .field("shutdown", &debug_info(iter!(self.shutdown)))
218 .finish()
219 }
220}