lattice_graph/square/
neighbors.rs

1use super::*;
2use crate::SquareGraph;
3use petgraph::{
4    graph::IndexType,
5    visit::{IntoNeighbors, IntoNeighborsDirected},
6};
7use std::iter::FusedIterator;
8
9/// Neighbors of the node. See [`neighbors`](`IntoNeighbors::neighbors`).
10#[derive(Clone, Debug)]
11pub struct Neighbors<Ix: IndexType, S> {
12    node: NodeIndex<Ix>,
13    state: usize,
14    h: usize,
15    v: usize,
16    s: PhantomData<S>,
17}
18
19impl<Ix, S> Iterator for Neighbors<Ix, S>
20where
21    Ix: IndexType,
22    S: Shape,
23{
24    type Item = NodeIndex<Ix>;
25
26    fn next(&mut self) -> Option<Self::Item> {
27        loop {
28            let n = self.node;
29            let x = match self.state {
30                0 if n.horizontal.index() != 0 => n.left(),
31                0 if <S as Shape>::LOOP_HORIZONTAL && n.horizontal.index() == 0 => NodeIndex {
32                    horizontal: Ix::new(self.h - 1),
33                    vertical: n.vertical,
34                },
35                1 if n.horizontal.index() + 1 < self.h => n.right(),
36                1 if <S as Shape>::LOOP_HORIZONTAL && n.horizontal.index() + 1 == self.h => {
37                    NodeIndex {
38                        horizontal: Ix::new(0),
39                        vertical: n.vertical,
40                    }
41                }
42                2 if n.vertical.index() != 0 => n.down(),
43                2 if <S as Shape>::LOOP_VERTICAL && n.vertical.index() == 0 => NodeIndex {
44                    horizontal: n.horizontal,
45                    vertical: Ix::new(self.v - 1),
46                },
47                3 if n.vertical.index() + 1 < self.v => n.up(),
48                3 if <S as Shape>::LOOP_VERTICAL && n.vertical.index() + 1 == self.v => NodeIndex {
49                    horizontal: n.horizontal,
50                    vertical: Ix::new(0),
51                },
52                4..=usize::MAX => return None,
53                _ => {
54                    self.state += 1;
55                    continue;
56                }
57            };
58            self.state += 1;
59            return Some(x);
60        }
61    }
62
63    fn size_hint(&self) -> (usize, Option<usize>) {
64        (0, Some(4 - self.state))
65    }
66}
67
68impl<Ix, S> FusedIterator for Neighbors<Ix, S>
69where
70    Ix: IndexType,
71    S: Shape,
72{
73}
74
75impl<N, E, Ix, S> IntoNeighbors for &SquareGraph<N, E, Ix, S>
76where
77    Ix: IndexType,
78    S: Shape,
79{
80    type Neighbors = Neighbors<Ix, S>;
81
82    fn neighbors(self, a: Self::NodeId) -> Self::Neighbors {
83        Neighbors {
84            node: a,
85            state: 0,
86            h: self.horizontal_node_count(),
87            v: self.vertical_node_count(),
88            s: PhantomData,
89        }
90    }
91}
92
93impl<N, E, Ix, S> IntoNeighborsDirected for &SquareGraph<N, E, Ix, S>
94where
95    Ix: IndexType,
96    S: Shape,
97{
98    type NeighborsDirected = Neighbors<Ix, S>;
99
100    fn neighbors_directed(
101        self,
102        n: Self::NodeId,
103        _d: petgraph::Direction,
104    ) -> Self::NeighborsDirected {
105        Neighbors {
106            node: n,
107            state: 0,
108            h: self.horizontal_node_count(),
109            v: self.vertical_node_count(),
110            s: PhantomData,
111        }
112    }
113}