1

I'm trying to mapped index into a slice given a transformation function, returning an iterator, here the example code:

pub trait MappedIdxIter<T> {
    fn map_idx(&self, transform_func: fn(idx: usize, max: usize) -> Option<usize>,) -> Box<dyn Iterator<Item = T>>;
}

impl<'a, U: 'a> MappedIdxIter<&'a U> for [U] {
    fn map_idx(&self, transform_func: fn(idx: usize, max: usize) -> Option<usize>,) -> Box<dyn Iterator<Item = &'a U>> {

        let max = self.len();
        let iter = (0..max).into_iter()
                .filter_map(|i| transform_func(i, max))
                .map(|i| &self[i]);
        Box::new(iter)
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn should_return_even_idx_values() {
        let list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

        let mapped: Vec<&u32> = list.map_idx(|i, m|
                if (i * 2) < m { Some(i * 2) } else { None }
        ).collect();

        assert_eq!([&0, &2, &4, &6, &8], mapped[..]);
    }

    #[test]
    fn should_return_1_5_3() {
        let list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

        let mapped: Vec<&u32> = list
            .map_idx(|i, _m| match i {
                0 => Some(1),
                1 => Some(5),
                2 => Some(3),
                _ => None,
            })
            .collect();

        assert_eq!([&1, &5, &3], mapped[..]);
    }
}

Rust playground

I'm getting the following error

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
   --> src/priority_list.rs:107:27
    |
107 |                 .map(|i| &self[i]);
    |                           ^^^^^^^
    |

How can tell rust that the iterator is only valid for the lifetime of self?

There is some pointers here https://users.rust-lang.org/t/how-to-write-trait-which-returns-an-iterator/44828 but I failed to make it work.

EDIT:

I've been able to implement this using awesome nougat crate, see comment

izissise
  • 898
  • 1
  • 7
  • 23
  • 1
    You need to adjust the trait so that the output items are bound to the lifetime of `self`, which is currently only possible with generic associated types (GATs). [Working Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=4e9baa41ae56d03071df2e14449a8ea1) – E_net4 Jul 12 '22 at 14:39
  • Ah yes GAT issue, reading more about the subject, I discovered nougat https://crates.io/crates/nougat a macro which emulate GAT, which allowed me to implement the example above in stable rust -> https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d70e18425c91b93cd6809fa970f03a66 – izissise Jul 12 '22 at 17:37

0 Answers0