diff --git a/lib/src/fairing/ad_hoc.rs b/lib/src/fairing/ad_hoc.rs index 82e2789f..1a0822a3 100644 --- a/lib/src/fairing/ad_hoc.rs +++ b/lib/src/fairing/ad_hoc.rs @@ -1,3 +1,6 @@ +use std::sync::Mutex; +use std::boxed::FnBox; + use {Rocket, Request, Response, Data}; use fairing::{Fairing, Kind, Info}; @@ -35,10 +38,10 @@ use fairing::{Fairing, Kind, Info}; pub enum AdHoc { /// An ad-hoc **attach** fairing. Called when the fairing is attached. #[doc(hidden)] - Attach(Box Result + Send + Sync + 'static>), + Attach(Mutex Result + Send + 'static>>>), /// An ad-hoc **launch** fairing. Called just before Rocket launches. #[doc(hidden)] - Launch(Box), + Launch(Mutex>>), /// An ad-hoc **request** fairing. Called when a request is received. #[doc(hidden)] Request(Box), @@ -61,9 +64,9 @@ impl AdHoc { /// let fairing = AdHoc::on_attach(|rocket| Ok(rocket)); /// ``` pub fn on_attach(f: F) -> AdHoc - where F: Fn(Rocket) -> Result + Send + Sync + 'static + where F: FnOnce(Rocket) -> Result + Send + 'static { - AdHoc::Attach(Box::new(f)) + AdHoc::Attach(Mutex::new(Some(Box::new(f)))) } /// Constructs an `AdHoc` launch fairing. The function `f` will be called by @@ -80,9 +83,9 @@ impl AdHoc { /// }); /// ``` pub fn on_launch(f: F) -> AdHoc - where F: Fn(&Rocket) + Send + Sync + 'static + where F: FnOnce(&Rocket) + Send + 'static { - AdHoc::Launch(Box::new(f)) + AdHoc::Launch(Mutex::new(Some(Box::new(f)))) } /// Constructs an `AdHoc` request fairing. The function `f` will be called @@ -158,15 +161,22 @@ impl Fairing for AdHoc { } fn on_attach(&self, rocket: Rocket) -> Result { - match *self { - AdHoc::Attach(ref callback) => callback(rocket), - _ => Ok(rocket), + if let AdHoc::Attach(ref mutex) = *self { + let mut option = mutex.lock().expect("AdHoc::Attach lock"); + option.take() + .expect("internal error: `on_attach` single-call invariant broken") + .call_box((rocket,)) + } else { + Ok(rocket) } } fn on_launch(&self, rocket: &Rocket) { - if let AdHoc::Launch(ref callback) = *self { - callback(rocket) + if let AdHoc::Launch(ref mutex) = *self { + let mut option = mutex.lock().expect("AdHoc::Launch lock"); + option.take() + .expect("internal error: `on_launch` single-call invariant broken") + .call_box((rocket, )) } } diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 2beb44a5..d25b3fb6 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -2,6 +2,7 @@ #![feature(const_fn)] #![feature(plugin, decl_macro)] #![feature(try_trait)] +#![feature(fnbox)] #![recursion_limit="256"] #![plugin(pear_codegen)]