3
\$\begingroup\$

In my effort to learn Rust I've tried implementing an Iterator that splits up a buffer in two halves, and correlates both halves by sliding them over each other with different positions (lags). You could use this e.g. to do autocorrelation, given a correlation function between two buffers (dot product for example).

I'm fairly new to Rust (coming from a C++ background), so any and all advice is welcome. Specifically to lifetimes, generics and idiomatic usage of Rust.

Also, should I turn this into an iterator adapter that takes an iterator and collects the data in an internal Vec? Would that cover a wider array of input?

pub struct Slide<'a, T, F> {
    items: &'a [T],
    func: F,
    lag: usize,
}

impl<'a, T, F> Slide<'a, T, F> {
    pub fn new<Out>(items: &'a [T], func: F) -> Slide<'a, T, F>
    where
        F: Fn(&'a [T], &'a [T]) -> Out,
    {
        Slide {
            items,
            func,
            lag: 0,
        }
    }
}

impl<'a, T, F, Out> Iterator for Slide<'a, T, F>
where
    F: Fn(&[T], &[T]) -> Out,
{
    type Item = Out;

    fn next(&mut self) -> Option<Out> {
        let half_length = self.items.len() / 2;

        if self.lag < half_length {
            let y = (self.func)(
                &self.items[0..half_length],
                &self.items[self.lag..self.lag + half_length],
            );

            self.lag += 1;
            Some(y)
        } else {
            None
        }
    }
}
```
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.