mirror of https://github.com/rwf2/Rocket.git
Remove use of 'unsafe' in 'Fairings'.
This commit is contained in:
parent
f8c36f5c67
commit
aaad4f5c57
|
@ -1,13 +1,16 @@
|
||||||
use {Rocket, Request, Response, Data};
|
use {Rocket, Request, Response, Data};
|
||||||
use fairing::{Fairing, Kind};
|
use fairing::{Fairing, Kind};
|
||||||
|
|
||||||
|
use yansi::Paint;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Fairings {
|
pub struct Fairings {
|
||||||
all_fairings: Vec<Box<Fairing>>,
|
all_fairings: Vec<Box<Fairing>>,
|
||||||
attach_failures: Vec<&'static str>,
|
attach_failures: Vec<&'static str>,
|
||||||
launch: Vec<&'static Fairing>,
|
// The vectors below hold indices into `all_fairings`.
|
||||||
request: Vec<&'static Fairing>,
|
launch: Vec<usize>,
|
||||||
response: Vec<&'static Fairing>,
|
request: Vec<usize>,
|
||||||
|
response: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fairings {
|
impl Fairings {
|
||||||
|
@ -30,32 +33,14 @@ impl Fairings {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(&mut self, fairing: Box<Fairing>) {
|
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;
|
let kind = fairing.info().kind;
|
||||||
if !kind.is_exactly(Kind::Attach) {
|
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);
|
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::Launch) { self.launch.push(index); }
|
||||||
if kind.is(Kind::Response) { self.response.push(ptr); }
|
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)]
|
#[inline(always)]
|
||||||
pub fn handle_launch(&self, rocket: &Rocket) {
|
pub fn handle_launch(&self, rocket: &Rocket) {
|
||||||
for fairing in &self.launch {
|
for &i in &self.launch {
|
||||||
fairing.on_launch(rocket);
|
self.all_fairings[i].on_launch(rocket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn handle_request(&self, req: &mut Request, data: &Data) {
|
pub fn handle_request(&self, req: &mut Request, data: &Data) {
|
||||||
for fairing in &self.request {
|
for &i in &self.request {
|
||||||
fairing.on_request(req, data);
|
self.all_fairings[i].on_request(req, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn handle_response(&self, request: &Request, response: &mut Response) {
|
pub fn handle_response(&self, request: &Request, response: &mut Response) {
|
||||||
for fairing in &self.response {
|
for &i in &self.response {
|
||||||
fairing.on_response(request, response);
|
self.all_fairings[i].on_response(request, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,14 +79,11 @@ impl Fairings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pretty_print_counts(&self) {
|
fn info_for(&self, kind: &str, fairings: &[usize]) {
|
||||||
use yansi::Paint;
|
|
||||||
|
|
||||||
fn info_if_nonempty(kind: &str, fairings: &[&Fairing]) {
|
|
||||||
if !fairings.is_empty() {
|
if !fairings.is_empty() {
|
||||||
let num = fairings.len();
|
let num = fairings.len();
|
||||||
let names = fairings.iter()
|
let names = fairings.iter().cloned()
|
||||||
.map(|f| f.info().name)
|
.map(|i| self.all_fairings[i].info().name)
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
|
|
||||||
|
@ -109,11 +91,12 @@ impl Fairings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pretty_print_counts(&self) {
|
||||||
if !self.all_fairings.is_empty() {
|
if !self.all_fairings.is_empty() {
|
||||||
info!("{}{}:", Paint::masked("📡 "), Paint::purple("Fairings"));
|
info!("{}{}:", Paint::masked("📡 "), Paint::purple("Fairings"));
|
||||||
info_if_nonempty("launch", &self.launch);
|
self.info_for("launch", &self.launch);
|
||||||
info_if_nonempty("request", &self.request);
|
self.info_for("request", &self.request);
|
||||||
info_if_nonempty("response", &self.response);
|
self.info_for("response", &self.response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue