Skip to content

Commit

Permalink
Add HomogeneousTuple trait.
Browse files Browse the repository at this point in the history
Allows clients to use certain tuple methods of `Itertools` in more
generic contexts.

This trait serves as a public facade for `TupleCollect`, an
internal implementation detail.

Fixes #387.
  • Loading branch information
jswrenn committed Dec 6, 2019
1 parent 775274c commit 1119de5
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 15 deletions.
14 changes: 10 additions & 4 deletions src/lib.rs
Expand Up @@ -137,6 +137,12 @@ pub mod structs {
pub use zip_longest::ZipLongest;
pub use ziptuple::Zip;
}

/// Traits helpful for using certain `Itertools` methods in generic contexts.
pub mod traits {
pub use ::tuple_impl::HomogeneousTuple;
}

#[allow(deprecated)]
pub use structs::*;
pub use concat_impl::concat;
Expand Down Expand Up @@ -588,7 +594,7 @@ pub trait Itertools : Iterator {
/// ```
fn tuple_windows<T>(self) -> TupleWindows<Self, T>
where Self: Sized + Iterator<Item = T::Item>,
T: tuple_impl::TupleCollect,
T: traits::HomogeneousTuple,
T::Item: Clone
{
tuple_impl::tuple_windows(self)
Expand Down Expand Up @@ -627,7 +633,7 @@ pub trait Itertools : Iterator {
/// See also [`Tuples::into_buffer`](structs/struct.Tuples.html#method.into_buffer).
fn tuples<T>(self) -> Tuples<Self, T>
where Self: Sized + Iterator<Item = T::Item>,
T: tuple_impl::TupleCollect
T: traits::HomogeneousTuple
{
tuple_impl::tuples(self)
}
Expand Down Expand Up @@ -1352,7 +1358,7 @@ pub trait Itertools : Iterator {
/// ```
fn next_tuple<T>(&mut self) -> Option<T>
where Self: Sized + Iterator<Item = T::Item>,
T: tuple_impl::TupleCollect
T: traits::HomogeneousTuple
{
T::collect_from_iter_no_buf(self)
}
Expand All @@ -1377,7 +1383,7 @@ pub trait Itertools : Iterator {
/// ```
fn collect_tuple<T>(mut self) -> Option<T>
where Self: Sized + Iterator<Item = T::Item>,
T: tuple_impl::TupleCollect
T: traits::HomogeneousTuple
{
match self.next_tuple() {
elt @ Some(_) => match self.next() {
Expand Down
34 changes: 23 additions & 11 deletions src/tuple_impl.rs
Expand Up @@ -2,20 +2,32 @@

use std::iter::Fuse;

// `HomogeneousTuple` is a public facade for `TupleCollect`, allowing
// tuple-related methods to be used by clients in generic contexts, while
// hiding the implementation details of `TupleCollect`.
// See https://github.com/rust-itertools/itertools/issues/387

/// Implemented for homogeneous tuples of size up to 4.
pub trait HomogeneousTuple
: TupleCollect
{}

impl<T: TupleCollect> HomogeneousTuple for T {}

/// An iterator over a incomplete tuple.
///
/// See [`.tuples()`](../trait.Itertools.html#method.tuples) and
/// [`Tuples::into_buffer()`](struct.Tuples.html#method.into_buffer).
#[derive(Debug)]
pub struct TupleBuffer<T>
where T: TupleCollect
where T: HomogeneousTuple
{
cur: usize,
buf: T::Buffer,
}

impl<T> TupleBuffer<T>
where T: TupleCollect
where T: HomogeneousTuple
{
fn new(buf: T::Buffer) -> Self {
TupleBuffer {
Expand All @@ -26,7 +38,7 @@ impl<T> TupleBuffer<T>
}

impl<T> Iterator for TupleBuffer<T>
where T: TupleCollect
where T: HomogeneousTuple
{
type Item = T::Item;

Expand Down Expand Up @@ -54,7 +66,7 @@ impl<T> Iterator for TupleBuffer<T>
}

impl<T> ExactSizeIterator for TupleBuffer<T>
where T: TupleCollect
where T: HomogeneousTuple
{
}

Expand All @@ -64,7 +76,7 @@ impl<T> ExactSizeIterator for TupleBuffer<T>
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Tuples<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect
T: HomogeneousTuple
{
iter: Fuse<I>,
buf: T::Buffer,
Expand All @@ -73,7 +85,7 @@ pub struct Tuples<I, T>
/// Create a new tuples iterator.
pub fn tuples<I, T>(iter: I) -> Tuples<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect
T: HomogeneousTuple
{
Tuples {
iter: iter.fuse(),
Expand All @@ -83,7 +95,7 @@ pub fn tuples<I, T>(iter: I) -> Tuples<I, T>

impl<I, T> Iterator for Tuples<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect
T: HomogeneousTuple
{
type Item = T;

Expand All @@ -94,7 +106,7 @@ impl<I, T> Iterator for Tuples<I, T>

impl<I, T> Tuples<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect
T: HomogeneousTuple
{
/// Return a buffer with the produced items that was not enough to be grouped in a tuple.
///
Expand All @@ -120,7 +132,7 @@ impl<I, T> Tuples<I, T>
#[derive(Debug)]
pub struct TupleWindows<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect
T: HomogeneousTuple
{
iter: I,
last: Option<T>,
Expand All @@ -129,7 +141,7 @@ pub struct TupleWindows<I, T>
/// Create a new tuple windows iterator.
pub fn tuple_windows<I, T>(mut iter: I) -> TupleWindows<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect,
T: HomogeneousTuple,
T::Item: Clone
{
use std::iter::once;
Expand All @@ -152,7 +164,7 @@ pub fn tuple_windows<I, T>(mut iter: I) -> TupleWindows<I, T>

impl<I, T> Iterator for TupleWindows<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect + Clone,
T: HomogeneousTuple + Clone,
T::Item: Clone
{
type Item = T;
Expand Down

0 comments on commit 1119de5

Please sign in to comment.