move shared fail struct into own crate

This commit is contained in:
Sam Rijs 2018-02-24 14:12:28 +11:00
parent c7bc04efc1
commit bc75ceb9e2
6 changed files with 69 additions and 35 deletions

8
Cargo.lock generated
View file

@ -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)",

View file

@ -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"

View file

@ -0,0 +1,7 @@
[package]
name = "shared-failure"
version = "0.1.0"
authors = ["Sam Rijs <srijs@airpost.net>"]
[dependencies]
failure = "0.1.1"

View file

@ -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<Error>);
impl SharedFailure {
pub fn downcast_ref<T: Fail>(&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<Error> for SharedFailure {
fn from(err: Error) -> SharedFailure {
SharedFailure(Arc::new(err))
}
}

View file

@ -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;

View file

@ -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<S>
@ -16,7 +17,7 @@ pub struct Cache<S>
{
inner: S,
duration: Duration,
cache: Mutex<LruCache<S::Request, (Instant, Shared<S::Future>)>>
cache: Mutex<LruCache<S::Request, (Instant, Shared<FromErr<S::Future, SharedFailure>>)>>
}
impl<S> Debug for Cache<S>
@ -50,7 +51,7 @@ impl<S> Service for Cache<S>
{
type Request = S::Request;
type Response = CachedItem<S::Response>;
type Error = CachedError;
type Error = SharedFailure;
type Future = Cached<S::Future>;
fn call(&self, req: Self::Request) -> Self::Future {
@ -63,18 +64,17 @@ impl<S> Service for Cache<S>
}
}
}
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<F: Future>(Shared<F>);
pub struct Cached<F: Future<Error=Error>>(Shared<FromErr<F, SharedFailure>>);
impl<F> Debug for Cached<F>
where F: Future + Debug,
F::Item: Debug,
F::Error: Debug
where F: Future<Error=Error> + Debug,
F::Item: Debug
{
fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
self.0.fmt(fmt)
@ -83,11 +83,11 @@ impl<F> Debug for Cached<F>
impl<F: Future<Error=Error>> Future for Cached<F> {
type Item = CachedItem<F::Item>;
type Error = CachedError;
type Error = SharedFailure;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
self.0.poll()
.map_err(CachedError)
.map_err(|err| (*err).clone())
.map(|async| async.map(CachedItem))
}
}
@ -102,26 +102,3 @@ impl<T> Deref for CachedItem<T> {
&self.0.deref()
}
}
#[derive(Debug)]
pub struct CachedError(SharedError<Error>);
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)
}
}