tower_web/error/
map.rs

1use http::status::StatusCode;
2use util::BufStream;
3
4use futures::{Future, Poll};
5
6/// Map an arbitrary error type to [`Error`]
7///
8/// The conversion is done by treating all errors as "internal server errors".
9///
10/// [`Error`]: struct.Error.html
11#[derive(Debug)]
12pub struct Map<T> {
13    inner: State<T>,
14}
15
16#[derive(Debug)]
17enum State<T> {
18    Inner(T),
19    Immediate(Option<::Error>),
20}
21
22impl<T> Map<T> {
23    /// Create a new `Map` instance backed by `inner`.
24    ///
25    /// The returned value will map all errors generated by `inner` into
26    /// [`Error`] by treating them as "internal server errors".
27    ///
28    /// [`Error`]: struct.Error.html
29    pub fn new(inner: T) -> Map<T> {
30        Map {
31            inner: State::Inner(inner),
32        }
33    }
34
35    /// Create a neew `Map` instance that is in the error state.
36    ///
37    /// The instance will yield `error` immediately when it is used.
38    pub fn immediate(error: ::Error) -> Map<T> {
39        Map {
40            inner: State::Immediate(Some(error)),
41        }
42    }
43}
44
45impl<T: Future> Future for Map<T> {
46    type Item = T::Item;
47    type Error = ::Error;
48
49    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
50        use self::State::*;
51
52        match self.inner {
53            Inner(ref mut f) => f.poll().map_err(|_| ::Error::from(StatusCode::INTERNAL_SERVER_ERROR)),
54            Immediate(ref mut e) => Err(e.take().unwrap()),
55        }
56    }
57}
58
59impl<T: BufStream> BufStream for Map<T> {
60    type Item = T::Item;
61    type Error = ::Error;
62
63    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
64        use self::State::*;
65
66        match self.inner {
67            Inner(ref mut f) => f.poll().map_err(|_| ::Error::from(StatusCode::INTERNAL_SERVER_ERROR)),
68            Immediate(ref mut e) => Err(e.take().unwrap()),
69        }
70    }
71}