use super::Position;
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum Entity {
Global,
Column(usize),
Row(usize),
Cell(usize, usize),
}
impl Entity {
pub fn iter(&self, count_rows: usize, count_cols: usize) -> EntityIterator {
EntityIterator::new(*self, count_rows, count_cols)
}
}
impl From<Position> for Entity {
fn from(pos: Position) -> Self {
Self::Cell(pos.row, pos.col)
}
}
impl From<(usize, usize)> for Entity {
fn from(pos: (usize, usize)) -> Self {
Self::Cell(pos.0, pos.1)
}
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct EntityIterator {
entity: Entity,
count_rows: usize,
count_cols: usize,
i: usize,
j: usize,
}
impl EntityIterator {
fn new(entity: Entity, count_rows: usize, count_cols: usize) -> Self {
Self {
entity,
count_rows,
count_cols,
i: 0,
j: 0,
}
}
}
impl Iterator for EntityIterator {
type Item = Position;
fn next(&mut self) -> Option<Self::Item> {
if self.count_rows == 0 || self.count_cols == 0 {
return None;
}
match self.entity {
Entity::Cell(row, col) => {
self.count_cols = 0;
self.count_rows = 0;
Some(Position::new(row, col))
}
Entity::Column(col) => {
if self.i >= self.count_rows {
return None;
}
let i = self.i;
self.i += 1;
Some(Position::new(i, col))
}
Entity::Row(row) => {
if self.j >= self.count_cols {
return None;
}
let j = self.j;
self.j += 1;
Some(Position::new(row, j))
}
Entity::Global => {
if self.j >= self.count_cols {
self.j = 0;
self.i += 1;
if self.i >= self.count_rows {
return None;
}
}
let j = self.j;
self.j += 1;
Some(Position::new(self.i, j))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_entity_iter() {
assert_eq!(
Entity::Global.iter(10, 10).collect::<Vec<_>>(),
vec![
Position::new(0, 0),
Position::new(0, 1),
Position::new(0, 2),
Position::new(0, 3),
Position::new(0, 4),
Position::new(0, 5),
Position::new(0, 6),
Position::new(0, 7),
Position::new(0, 8),
Position::new(0, 9),
Position::new(1, 0),
Position::new(1, 1),
Position::new(1, 2),
Position::new(1, 3),
Position::new(1, 4),
Position::new(1, 5),
Position::new(1, 6),
Position::new(1, 7),
Position::new(1, 8),
Position::new(1, 9),
Position::new(2, 0),
Position::new(2, 1),
Position::new(2, 2),
Position::new(2, 3),
Position::new(2, 4),
Position::new(2, 5),
Position::new(2, 6),
Position::new(2, 7),
Position::new(2, 8),
Position::new(2, 9),
Position::new(3, 0),
Position::new(3, 1),
Position::new(3, 2),
Position::new(3, 3),
Position::new(3, 4),
Position::new(3, 5),
Position::new(3, 6),
Position::new(3, 7),
Position::new(3, 8),
Position::new(3, 9),
Position::new(4, 0),
Position::new(4, 1),
Position::new(4, 2),
Position::new(4, 3),
Position::new(4, 4),
Position::new(4, 5),
Position::new(4, 6),
Position::new(4, 7),
Position::new(4, 8),
Position::new(4, 9),
Position::new(5, 0),
Position::new(5, 1),
Position::new(5, 2),
Position::new(5, 3),
Position::new(5, 4),
Position::new(5, 5),
Position::new(5, 6),
Position::new(5, 7),
Position::new(5, 8),
Position::new(5, 9),
Position::new(6, 0),
Position::new(6, 1),
Position::new(6, 2),
Position::new(6, 3),
Position::new(6, 4),
Position::new(6, 5),
Position::new(6, 6),
Position::new(6, 7),
Position::new(6, 8),
Position::new(6, 9),
Position::new(7, 0),
Position::new(7, 1),
Position::new(7, 2),
Position::new(7, 3),
Position::new(7, 4),
Position::new(7, 5),
Position::new(7, 6),
Position::new(7, 7),
Position::new(7, 8),
Position::new(7, 9),
Position::new(8, 0),
Position::new(8, 1),
Position::new(8, 2),
Position::new(8, 3),
Position::new(8, 4),
Position::new(8, 5),
Position::new(8, 6),
Position::new(8, 7),
Position::new(8, 8),
Position::new(8, 9),
Position::new(9, 0),
Position::new(9, 1),
Position::new(9, 2),
Position::new(9, 3),
Position::new(9, 4),
Position::new(9, 5),
Position::new(9, 6),
Position::new(9, 7),
Position::new(9, 8),
Position::new(9, 9)
]
);
}
}