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