use crate::joinable::JoinIterable;
pub trait LinearIterator {
fn key(&self) -> Option<usize>;
fn next(&mut self) -> Option<usize>;
fn seek(&mut self, seek_key: usize) -> bool;
fn at_end(&self) -> bool;
}
pub trait LinearIterable: JoinIterable {
fn linear_iter(&self) -> impl LinearIterator;
}
impl JoinIterable for Vec<usize> {}
struct VecLinearIter<'a> {
data: &'a [usize],
index: usize,
}
impl LinearIterator for VecLinearIter<'_> {
fn key(&self) -> Option<usize> {
if self.index != 0 && !self.at_end() {
Some(self.data[self.index - 1])
} else {
None
}
}
fn next(&mut self) -> Option<usize> {
self.index += 1;
if self.at_end() {
return None;
}
self.key()
}
fn seek(&mut self, seek_key: usize) -> bool {
while let Some(key) = self.key() {
if key >= seek_key {
return true;
}
self.index += 1;
}
false
}
fn at_end(&self) -> bool { self.index > self.data.len() }
}
impl LinearIterable for Vec<usize> {
fn linear_iter(&self) -> impl LinearIterator {
VecLinearIter {
data: self,
index: 0,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vec_linear_iterator() {
let data = vec![1, 2, 3, 4, 5];
let mut iter = data.linear_iter();
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert!(iter.seek(3));
assert_eq!(iter.next(), Some(4));
assert!(!iter.at_end());
assert_eq!(iter.next(), Some(5));
assert_eq!(iter.next(), None);
assert!(iter.at_end());
}
#[test]
fn empty_vec() {
let data: Vec<usize> = vec![];
let mut iter = data.linear_iter();
assert_eq!(iter.key(), None);
assert_eq!(iter.next(), None);
assert!(iter.at_end());
}
#[test]
fn single_element() {
let data = vec![42];
let mut iter = data.linear_iter();
assert_eq!(iter.key(), None);
assert_eq!(iter.next(), Some(42));
assert_eq!(iter.key(), Some(42));
assert!(!iter.at_end());
assert_eq!(iter.next(), None);
assert!(iter.at_end());
}
#[test]
fn key_tracks_position() {
let data = vec![10, 20, 30];
let mut iter = data.linear_iter();
assert_eq!(iter.key(), None);
assert_eq!(iter.next(), Some(10));
assert_eq!(iter.key(), Some(10));
assert_eq!(iter.next(), Some(20));
assert_eq!(iter.key(), Some(20));
assert_eq!(iter.next(), Some(30));
assert_eq!(iter.key(), Some(30));
assert_eq!(iter.next(), None);
assert_eq!(iter.key(), None);
}
#[test]
fn seek_exact_key() {
let data = vec![1, 3, 5, 7, 9];
let mut iter = data.linear_iter();
iter.next();
assert!(iter.seek(5));
assert_eq!(iter.key(), Some(5));
}
#[test]
fn seek_upper_bound() {
let data = vec![1, 3, 5, 7, 9];
let mut iter = data.linear_iter();
iter.next();
assert!(iter.seek(4));
assert_eq!(iter.key(), Some(5));
}
#[test]
fn seek_past_all() {
let data = vec![1, 3, 5];
let mut iter = data.linear_iter();
iter.next();
assert!(!iter.seek(100));
assert!(iter.at_end());
}
#[test]
fn seek_to_current_key() {
let data = vec![1, 3, 5, 7];
let mut iter = data.linear_iter();
iter.next();
assert!(iter.seek(1));
assert_eq!(iter.key(), Some(1));
}
#[test]
fn seek_then_next() {
let data = vec![1, 3, 5, 7, 9];
let mut iter = data.linear_iter();
iter.next();
assert!(iter.seek(5));
assert_eq!(iter.key(), Some(5));
assert_eq!(iter.next(), Some(7));
assert_eq!(iter.next(), Some(9));
assert_eq!(iter.next(), None);
}
#[test]
fn multiple_seeks() {
let data = vec![1, 3, 5, 7, 9];
let mut iter = data.linear_iter();
iter.next();
assert!(iter.seek(3));
assert_eq!(iter.key(), Some(3));
assert!(iter.seek(7));
assert_eq!(iter.key(), Some(7));
assert!(iter.seek(9));
assert_eq!(iter.key(), Some(9));
assert!(!iter.seek(10));
}
}