1
+ use self :: layout:: Position ;
1
2
use crate :: prelude:: * ;
2
3
3
4
/// An iterator over rows within a `Rect`.
@@ -68,9 +69,50 @@ impl Iterator for Columns {
68
69
}
69
70
}
70
71
72
+ /// An iterator over positions within a `Rect`.
73
+ ///
74
+ /// The iterator will yield all positions within the `Rect` in a row-major order.
75
+ pub struct Positions {
76
+ /// The `Rect` associated with the positions.
77
+ pub rect : Rect ,
78
+ /// The current position within the `Rect`.
79
+ pub current_position : Position ,
80
+ }
81
+
82
+ impl Positions {
83
+ /// Creates a new `Positions` iterator.
84
+ pub fn new ( rect : Rect ) -> Self {
85
+ Self {
86
+ rect,
87
+ current_position : Position :: new ( rect. x , rect. y ) ,
88
+ }
89
+ }
90
+ }
91
+
92
+ impl Iterator for Positions {
93
+ type Item = Position ;
94
+
95
+ /// Retrieves the next position within the `Rect`.
96
+ ///
97
+ /// Returns `None` when there are no more positions to iterate through.
98
+ fn next ( & mut self ) -> Option < Self :: Item > {
99
+ if self . current_position . y >= self . rect . bottom ( ) {
100
+ return None ;
101
+ }
102
+ let position = self . current_position ;
103
+ self . current_position . x += 1 ;
104
+ if self . current_position . x >= self . rect . right ( ) {
105
+ self . current_position . x = self . rect . x ;
106
+ self . current_position . y += 1 ;
107
+ }
108
+ Some ( position)
109
+ }
110
+ }
111
+
71
112
#[ cfg( test) ]
72
113
mod tests {
73
114
use super :: * ;
115
+ use crate :: layout:: Position ;
74
116
75
117
#[ test]
76
118
fn rows ( ) {
@@ -89,4 +131,15 @@ mod tests {
89
131
assert_eq ! ( columns. next( ) , Some ( Rect :: new( 1 , 0 , 1 , 2 ) ) ) ;
90
132
assert_eq ! ( columns. next( ) , None ) ;
91
133
}
134
+
135
+ #[ test]
136
+ fn positions ( ) {
137
+ let rect = Rect :: new ( 0 , 0 , 2 , 2 ) ;
138
+ let mut positions = Positions :: new ( rect) ;
139
+ assert_eq ! ( positions. next( ) , Some ( Position :: new( 0 , 0 ) ) ) ;
140
+ assert_eq ! ( positions. next( ) , Some ( Position :: new( 1 , 0 ) ) ) ;
141
+ assert_eq ! ( positions. next( ) , Some ( Position :: new( 0 , 1 ) ) ) ;
142
+ assert_eq ! ( positions. next( ) , Some ( Position :: new( 1 , 1 ) ) ) ;
143
+ assert_eq ! ( positions. next( ) , None ) ;
144
+ }
92
145
}
0 commit comments