1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
pub trait Direction: Sized {
    type Directions: Iterator<Item = Self>;

    fn inv(self) -> Self;
    fn directions() -> Self::Directions;
}

/// A `Neighborhood` contains all of your neighbors, which are each in their own `Direction`.
pub trait Neighborhood<T> {
    type Direction: Direction;
    type Iter: Iterator<Item = T>;
    type DirIter: Iterator<Item = (Self::Direction, T)>;

    fn new<F: FnMut(Self::Direction) -> T>(F) -> Self;

    /// Iterate over all neighbor cells.
    fn iter(self) -> Self::Iter;
    /// Iterate over all neighbor cells with their directions.
    fn dir_iter(self) -> Self::DirIter;
}

pub trait GetNeighbors<'a, Idx, Neighbors> {
    fn get_neighbors(&'a self, index: Idx) -> Neighbors;
}

pub trait TakeMoveDirection<Idx, Dir, Move> {
    /// This should be called exactly once for every index and direction.
    ///
    /// This is marked unsafe to ensure people read the documentation due to the above requirement.
    unsafe fn take_move_direction(&self, Idx, Dir) -> Move;
}

pub trait TakeMoveNeighbors<Idx, MoveNeighbors> {
    /// This should be called exactly once for every index, making it unsafe.
    ///
    /// This is marked unsafe to ensure people read the documentation due to the above requirement.
    unsafe fn take_move_neighbors(&self, Idx) -> MoveNeighbors;
}