lattice_graph/square/
neighbors.rs1use super::*;
2use crate::SquareGraph;
3use petgraph::{
4 graph::IndexType,
5 visit::{IntoNeighbors, IntoNeighborsDirected},
6};
7use std::iter::FusedIterator;
8
9#[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}