Module ropey::iter

source ·
Expand description

Iterators over a Rope’s data.

The iterators in Ropey can be created from both Ropes and RopeSlices. When created from a RopeSlice, they iterate over only the data that the RopeSlice refers to. For the Lines and Chunks iterators, the data of the first and last yielded item will be correctly truncated to match the bounds of the RopeSlice.

Reverse iteration

All iterators in Ropey operate as a cursor that can move both forwards and backwards over its contents. This can be accomplished via the next() and prev() methods on each iterator, or by using the reverse() or reversed() methods to change the iterator’s direction.

Conceptually, an iterator in Ropey is always positioned between the elements it iterates over, and returns an element when it jumps over it via the next() or prev() methods.

For example, given the text "abc" and a Chars iterator starting at the beginning of the text, you would get the following sequence of states and return values by repeatedly calling next() (the vertical bar represents the position of the iterator):

  1. |abc
  2. a|bc -> Some('a')
  3. ab|c -> Some('b')
  4. abc| -> Some('c')
  5. abc| -> None

The prev() method operates identically, except moving in the opposite direction. And reverse() simply swaps the behavior of prev() and next().

Creating iterators at any position

Iterators in Ropey can be created starting at any position in the text. This is accomplished with the various bytes_at(), chars_at(), etc. methods of Rope and RopeSlice.

When an iterator is created this way, it is positioned such that a call to next() will return the specified element, and a call to prev() will return the element just before the specified one.

Importantly, iterators created this way still have access to the entire contents of the Rope/RopeSlice they were created from—the contents before the specified position is not truncated. For example, you can create a Chars iterator starting at the end of a Rope, and then use the prev() method to iterate backwards over all of that Rope’s chars.

A possible point of confusion

The Rust standard library has an iterator trait DoubleEndedIterator with a method rev(). While this method’s name is very similar to Ropey’s reverse() method, its behavior is very different.

DoubleEndedIterator actually provides two iterators: one starting at each end of the collection, moving in opposite directions towards each other. Calling rev() switches between those two iterators, changing not only the direction of iteration but also its current position in the collection.

The reverse() method on Ropey’s iterators, on the other hand, reverses the direction of the iterator in-place, without changing its position in the text.

Structs

  • An iterator over a Rope’s bytes.
  • An iterator over a Rope’s chars.
  • An iterator over a Rope’s contiguous str chunks.
  • An iterator over a Rope’s lines.