Skip to content
Snippets Groups Projects
Commit 8fec8a92 authored by Carl Lerche's avatar Carl Lerche
Browse files

Implement iterator adapter for `Buf`

parent 4f8c5651
No related branches found
No related tags found
No related merge requests found
use super::{Take, Reader, FromBuf}; use super::{Take, Reader, Iter, FromBuf};
use byteorder::ByteOrder; use byteorder::ByteOrder;
use std::{cmp, ptr}; use std::{cmp, ptr};
...@@ -546,4 +546,23 @@ pub trait Buf { ...@@ -546,4 +546,23 @@ pub trait Buf {
fn reader(self) -> Reader<Self> where Self: Sized { fn reader(self) -> Reader<Self> where Self: Sized {
super::reader::new(self) super::reader::new(self)
} }
/// Returns an iterator over the bytes contained by the buffer.
///
/// # Examples
///
/// ```
/// use bytes::{Buf, IntoBuf, Bytes};
///
/// let buf = Bytes::from(&b"abc"[..]).into_buf();
/// let mut iter = buf.iter();
///
/// assert_eq!(iter.next(), Some(b'a'));
/// assert_eq!(iter.next(), Some(b'b'));
/// assert_eq!(iter.next(), Some(b'c'));
/// assert_eq!(iter.next(), None);
/// ```
fn iter(self) -> Iter<Self> where Self: Sized {
super::iter::new(self)
}
} }
use Buf;
/// Iterator over the bytes contained by the buffer.
///
/// This struct is created by the [`iter`] method on [`Buf`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use bytes::{Buf, IntoBuf, Bytes};
///
/// let buf = Bytes::from(&b"abc"[..]).into_buf();
/// let mut iter = buf.iter();
///
/// assert_eq!(iter.next(), Some(b'a'));
/// assert_eq!(iter.next(), Some(b'b'));
/// assert_eq!(iter.next(), Some(b'c'));
/// assert_eq!(iter.next(), None);
/// ```
///
/// [`iter`]: trait.Buf.html#method.iter
/// [`Buf`]: trait.Buf.html
pub struct Iter<T> {
inner: T,
}
impl<T> Iter<T> {
/// Consumes this `Iter`, returning the underlying value.
///
/// # Examples
///
/// ```rust
/// use bytes::{Buf, IntoBuf, Bytes};
///
/// let buf = Bytes::from(&b"abc"[..]).into_buf();
/// let mut iter = buf.iter();
///
/// assert_eq!(iter.next(), Some(b'a'));
///
/// let buf = iter.into_inner();
/// assert_eq!(2, buf.remaining());
/// ```
pub fn into_inner(self) -> T {
self.inner
}
/// Gets a reference to the underlying `Buf`.
///
/// It is inadvisable to directly read from the underlying `Buf`.
///
/// # Examples
///
/// ```rust
/// use bytes::{Buf, IntoBuf, Bytes};
///
/// let buf = Bytes::from(&b"abc"[..]).into_buf();
/// let mut iter = buf.iter();
///
/// assert_eq!(iter.next(), Some(b'a'));
///
/// assert_eq!(2, iter.get_ref().remaining());
/// ```
pub fn get_ref(&self) -> &T {
&self.inner
}
/// Gets a mutable reference to the underlying `Buf`.
///
/// It is inadvisable to directly read from the underlying `Buf`.
///
/// # Examples
///
/// ```rust
/// use bytes::{Buf, IntoBuf, BytesMut};
///
/// let buf = BytesMut::from(&b"abc"[..]).into_buf();
/// let mut iter = buf.iter();
///
/// assert_eq!(iter.next(), Some(b'a'));
///
/// iter.get_mut().set_position(0);
///
/// assert_eq!(iter.next(), Some(b'a'));
/// ```
pub fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
}
pub fn new<T>(inner: T) -> Iter<T> {
Iter { inner: inner }
}
impl<T: Buf> Iterator for Iter<T> {
type Item = u8;
fn next(&mut self) -> Option<u8> {
if !self.inner.has_remaining() {
return None;
}
let b = self.inner.bytes()[0];
self.inner.advance(1);
Some(b)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let rem = self.inner.remaining();
(rem, Some(rem))
}
}
...@@ -22,6 +22,7 @@ mod buf; ...@@ -22,6 +22,7 @@ mod buf;
mod buf_mut; mod buf_mut;
mod from_buf; mod from_buf;
mod into_buf; mod into_buf;
mod iter;
mod reader; mod reader;
mod source; mod source;
mod take; mod take;
...@@ -31,6 +32,7 @@ pub use self::buf::Buf; ...@@ -31,6 +32,7 @@ pub use self::buf::Buf;
pub use self::buf_mut::BufMut; pub use self::buf_mut::BufMut;
pub use self::from_buf::FromBuf; pub use self::from_buf::FromBuf;
pub use self::into_buf::IntoBuf; pub use self::into_buf::IntoBuf;
pub use self::iter::Iter;
pub use self::reader::Reader; pub use self::reader::Reader;
pub use self::source::Source; pub use self::source::Source;
pub use self::take::Take; pub use self::take::Take;
......
use {IntoBuf, BufMut}; use {IntoBuf, Buf, BufMut};
use buf::Iter;
use std::{cmp, fmt, mem, hash, ops, slice, ptr, usize}; use std::{cmp, fmt, mem, hash, ops, slice, ptr, usize};
use std::borrow::Borrow; use std::borrow::Borrow;
...@@ -733,6 +734,24 @@ impl Borrow<[u8]> for Bytes { ...@@ -733,6 +734,24 @@ impl Borrow<[u8]> for Bytes {
} }
} }
impl IntoIterator for Bytes {
type Item = u8;
type IntoIter = Iter<Cursor<Bytes>>;
fn into_iter(self) -> Self::IntoIter {
self.into_buf().iter()
}
}
impl<'a> IntoIterator for &'a Bytes {
type Item = u8;
type IntoIter = Iter<Cursor<&'a Bytes>>;
fn into_iter(self) -> Self::IntoIter {
self.into_buf().iter()
}
}
/* /*
* *
* ===== BytesMut ===== * ===== BytesMut =====
...@@ -1286,6 +1305,24 @@ impl Clone for BytesMut { ...@@ -1286,6 +1305,24 @@ impl Clone for BytesMut {
} }
} }
impl IntoIterator for BytesMut {
type Item = u8;
type IntoIter = Iter<Cursor<BytesMut>>;
fn into_iter(self) -> Self::IntoIter {
self.into_buf().iter()
}
}
impl<'a> IntoIterator for &'a BytesMut {
type Item = u8;
type IntoIter = Iter<Cursor<&'a BytesMut>>;
fn into_iter(self) -> Self::IntoIter {
self.into_buf().iter()
}
}
/* /*
* *
* ===== Inner ===== * ===== Inner =====
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment