diff --git a/Cargo.lock b/Cargo.lock index f493f4a..8205630 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -670,6 +670,13 @@ dependencies = [ "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "shared-failure" +version = "0.1.0" +dependencies = [ + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "shiny-robots" version = "0.1.0" @@ -690,6 +697,7 @@ dependencies = [ "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "shared-failure 0.1.0", "slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "slog-json 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index f5a6800..bfd8c46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,5 +28,9 @@ toml = "0.4.5" version = "0.2.0" path = "libs/badge" +[dependencies.shared-failure] +version = "0.1.0" +path = "libs/shared-failure" + [build-dependencies] sass-rs = "0.2.1" diff --git a/libs/shared-failure/Cargo.toml b/libs/shared-failure/Cargo.toml new file mode 100644 index 0000000..b03dd19 --- /dev/null +++ b/libs/shared-failure/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "shared-failure" +version = "0.1.0" +authors = ["Sam Rijs "] + +[dependencies] +failure = "0.1.1" diff --git a/libs/shared-failure/src/lib.rs b/libs/shared-failure/src/lib.rs new file mode 100644 index 0000000..8b728d0 --- /dev/null +++ b/libs/shared-failure/src/lib.rs @@ -0,0 +1,37 @@ +extern crate failure; + +use std::fmt::{Display, Formatter, Result as FmtResult}; +use std::sync::Arc; + +use failure::{Backtrace, Error, Fail}; + +#[derive(Clone, Debug)] +pub struct SharedFailure(Arc); + +impl SharedFailure { + pub fn downcast_ref(&self) -> Option<&T> { + self.0.downcast_ref() + } +} + +impl Fail for SharedFailure { + fn cause(&self) -> Option<&Fail> { + Some(self.0.cause()) + } + + fn backtrace(&self) -> Option<&Backtrace> { + Some(self.0.backtrace()) + } +} + +impl Display for SharedFailure { + fn fmt(&self, f: &mut Formatter) -> FmtResult { + self.0.fmt(f) + } +} + +impl From for SharedFailure { + fn from(err: Error) -> SharedFailure { + SharedFailure(Arc::new(err)) + } +} diff --git a/src/main.rs b/src/main.rs index dea0fa1..8ea8e0f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,6 +18,7 @@ extern crate semver; #[macro_use] extern crate serde_derive; extern crate serde; extern crate serde_json; +extern crate shared_failure; #[macro_use] extern crate slog; extern crate slog_json; extern crate tokio_core; diff --git a/src/utils/cache.rs b/src/utils/cache.rs index 89d2aab..a002159 100644 --- a/src/utils/cache.rs +++ b/src/utils/cache.rs @@ -1,13 +1,14 @@ -use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; +use std::fmt::{Debug, Formatter, Result as FmtResult}; use std::hash::Hash; use std::time::{Duration, Instant}; use std::ops::Deref; use std::sync::Mutex; -use failure::{Error, Fail}; +use failure::Error; use futures::{Future, Poll}; -use futures::future::{Shared, SharedError, SharedItem}; +use futures::future::{FromErr, Shared, SharedItem}; use lru_cache::LruCache; +use shared_failure::SharedFailure; use tokio_service::Service; pub struct Cache @@ -16,7 +17,7 @@ pub struct Cache { inner: S, duration: Duration, - cache: Mutex)>> + cache: Mutex>)>> } impl Debug for Cache @@ -50,7 +51,7 @@ impl Service for Cache { type Request = S::Request; type Response = CachedItem; - type Error = CachedError; + type Error = SharedFailure; type Future = Cached; fn call(&self, req: Self::Request) -> Self::Future { @@ -63,18 +64,17 @@ impl Service for Cache } } } - let shared_future = self.inner.call(req.clone()).shared(); + let shared_future = self.inner.call(req.clone()).from_err().shared(); cache.insert(req, (now + self.duration, shared_future.clone())); Cached(shared_future) } } -pub struct Cached(Shared); +pub struct Cached>(Shared>); impl Debug for Cached - where F: Future + Debug, - F::Item: Debug, - F::Error: Debug + where F: Future + Debug, + F::Item: Debug { fn fmt(&self, fmt: &mut Formatter) -> FmtResult { self.0.fmt(fmt) @@ -83,11 +83,11 @@ impl Debug for Cached impl> Future for Cached { type Item = CachedItem; - type Error = CachedError; + type Error = SharedFailure; fn poll(&mut self) -> Poll { self.0.poll() - .map_err(CachedError) + .map_err(|err| (*err).clone()) .map(|async| async.map(CachedItem)) } } @@ -102,26 +102,3 @@ impl Deref for CachedItem { &self.0.deref() } } - -#[derive(Debug)] -pub struct CachedError(SharedError); - -impl Fail for CachedError { - fn cause(&self) -> Option<&Fail> { - Some(self.0.cause()) - } - - fn backtrace(&self) -> Option<&::failure::Backtrace> { - Some(self.0.backtrace()) - } - - fn causes(&self) -> ::failure::Causes { - self.0.causes() - } -} - -impl Display for CachedError { - fn fmt(&self, f: &mut Formatter) -> FmtResult { - Display::fmt(&self.0, f) - } -}