Rocket

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit aaad4f5c57bd4b4dcf8e564adabcf0d5aba46161
parent f8c36f5c67041905e8aad8efe817f0a354c27d01
Author: Sergio Benitez <sb@sergio.bz>
Date:   Sun, 22 Jul 2018 04:28:02 -0700

Remove use of 'unsafe' in 'Fairings'.

Diffstat:
Mcore/lib/src/fairing/fairings.rs | 77++++++++++++++++++++++++++++++-----------------------------------------------
1 file changed, 30 insertions(+), 47 deletions(-)

diff --git a/core/lib/src/fairing/fairings.rs b/core/lib/src/fairing/fairings.rs @@ -1,13 +1,16 @@ use {Rocket, Request, Response, Data}; use fairing::{Fairing, Kind}; +use yansi::Paint; + #[derive(Default)] pub struct Fairings { all_fairings: Vec<Box<Fairing>>, attach_failures: Vec<&'static str>, - launch: Vec<&'static Fairing>, - request: Vec<&'static Fairing>, - response: Vec<&'static Fairing>, + // The vectors below hold indices into `all_fairings`. + launch: Vec<usize>, + request: Vec<usize>, + response: Vec<usize>, } impl Fairings { @@ -30,32 +33,14 @@ impl Fairings { } fn add(&mut self, fairing: Box<Fairing>) { - // The `Fairings` structure separates `all_fairings` into kind groups so - // we don't have to search through all fairings and do a comparison at - // runtime. We need references since a single structure can be multiple - // kinds. The lifetime of that reference is really the lifetime of the - // `Box` for referred fairing, but that lifetime is dynamic; there's no - // way to express it. So we cheat and say that the lifetime is - // `'static` and cast it here. For this to be safe, the following must - // be preserved: - // - // 1) The references can never be exposed with a `'static` lifetime. - // 2) The `Box<Fairing>` must live for the lifetime of the reference. - // - // We maintain these invariants by not exposing the references and never - // deallocating `Box<Fairing>` structures. As such, the references will - // always be valid. Note: `ptr` doesn't point into the `Vec`, so - // reallocations there are irrelevant. Instead, it points into the heap. - // - // Also, we don't save attach fairings since we don't need them anymore. let kind = fairing.info().kind; if !kind.is_exactly(Kind::Attach) { - let ptr: &'static Fairing = unsafe { ::std::mem::transmute(&*fairing) }; - + let index = self.all_fairings.len(); self.all_fairings.push(fairing); - if kind.is(Kind::Launch) { self.launch.push(ptr); } - if kind.is(Kind::Request) { self.request.push(ptr); } - if kind.is(Kind::Response) { self.response.push(ptr); } + + if kind.is(Kind::Launch) { self.launch.push(index); } + if kind.is(Kind::Request) { self.request.push(index); } + if kind.is(Kind::Response) { self.response.push(index); } } } @@ -67,22 +52,22 @@ impl Fairings { #[inline(always)] pub fn handle_launch(&self, rocket: &Rocket) { - for fairing in &self.launch { - fairing.on_launch(rocket); + for &i in &self.launch { + self.all_fairings[i].on_launch(rocket); } } #[inline(always)] pub fn handle_request(&self, req: &mut Request, data: &Data) { - for fairing in &self.request { - fairing.on_request(req, data); + for &i in &self.request { + self.all_fairings[i].on_request(req, data); } } #[inline(always)] pub fn handle_response(&self, request: &Request, response: &mut Response) { - for fairing in &self.response { - fairing.on_response(request, response); + for &i in &self.response { + self.all_fairings[i].on_response(request, response); } } @@ -94,26 +79,24 @@ impl Fairings { } } - pub fn pretty_print_counts(&self) { - use yansi::Paint; + fn info_for(&self, kind: &str, fairings: &[usize]) { + if !fairings.is_empty() { + let num = fairings.len(); + let names = fairings.iter().cloned() + .map(|i| self.all_fairings[i].info().name) + .collect::<Vec<_>>() + .join(", "); - fn info_if_nonempty(kind: &str, fairings: &[&Fairing]) { - if !fairings.is_empty() { - let num = fairings.len(); - let names = fairings.iter() - .map(|f| f.info().name) - .collect::<Vec<_>>() - .join(", "); - - info_!("{} {}: {}", Paint::white(num), kind, Paint::white(names)); - } + info_!("{} {}: {}", Paint::white(num), kind, Paint::white(names)); } + } + pub fn pretty_print_counts(&self) { if !self.all_fairings.is_empty() { info!("{}{}:", Paint::masked("📡 "), Paint::purple("Fairings")); - info_if_nonempty("launch", &self.launch); - info_if_nonempty("request", &self.request); - info_if_nonempty("response", &self.response); + self.info_for("launch", &self.launch); + self.info_for("request", &self.request); + self.info_for("response", &self.response); } } }