rusterlium / rustler

Safe Rust bridge for creating Erlang NIF functions
https://docs.rs/crate/rustler
Apache License 2.0
4.32k stars 225 forks source link

Add reverse map iteration #596

Closed devsnek closed 7 months ago

devsnek commented 7 months ago

pretty self explanatory. i found need of this api in a library i'm writing.

filmor commented 7 months ago

I know that it might be a bit tedious to implement as the model doesn't map 1-to-1, but it would be more ergonomic to extend MapIterator to be a DoubleEndedIterator as you could then use .rev() on it (as one would expect).

DoubleEndedIterator sadly doesn't have "cursor" semantics, so this would need to be implemented as a pair of Option<SimpleMapIterator>, one going backwards, one going forwards, with an additional check of whether they point to the same element. So roughly

struct SimpleMapIterator {
    is_forward: bool,
    last_key: Option<Term>,
    iter: ...
}

struct MapIterator {
    done: bool,
    fwd: SimpleMapIterator,
    bck: SimpleMapIterator,
}

impl<'a> DoubleEndedIterator for MapIterator {
    // ...
    fn next(mut self) -> Option<...> {
        if self.done { return None }
        if let Some((k, v)) = self.fwd.next() {
            if let Some((b_k, _)) = self.bwd.last_key {
                if k == b_k {
                   self.done = true;
                   return None;
                }
            }
            Some((k, v))
        } else {
            self.done = true;
            None
        }
    }

    fn next_back(mut self) -> ... {
       // same with roles of bwd and fwd reversed
    }
}
devsnek commented 6 months ago

@filmor thanks, do you know when the next release will be cut?