#fixed-length #vec #next #circular #io #iterator #items

circular_vec

A fixed length vector that provides a next function that loops infinitely

2 releases

0.1.1 Jul 24, 2021
0.1.0 Jul 24, 2021

#1884 in Data structures

MIT license

6KB
69 lines

Circular Vec

This provides a struct called CircularVec. It is a fixed length Vec that provides a next function, which iterates through the vec. When it hits the end, instead of returning None, we just loop back to the start.

Note: This struct could use a lot of love. While I do have a need for this struct, and I use this for a personal project, this is also to become familiar with publishing a crate to crates.io. See the many ways this could be improved below.

Future work

  • This is likely not as efficient as it could be. We use Vec internally, which can grow, but we don't need that.
  • We could export a version of this that can change size. Shrink semantics TBA.
  • This doesn't implement many traits that it could. See the traits that Vec implements for inspiration.
  • The API could probably use some love, like exposing this as an iterator instead of providing a next function.
  • Probably much much more.

lib.rs:

This struct maintains a fixed length circular Vec. You provide the items for the circular Vec at initialization time and can then never change the amount of items held within. It provides a next function that, when it hits the end of the struct, just loops back to the start.

The CircularVec allows for in place changes to the items held within using the next_mut function, though for most cases just using next is fine. To call either of these functions you must have a mutable reference to the CircularVec so that it can increment its internal counter.

Notably, CircularVec does not implement IntoIterator because it would produce an iterator that never ends, which is not the intended use of IntoIterator. Accordingly, the next function here does not return the item (T), but a reference to it (&T), and returns &T instead of Option<&T> because there will always be an item it can return.

Example usage:

 let mut cv: CircularVec<String> = ["hello".to_string(), "world".to_string()]
     .to_vec()
     .into_iter()
     .collect();
         
 assert_eq!(cv.next(), "hello");
 assert_eq!(cv.next(), "world");
 assert_eq!(cv.next(), "hello");
 assert_eq!(cv.next(), "world");

No runtime deps