Search code examples
rustmethodsrust-clippy

Method can be confused for the standard trait method


I have this warning, and I don't how to fix this warning.

warning: method `next` can be confused for the standard trait method `std::iter::Iterator::next`
  --> src/util/mod.rs:51:5
   |
51 | /     pub fn next(&mut self) -> Option<I::Item> {
52 | |         if self.iterator.peek().is_some() {
53 | |             self.prev = replace(&mut self.current, self.iterator.next());
54 | |             return self.current.clone();
...  |
59 | |         None
60 | |     }
   | |_____^
   |
   = help: consider implementing the trait `std::iter::Iterator` or choosing a less ambiguous method name
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
   = note: `#[warn(clippy::should_implement_trait)]` on by default

Here's the code I have right now - an iterator that's able to peek the previous item. next method is also in the snippet.

pub struct PrevPeekable<I>
where
    I: Iterator,
    <I as Iterator>::Item: Clone,
{
    /// Iterator that `PrevPeekable` wraps
    iterator: Peekable<I>,
    /// The item before the current item
    prev: Option<I::Item>,
    /// The current item
    current: Option<I::Item>,
    /// Keeps track of whether the iterator has reached the end or not
    finished: bool,
}

impl<I> PrevPeekable<I>
where
    I: Iterator,
    <I as Iterator>::Item: Clone,
{
        /// Returns the next item in the iterator
    pub fn next(&mut self) -> Option<I::Item> {
        if self.iterator.peek().is_some() {
            self.prev = replace(&mut self.current, self.iterator.next());
            return self.current.clone();
        } else if !self.finished {
            self.prev = replace(&mut self.current, self.iterator.next());
            self.finished = true;
        }
        None
    }
}

Thanks in advance.


Solution

  • You need to implement the Iterator trait and move your next code into this implementation:

    use std::mem::replace;
    use std::iter::Peekable;
    
    pub struct PrevPeekable<I>
    where
        I: Iterator,
        <I as Iterator>::Item: Clone,
    {
        /// Iterator that `PrevPeekable` wraps
        iterator: Peekable<I>,
        /// The item before the current item
        prev: Option<I::Item>,
        /// The current item
        current: Option<I::Item>,
        /// Keeps track of whether the iterator has reached the end or not
        finished: bool,
    }
    
    impl<I> Iterator for PrevPeekable<I>
    where
        I: Iterator,
        <I as Iterator>::Item: Clone,
    {
        type Item = I::Item;
    
        /// Returns the next item in the iterator
        fn next(&mut self) -> Option<I::Item> {
            if self.iterator.peek().is_some() {
                self.prev = replace(&mut self.current, self.iterator.next());
                return self.current.clone();
            } else if !self.finished {
                self.prev = replace(&mut self.current, self.iterator.next());
                self.finished = true;
            }
            None
        }
    }
    

    Playground