use BufStream; use bytes::Buf; use futures::Poll; /// Limits the stream to a maximum amount of data. #[derive(Debug)] pub struct Limit { stream: T, remaining: u64, } /// Errors returned from `Limit`. #[derive(Debug)] pub struct LimitError { /// When `None`, limit was reached inner: Option, } impl Limit { pub(crate) fn new(stream: T, amount: u64) -> Limit { Limit { stream, remaining: amount, } } } impl BufStream for Limit where T: BufStream, { type Item = T::Item; type Error = LimitError; fn poll_buf(&mut self) -> Poll, Self::Error> { use futures::Async::Ready; if self.stream.size_hint().lower() > self.remaining { return Err(LimitError { inner: None }); } let res = self .stream .poll_buf() .map_err(|err| LimitError { inner: Some(err) }); match res { Ok(Ready(Some(ref buf))) => { if buf.remaining() as u64 > self.remaining { self.remaining = 0; return Err(LimitError { inner: None }); } self.remaining -= buf.remaining() as u64; } _ => {} } res } } // ===== impl LimitError ===== impl LimitError { /// Returns `true` if the error was caused by polling the stream. pub fn is_stream_err(&self) -> bool { self.inner.is_some() } /// Returns `true` if the stream reached its limit. pub fn is_limit_err(&self) -> bool { self.inner.is_none() } }