1#[cfg(all(not(feature = "i32"), not(feature = "i64")))]
21compile_error!("either feature \"i32\" or \"i64\" must be enabled");
22
23#[cfg(all(feature = "i32", feature = "i64"))]
24compile_error!("feature \"i32\" and feature \"i64\" cannot be enabled at the same time");
25
26#[warn(missing_docs)]
27pub mod grid;
28pub mod immutable;
29
30#[cfg(feature = "bevy_reflect")]
31use bevy_reflect::Reflect;
32
33#[cfg(feature = "serde")]
34use serde::{
35 de::{self, Deserialize, Deserializer, MapAccess, Visitor},
36 ser::{Serialize, SerializeStruct, Serializer},
37};
38
39pub use grid::Grid;
40pub use immutable::Immutable;
41use std::hash::BuildHasher;
42use std::ops::{Index, IndexMut};
43
44#[cfg(feature = "i32")]
45type Scalar = i32;
46#[cfg(feature = "i64")]
47type Scalar = i64;
48
49#[cfg(feature = "hashbrown")]
50use hashbrown::HashMap;
51#[cfg(not(feature = "hashbrown"))]
52use std::collections::HashMap;
53
54#[cfg(feature = "hashbrown")]
56pub type DefaultHashBuilder = hashbrown::hash_map::DefaultHashBuilder;
57#[cfg(not(feature = "hashbrown"))]
59pub type DefaultHashBuilder = std::hash::RandomState;
60
61#[cfg_attr(feature = "i32", doc = "`HashMap<(i32, i32), T>`")]
66#[cfg_attr(feature = "i64", doc = "`HashMap<(i64, i64), T>`")]
67#[cfg_attr(feature = "i32", doc = "`HashMap<(i32, i32), T>`,")]
78#[cfg_attr(feature = "i64", doc = "`HashMap<(i64, i64), T>`,")]
79#[cfg_attr(feature = "i32", doc = "`HashMap<(i32, i32), T>`,")]
81#[cfg_attr(feature = "i64", doc = "`HashMap<(i64, i64), T>`")]
82#[derive(Debug, Clone)]
89#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
90pub struct Plane<T: Default, S: BuildHasher = DefaultHashBuilder> {
91 grid: Grid<T>,
92 offset: (Scalar, Scalar),
94 map: HashMap<(Scalar, Scalar), T, S>,
95
96 default_value: Immutable<T>,
99}
100
101#[cfg(feature = "serde")]
102impl<'de, T: Default + Deserialize<'de>, H: Default + BuildHasher> Deserialize<'de>
103 for Plane<T, H>
104{
105 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
106 where
107 D: Deserializer<'de>,
108 {
109 use std::marker::PhantomData;
110 #[derive(serde::Deserialize)]
111 #[serde(field_identifier, rename_all = "lowercase")]
112 enum Field {
113 Offset,
114 Size,
115 Grid,
116 Map,
117 }
118
119 struct PlaneVisitor<T, H> {
120 _p: PhantomData<(T, H)>,
121 }
122
123 impl<'de, T: Default + Deserialize<'de>, H: Default + BuildHasher> Visitor<'de>
124 for PlaneVisitor<T, H>
125 {
126 type Value = Plane<T, H>;
127
128 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
129 formatter.write_str("struct Grid")
130 }
131
132 fn visit_map<V>(self, mut accsess: V) -> Result<Plane<T, H>, V::Error>
133 where
134 V: MapAccess<'de>,
135 {
136 let mut offset: Option<(Scalar, Scalar)> = None;
137 let mut size: Option<(Scalar, Scalar)> = None;
138 let mut grid = None;
139 let mut map = None;
140 while let Some(key) = accsess.next_key()? {
141 match key {
142 Field::Offset => {
143 if offset.is_some() {
144 return Err(de::Error::duplicate_field("offset"));
145 }
146 offset = Some(accsess.next_value()?);
147 }
148 Field::Size => {
149 if size.is_some() {
150 return Err(de::Error::duplicate_field("size"));
151 }
152 size = Some(accsess.next_value()?);
153 }
154 Field::Grid => {
155 if grid.is_some() {
156 return Err(de::Error::duplicate_field("grid"));
157 }
158 grid = Some(accsess.next_value()?);
159 }
160 Field::Map => {
161 if map.is_some() {
162 return Err(de::Error::duplicate_field("map"));
163 }
164 map = Some(accsess.next_value()?);
165 }
166 }
167 }
168
169 let (x_min, y_min) = offset.ok_or_else(|| de::Error::missing_field("offset"))?;
170 let map = map.ok_or_else(|| de::Error::missing_field("map"))?;
171
172 if let Some(grid) = grid {
173 Ok(Plane::from_grid_and_hash_map(grid, map, -x_min, -y_min))
174 } else if let Some((x_size, y_size)) = size {
175 Ok(Plane::from_hash_map(
176 map,
177 -x_min,
178 -y_min,
179 x_size - x_min,
180 y_size - y_min,
181 ))
182 } else {
183 Err(de::Error::missing_field("grid or size"))
184 }
185 }
186 }
187
188 const FIELDS: &'static [&'static str] = &["cols", "data", "order"];
189 deserializer.deserialize_struct("Grid", FIELDS, PlaneVisitor { _p: PhantomData })
190 }
191}
192
193#[cfg(feature = "serde")]
194impl<T: Default + Serialize, H: BuildHasher> Serialize for Plane<T, H> {
195 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
196 where
197 S: Serializer,
198 {
199 let mut state = serializer.serialize_struct("Plane", 3)?;
201 state.serialize_field("offset", &self.offset)?;
202 state.serialize_field("grid", &self.grid)?;
203 state.serialize_field("map", &self.map)?;
204 state.end()
205 }
206}
207
208#[inline]
209fn rows_cols(x_min: Scalar, y_min: Scalar, x_max: Scalar, y_max: Scalar) -> (usize, usize) {
210 ((x_max - x_min + 1) as usize, (y_max - y_min + 1) as usize)
211}
212
213impl<T: Default, S: Default + BuildHasher> Default for Plane<T, S> {
214 #[cfg_attr(feature = "i32", doc = "`HashMap<(i32, i32), T>`,")]
217 #[cfg_attr(feature = "i64", doc = "`HashMap<(i64, i64), T>`,")]
218 fn default() -> Self {
220 Self {
221 grid: Grid::new(0, 0),
222 offset: (0, 0),
223 map: HashMap::default(),
224 default_value: Immutable::default(),
225 }
226 }
227}
228
229impl<T: Default> Plane<T, DefaultHashBuilder> {
230 #[inline]
231 pub fn new(x_min: Scalar, y_min: Scalar, x_max: Scalar, y_max: Scalar) -> Self {
232 Self::default_hasher(x_min, y_min, x_max, y_max)
233 }
234}
235
236impl<T: Default, S: Default + BuildHasher> Plane<T, S> {
237 #[inline]
238 pub fn default_hasher(x_min: Scalar, y_min: Scalar, x_max: Scalar, y_max: Scalar) -> Self {
239 Self::with_hasher(x_min, y_min, x_max, y_max, Default::default())
240 }
241 #[inline]
242 pub fn from_grid(grid: Grid<T>, x_min: Scalar, y_min: Scalar) -> Self {
243 Self::from_grid_and_hash_map(grid, HashMap::default(), x_min, y_min)
244 }
245}
246
247impl<T: Default, S: BuildHasher> Plane<T, S> {
248 pub fn with_hasher(
250 x_min: Scalar,
251 y_min: Scalar,
252 x_max: Scalar,
253 y_max: Scalar,
254 hasher: S,
255 ) -> Self {
256 let (rows, cols): (usize, usize) = rows_cols(x_min, y_min, x_max, y_max);
257 Self::from_grid_and_hash_map(
258 Grid::new(rows, cols),
259 HashMap::with_hasher(hasher),
260 x_min,
261 y_min,
262 )
263 }
264
265 #[inline]
266 pub fn inner_grid(&self) -> &Grid<T> {
267 &self.grid
268 }
269 #[inline]
270 pub fn inner_grid_mut(&mut self) -> &mut Grid<T> {
271 &mut self.grid
272 }
273 #[inline]
274 pub fn inner_hash_map(&self) -> &HashMap<(Scalar, Scalar), T, S> {
275 &self.map
276 }
277 #[inline]
278 pub fn inner_hash_map_mut(&mut self) -> &mut HashMap<(Scalar, Scalar), T, S> {
279 &mut self.map
280 }
281
282 pub fn from_hash_map(
283 map: HashMap<(Scalar, Scalar), T, S>,
284 x_min: Scalar,
285 y_min: Scalar,
286 x_max: Scalar,
287 y_max: Scalar,
288 ) -> Self {
289 let mut plane = Self::from_grid_and_hash_map(Grid::new(0, 0), map, 0, 0);
290 plane.relocate_grid(x_min, x_max, y_min, y_max);
291 plane
292 }
293
294 #[inline]
295 pub fn from_grid_with_hasher(grid: Grid<T>, x_min: Scalar, y_min: Scalar, hasher: S) -> Self {
296 Self::from_grid_and_hash_map(grid, HashMap::with_hasher(hasher), x_min, y_min)
297 }
298
299 pub fn from_grid_and_hash_map(
305 grid: Grid<T>,
306 map: HashMap<(Scalar, Scalar), T, S>,
307 x_min: Scalar,
308 y_min: Scalar,
309 ) -> Self {
310 Self {
311 grid,
312 offset: (-x_min, -y_min),
313 map,
314 default_value: Immutable::default(),
315 }
316 }
317
318 pub fn into_hash_map(self) -> HashMap<(Scalar, Scalar), T, S> {
319 let mut map = self.map;
320
321 for ((x, y), val) in self.grid.into_iter_indexed() {
322 let vec = (x as Scalar - self.offset.0, y as Scalar - self.offset.1);
323 map.insert(vec, val);
324 }
325
326 map
327 }
328
329 pub fn global_coordinates_from_grid(&self, x: usize, y: usize) -> (Scalar, Scalar) {
330 let x = x as Scalar - self.offset.0;
331 let y = y as Scalar - self.offset.1;
332 (x, y)
333 }
334
335 pub fn grid_coordinates_from_global(&self, x: Scalar, y: Scalar) -> Option<(usize, usize)> {
336 let x = x + self.offset.0;
337 let y = y + self.offset.1;
338
339 if 0 <= x && x < self.grid.rows() as Scalar && 0 <= y && y < self.grid.cols() as Scalar {
340 Some((x as usize, y as usize))
341 } else {
342 None
343 }
344 }
345
346 pub unsafe fn get_unchecked(&self, x: Scalar, y: Scalar) -> &T {
353 let x = (x + self.offset.0) as usize;
354 let y = (y + self.offset.1) as usize;
355
356 self.grid.get_unchecked(x, y)
357 }
358
359 pub unsafe fn get_unchecked_mut(&mut self, x: Scalar, y: Scalar) -> &mut T {
366 let x = (x + self.offset.0) as usize;
367 let y = (y + self.offset.1) as usize;
368
369 self.grid.get_unchecked_mut(x, y)
370 }
371
372 pub fn get(&self, x: Scalar, y: Scalar) -> &T {
375 if let Some((x, y)) = self.grid_coordinates_from_global(x, y) {
376 unsafe { self.grid.get_unchecked(x, y) }
379 } else {
380 let val = self.map.get(&(x, y));
381
382 val.unwrap_or(&self.default_value)
383 }
384 }
385
386 pub fn get_mut(&mut self, x: Scalar, y: Scalar) -> &mut T {
389 if let Some((x, y)) = self.grid_coordinates_from_global(x, y) {
390 unsafe { self.grid.get_unchecked_mut(x, y) }
393 } else {
394 self.map.entry((x, y)).or_default()
395 }
396 }
397
398 pub fn insert(&mut self, value: T, x: Scalar, y: Scalar) -> T {
401 if let Some((x, y)) = self.grid_coordinates_from_global(x, y) {
402 std::mem::replace(unsafe { self.grid.get_unchecked_mut(x, y) }, value)
405 } else {
406 self.map.insert((x, y), value).unwrap_or_default()
407 }
408 }
409
410 pub fn relocate_grid(&mut self, x_min: Scalar, y_min: Scalar, x_max: Scalar, y_max: Scalar) {
413 let (rows, cols) = rows_cols(x_min, y_min, x_max, y_max);
414 let mut new_grid = Grid::new(rows, cols);
415
416 let old_grid = std::mem::replace(&mut self.grid, Grid::new(0, 0));
417
418 for ((x, y), val) in old_grid.into_iter_indexed() {
419 let vec = self.global_coordinates_from_grid(x, y);
420 self.map.insert(vec, val);
421 }
422
423 for ((x, y), val) in new_grid.indexed_iter_mut() {
424 let vec = self.global_coordinates_from_grid(x, y);
425 *val = self.map.remove(&vec).unwrap_or_default();
426 }
427
428 self.grid = new_grid;
429 self.offset = (-x_min, -y_min);
430 }
431
432 pub fn iter_rect(
436 &self,
437 x_min: Scalar,
438 y_min: Scalar,
439 x_max: Scalar,
440 y_max: Scalar,
441 ) -> impl Iterator<Item = ((Scalar, Scalar), &T)> {
442 (x_min..=x_max).flat_map(move |x| (y_min..=y_max).map(move |y| ((x, y), self.get(x, y))))
443 }
444
445 pub fn foreach_rect_mut(
449 &mut self,
450 x_min: Scalar,
451 y_min: Scalar,
452 x_max: Scalar,
453 y_max: Scalar,
454 mut func: impl FnMut((Scalar, Scalar), &mut T),
455 ) {
456 for x in x_min..=x_max {
457 for y in y_min..=y_max {
458 func((x, y), self.get_mut(x, y))
459 }
460 }
461 }
462
463 pub fn iter_all(&self) -> impl Iterator<Item = ((Scalar, Scalar), &T)> {
465 self.grid
466 .indexed_iter()
467 .map(move |((x, y), elem)| {
468 (
469 (x as Scalar - self.offset.0, y as Scalar - self.offset.1),
470 elem,
471 )
472 })
473 .chain(self.map.iter().map(|(vec, elem)| (*vec, elem)))
474 }
475
476 pub fn iter_all_mut(&mut self) -> impl Iterator<Item = ((Scalar, Scalar), &mut T)> {
478 let offset = self.offset;
479
480 self.grid
481 .indexed_iter_mut()
482 .map(move |((x, y), elem)| ((x as Scalar - offset.0, y as Scalar - offset.1), elem))
483 .chain(self.map.iter_mut().map(|(vec, elem)| (*vec, elem)))
484 }
485
486 pub fn into_iter_all(self) -> impl Iterator<Item = ((Scalar, Scalar), T)> {
488 self.grid
489 .into_iter_indexed()
490 .map(move |((x, y), elem)| {
491 (
492 (x as Scalar - self.offset.0, y as Scalar - self.offset.1),
493 elem,
494 )
495 })
496 .chain(self.map)
497 }
498}
499
500impl<T, S: BuildHasher> Plane<Option<T>, S> {
501 pub fn iter(&self) -> impl Iterator<Item = ((Scalar, Scalar), &T)> {
503 self.grid
504 .indexed_iter()
505 .filter_map(move |((x, y), elem)| {
506 elem.as_ref().map(|el| {
507 (
508 (x as Scalar - self.offset.0, y as Scalar - self.offset.1),
509 el,
510 )
511 })
512 })
513 .chain(
514 self.map
515 .iter()
516 .filter_map(|(vec, elem)| elem.as_ref().map(|el| (*vec, el))),
517 )
518 }
519
520 pub fn iter_mut(&mut self) -> impl Iterator<Item = ((Scalar, Scalar), &mut T)> {
522 let offset = self.offset;
523
524 self.grid
525 .indexed_iter_mut()
526 .filter_map(move |((x, y), elem)| {
527 elem.as_mut()
528 .map(|el| ((x as Scalar - offset.0, y as Scalar - offset.1), el))
529 })
530 .chain(
531 self.map
532 .iter_mut()
533 .filter_map(|(vec, elem)| elem.as_mut().map(|el| (*vec, el))),
534 )
535 }
536
537 pub fn into_iter(self) -> impl Iterator<Item = ((Scalar, Scalar), T)> {
539 self.grid
540 .into_iter_indexed()
541 .filter_map(move |((x, y), elem)| {
542 elem.map(|el| {
543 (
544 (x as Scalar - self.offset.0, y as Scalar - self.offset.1),
545 el,
546 )
547 })
548 })
549 .chain(
550 self.map
551 .into_iter()
552 .filter_map(|(vec, elem)| elem.map(|el| (vec, el))),
553 )
554 }
555}
556
557impl<T: Default, S: Default + BuildHasher> From<Grid<T>> for Plane<T, S> {
558 #[inline]
559 fn from(value: Grid<T>) -> Self {
560 Self::from_grid(value, 0, 0)
561 }
562}
563
564impl<T: Default, S: BuildHasher> From<HashMap<(Scalar, Scalar), T, S>> for Plane<T, S> {
565 #[inline]
566 fn from(value: HashMap<(Scalar, Scalar), T, S>) -> Self {
567 Self::from_hash_map(value, 0, 0, 0, 0)
568 }
569}
570
571impl<T: Default, S: BuildHasher> Index<(Scalar, Scalar)> for Plane<T, S> {
572 type Output = T;
573 #[inline]
574 fn index(&self, (x, y): (Scalar, Scalar)) -> &Self::Output {
575 self.get(x, y)
576 }
577}
578
579impl<T: Default, S: BuildHasher> IndexMut<(Scalar, Scalar)> for Plane<T, S> {
580 #[inline]
581 fn index_mut(&mut self, (x, y): (Scalar, Scalar)) -> &mut Self::Output {
582 self.get_mut(x, y)
583 }
584}
585
586#[cfg(test)]
587mod tests {
588 use super::grid::{grid, Grid};
589 use super::Plane;
590 #[cfg(feature = "hashbrown")]
591 use hashbrown::HashMap;
592 #[cfg(not(feature = "hashbrown"))]
593 use std::collections::HashMap;
594
595 #[test]
596 fn test_iter() {
597 let grid: Grid<Option<i32>> = grid![
598 [Some(1), Some(2)]
599 [Some(3), Some(4)]
600 ];
601 let mut hash_map = HashMap::new();
602 hash_map.insert((23, 40), Some(19));
603 hash_map.insert((40, 40), Some(13));
604 let plane: Plane<Option<i32>> = Plane::from_grid_and_hash_map(grid, hash_map, 2, 2);
605
606 let mut elements: Vec<_> = plane.iter().map(|(a, v)| (a, *v)).collect();
607 elements.sort_by(|(_, v1), (_, v2)| v1.cmp(v2));
608
609 assert_eq!(
610 elements,
611 vec![
612 ((2, 2), 1),
613 ((2, 3), 2),
614 ((3, 2), 3),
615 ((3, 3), 4),
616 ((40, 40), 13),
617 ((23, 40), 19),
618 ]
619 );
620 }
621
622 #[test]
623 fn test_iter_mut() {
624 let grid: Grid<Option<i32>> = grid![
625 [Some(1), Some(2)]
626 [Some(3), Some(4)]
627 ];
628 let mut hash_map = HashMap::new();
629 hash_map.insert((23, 40), Some(19));
630 hash_map.insert((40, 40), Some(13));
631
632 let mut plane: Plane<Option<i32>> = Plane::from_grid_and_hash_map(grid, hash_map, 2, 2);
633
634 for (_, elem) in plane.iter_mut() {
635 *elem += 1;
636 }
637
638 let mut elements: Vec<_> = plane.iter().map(|(a, v)| (a, *v)).collect();
639 elements.sort_by(|(_, v1), (_, v2)| v1.cmp(v2));
640
641 assert_eq!(
642 elements,
643 vec![
644 ((2, 2), 2),
645 ((2, 3), 3),
646 ((3, 2), 4),
647 ((3, 3), 5),
648 ((40, 40), 14),
649 ((23, 40), 20),
650 ]
651 );
652 }
653
654 #[test]
655 fn test_into_iter() {
656 let grid: Grid<Option<i32>> = grid![
657 [Some(1), Some(2)]
658 [Some(3), Some(4)]
659 ];
660 let mut hash_map = HashMap::new();
661 hash_map.insert((23, 40), Some(19));
662 hash_map.insert((40, 40), Some(13));
663 let plane: Plane<Option<i32>> = Plane::from_grid_and_hash_map(grid, hash_map, 2, 2);
664
665 let mut elements: Vec<_> = plane.into_iter().collect();
666 elements.sort_by(|(_, v1), (_, v2)| v1.cmp(v2));
667
668 assert_eq!(
669 elements,
670 vec![
671 ((2, 2), 1),
672 ((2, 3), 2),
673 ((3, 2), 3),
674 ((3, 3), 4),
675 ((40, 40), 13),
676 ((23, 40), 19),
677 ]
678 );
679 }
680
681 #[test]
682 fn test_default_initialization() {
683 let plane: Plane<Option<()>> = Plane::default();
684 let elements: Vec<_> = plane.into_iter().collect();
685
686 assert_eq!(elements.len(), 0);
687 }
688
689 #[test]
690 fn test_inserting_element() {
691 let mut plane = Plane::new(1, 1, 4, 4);
692
693 assert_eq!(*plane.get(1, 1), None);
694 assert_eq!(*plane.get(4, 4), None);
695 assert_eq!(*plane.get(1, 100), None);
696
697 assert_eq!(plane.insert(Some(5), 1, 1), None);
698 assert_eq!(*plane.get(1, 1), Some(5));
699
700 assert_eq!(plane.insert(Some(6), -1, -1), None);
701 assert_eq!(*plane.get(-1, -1), Some(6));
702
703 assert_eq!(plane.insert(Some(8), -1, -1), Some(6));
704 assert_eq!(*plane.get(-1, -1), Some(8));
705
706 assert_eq!(plane.insert(Some(7), 4, 4), None);
707 assert_eq!(*plane.get(4, 4), Some(7));
708
709 assert_eq!(plane.insert(Some(9), 4, 4), Some(7));
710 assert_eq!(*plane.get(4, 4), Some(9));
711 }
712
713 #[test]
714 fn test_get_element_mut() {
715 let mut plane = Plane::new(1, 1, 4, 4);
716 plane.insert(Some(8), 1, 1);
717 if let Some(elem) = plane.get_mut(1, 1) {
718 *elem = 10;
719 }
720 assert_eq!(*plane.get(1, 1), Some(10));
721 }
722
723 #[test]
724 fn test_iter_rect() {
725 let mut plane = Plane::new(1, 1, 4, 4);
726 plane.insert((1, 1), 1, 1);
727 plane.insert((2, 1), 2, 1);
728 plane.insert((3, 1), 3, 1);
729 plane.insert((4, 1), 4, 1);
730 plane.insert((5, 1), 5, 1);
731
732 plane.insert((1, 2), 1, 2);
733 plane.insert((2, 2), 2, 2);
734 plane.insert((3, 2), 3, 2);
735 plane.insert((4, 2), 4, 2);
736 plane.insert((5, 2), 5, 2);
737
738 plane.insert((1, 3), 1, 3);
739 plane.insert((2, 3), 2, 3);
740 plane.insert((3, 3), 3, 3);
741 plane.insert((4, 3), 4, 3);
742 plane.insert((5, 3), 5, 3);
743
744 plane.insert((1, 4), 1, 4);
745 plane.insert((2, 4), 2, 4);
746 plane.insert((3, 4), 3, 4);
747 plane.insert((4, 4), 4, 4);
748 plane.insert((5, 4), 5, 4);
749
750 plane.insert((1, 5), 1, 5);
751 plane.insert((2, 5), 2, 5);
752 plane.insert((3, 5), 3, 5);
753 plane.insert((4, 5), 4, 5);
754 plane.insert((5, 5), 5, 5);
755
756 let mut value: Vec<_> = plane.iter_rect(2, 2, 6, 5).map(|(a, v)| (a, *v)).collect();
757 value.sort_by(
758 |((x1, y1), _), ((x2, y2), _)| {
759 if x1 == x2 {
760 y1.cmp(y2)
761 } else {
762 x1.cmp(x2)
763 }
764 },
765 );
766
767 assert_eq!(
768 value,
769 vec![
770 ((2, 2), (2, 2)),
771 ((2, 3), (2, 3)),
772 ((2, 4), (2, 4)),
773 ((2, 5), (2, 5)),
774 ((3, 2), (3, 2)),
775 ((3, 3), (3, 3)),
776 ((3, 4), (3, 4)),
777 ((3, 5), (3, 5)),
778 ((4, 2), (4, 2)),
779 ((4, 3), (4, 3)),
780 ((4, 4), (4, 4)),
781 ((4, 5), (4, 5)),
782 ((5, 2), (5, 2)),
783 ((5, 3), (5, 3)),
784 ((5, 4), (5, 4)),
785 ((5, 5), (5, 5)),
786 ((6, 2), (0, 0)),
787 ((6, 3), (0, 0)),
788 ((6, 4), (0, 0)),
789 ((6, 5), (0, 0)),
790 ]
791 );
792 }
793
794 #[test]
795 fn test_iter_rect_mut() {
796 let mut plane = Plane::new(1, 1, 4, 4);
797 plane.insert((1, 1), 1, 1);
798 plane.insert((2, 1), 2, 1);
799 plane.insert((3, 1), 3, 1);
800 plane.insert((4, 1), 4, 1);
801 plane.insert((5, 1), 5, 1);
802
803 plane.insert((1, 2), 1, 2);
804 plane.insert((2, 2), 2, 2);
805 plane.insert((3, 2), 3, 2);
806 plane.insert((4, 2), 4, 2);
807 plane.insert((5, 2), 5, 2);
808
809 plane.insert((1, 3), 1, 3);
810 plane.insert((2, 3), 2, 3);
811 plane.insert((3, 3), 3, 3);
812 plane.insert((4, 3), 4, 3);
813 plane.insert((5, 3), 5, 3);
814
815 plane.insert((1, 4), 1, 4);
816 plane.insert((2, 4), 2, 4);
817 plane.insert((3, 4), 3, 4);
818 plane.insert((4, 4), 4, 4);
819 plane.insert((5, 4), 5, 4);
820
821 plane.insert((1, 5), 1, 5);
822 plane.insert((2, 5), 2, 5);
823 plane.insert((3, 5), 3, 5);
824 plane.insert((4, 5), 4, 5);
825 plane.insert((5, 5), 5, 5);
826
827 plane.foreach_rect_mut(3, 2, 6, 5, |_, (xv, yv)| {
828 *xv += 10;
829 *yv += 20;
830 });
831
832 let mut value: Vec<_> = plane.iter_rect(2, 2, 7, 5).map(|(a, v)| (a, *v)).collect();
833 value.sort_by(
834 |((x1, y1), _), ((x2, y2), _)| {
835 if x1 == x2 {
836 y1.cmp(y2)
837 } else {
838 x1.cmp(x2)
839 }
840 },
841 );
842
843 assert_eq!(
844 value,
845 vec![
846 ((2, 2), (2, 2)),
847 ((2, 3), (2, 3)),
848 ((2, 4), (2, 4)),
849 ((2, 5), (2, 5)),
850 ((3, 2), (13, 22)),
851 ((3, 3), (13, 23)),
852 ((3, 4), (13, 24)),
853 ((3, 5), (13, 25)),
854 ((4, 2), (14, 22)),
855 ((4, 3), (14, 23)),
856 ((4, 4), (14, 24)),
857 ((4, 5), (14, 25)),
858 ((5, 2), (15, 22)),
859 ((5, 3), (15, 23)),
860 ((5, 4), (15, 24)),
861 ((5, 5), (15, 25)),
862 ((6, 2), (10, 20)),
863 ((6, 3), (10, 20)),
864 ((6, 4), (10, 20)),
865 ((6, 5), (10, 20)),
866 ((7, 2), (0, 0)),
867 ((7, 3), (0, 0)),
868 ((7, 4), (0, 0)),
869 ((7, 5), (0, 0)),
870 ]
871 );
872 }
873}