iter-set 2.0.2

Set operations on sorted, deduplicated iterators.
Documentation
use core::fmt;

pub(crate) struct PutBack<I: Iterator> {
    iter: I,
    next: Option<I::Item>,
}

impl<I: Iterator> PutBack<I> {
    pub fn new(iter: I) -> Self {
        PutBack { iter, next: None }
    }

    pub fn put_back(&mut self, item: I::Item) {
        debug_assert!(self.next.is_none());
        self.next = Some(item);
    }
}

impl<I: Iterator> Iterator for PutBack<I> {
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        if self.next.is_some() {
            self.next.take()
        } else {
            self.iter.next()
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let (lower, upper) = self.iter.size_hint();
        if self.next.is_some() {
            (
                lower.saturating_add(1),
                upper.and_then(|n| n.checked_add(1)),
            )
        } else {
            (lower, upper)
        }
    }
}

impl<I: fmt::Debug + Iterator> fmt::Debug for PutBack<I> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("PutBack")
            .field("iter", &self.iter)
            .field(
                "next",
                if self.next.is_some() {
                    &"Some(_)"
                } else {
                    &"None"
                },
            )
            .finish()
    }
}