Files
adler32
backtrace
backtrace_sys
base64
bigtable
bitflags
byteorder
bytes
cfg_if
cookie
cookie_store
crc32fast
crossbeam_deque
crossbeam_epoch
crossbeam_queue
crossbeam_utils
curl
curl_sys
dtoa
either
encoding_rs
error_chain
failure
failure_derive
flate2
fnv
foreign_types
foreign_types_shared
futures
futures_cpupool
goauth
h2
http
http_body
httparse
hyper
hyper_tls
idna
indexmap
iovec
itoa
lazy_static
libc
libz_sys
lock_api
log
matches
maybe_uninit
memoffset
mime
mime_guess
miniz_oxide
mio
native_tls
net2
num_cpus
num_traits
openssl
openssl_probe
openssl_sys
parking_lot
parking_lot_core
percent_encoding
proc_macro2
protobuf
protobuf_json
publicsuffix
quote
rand
rand_chacha
rand_core
rand_hc
rand_isaac
rand_jitter
rand_os
rand_pcg
rand_xorshift
regex
regex_syntax
reqwest
rustc_demangle
rustc_serialize
ryu
scopeguard
serde
serde_codegen_internals
serde_derive
serde_json
serde_urlencoded
slab
smallvec
smpl_jwt
socket2
string
syn
synom
synstructure
time
tokio
tokio_buf
tokio_current_thread
tokio_executor
tokio_io
tokio_reactor
tokio_sync
tokio_tcp
tokio_threadpool
tokio_timer
try_from
try_lock
unicase
unicode_bidi
unicode_normalization
unicode_xid
url
uuid
want
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
use super::FromBufStream;
use BufStream;

use futures::{Future, Poll};

/// Consumes a buf stream, collecting the data into a single byte container.
///
/// `Collect` values are produced by `BufStream::collect`.
#[derive(Debug)]
pub struct Collect<T, U>
where
    T: BufStream,
    U: FromBufStream<T::Item>,
{
    stream: T,
    builder: Option<U::Builder>,
}

/// Errors returned from `Collect` future.
#[derive(Debug)]
pub struct CollectError<T, U> {
    inner: Error<T, U>,
}

#[derive(Debug)]
enum Error<T, U> {
    Stream(T),
    Collect(U),
}

impl<T, U> Collect<T, U>
where
    T: BufStream,
    U: FromBufStream<T::Item>,
{
    pub(crate) fn new(stream: T) -> Collect<T, U> {
        let builder = U::builder(&stream.size_hint());

        Collect {
            stream,
            builder: Some(builder),
        }
    }
}

impl<T, U> Future for Collect<T, U>
where
    T: BufStream,
    U: FromBufStream<T::Item>,
{
    type Item = U;
    type Error = CollectError<T::Error, U::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        loop {
            let res = self.stream.poll_buf().map_err(|err| {
                let inner = Error::Stream(err);
                CollectError { inner }
            });

            match try_ready!(res) {
                Some(mut buf) => {
                    let builder = self.builder.as_mut().expect("cannot poll after done");

                    U::extend(builder, &mut buf, &self.stream.size_hint()).map_err(|err| {
                        let inner = Error::Collect(err);
                        CollectError { inner }
                    })?;
                }
                None => {
                    let builder = self.builder.take().expect("cannot poll after done");
                    let value = U::build(builder).map_err(|err| {
                        let inner = Error::Collect(err);
                        CollectError { inner }
                    })?;
                    return Ok(value.into());
                }
            }
        }
    }
}

// ===== impl CollectError =====

impl<T, U> CollectError<T, U> {
    /// Returns `true` if the error was caused by polling the stream.
    pub fn is_stream_err(&self) -> bool {
        match self.inner {
            Error::Stream(_) => true,
            _ => false,
        }
    }

    /// Returns `true` if the error happened while collecting the data.
    pub fn is_collect_err(&self) -> bool {
        match self.inner {
            Error::Collect(_) => true,
            _ => false,
        }
    }
}