tower_web/extract/
option.rs

1//! Types used to extract `Option` values from an HTTP request.
2
3use extract::{Extract, ExtractFuture, Error, Context};
4use util::BufStream;
5
6use futures::{Async, Poll};
7
8/// Extract an `Option` value from an HTTP request.
9#[derive(Debug)]
10pub struct ExtractOptionFuture<T> {
11    inner: T,
12    none: bool,
13}
14
15impl<T, B: BufStream> Extract<B> for Option<T>
16where T: Extract<B>,
17{
18    type Future = ExtractOptionFuture<T::Future>;
19
20    fn extract(ctx: &Context) -> Self::Future {
21        ExtractOptionFuture {
22            inner: T::extract(ctx),
23            none: false,
24        }
25    }
26}
27
28impl<T> ExtractFuture for ExtractOptionFuture<T>
29where T: ExtractFuture,
30{
31    type Item = Option<T::Item>;
32
33    fn poll(&mut self) -> Poll<(), Error> {
34        match self.inner.poll() {
35            Err(ref e) if e.is_missing_argument() => {
36                self.none = true;
37                Ok(Async::Ready(()))
38            }
39            res => res,
40        }
41    }
42
43    fn extract(self) -> Self::Item {
44        if self.none {
45            None
46        } else {
47            Some(self.inner.extract())
48        }
49    }
50}