simple_grid/lib.rs
1//! A simple and small library for representing two-dimensional grids.
2
3mod index;
4#[cfg(feature = "linalg")]
5pub mod linalg;
6pub(crate) mod utils;
7
8pub use index::GridIndex;
9use index::LinearIndexError;
10use std::{
11 collections::HashMap,
12 fmt::Display,
13 ops::{Index, IndexMut},
14};
15use utils::*;
16
17/// A two-dimensional array, indexed with x-and-y-coordinates (columns and rows).
18#[derive(Debug, Clone, PartialEq, Eq, Hash)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
20#[non_exhaustive]
21pub struct Grid<T> {
22 /// The width of the grid (number of columns).
23 pub(crate) width: usize,
24 /// The height of the grid (number of rows).
25 pub(crate) height: usize,
26 /// The data of the grid, stored in a linear array of `width * height` length.
27 data: Vec<T>,
28}
29
30impl<T> Grid<T> {
31 /// Construct a new Grid.
32 ///
33 /// ## Panics
34 /// * If `width * height != data.len()`
35 /// * If one of (but not both) `width` and `height` is zero.
36 ///
37 /// ## Example
38 /// ```
39 /// # use simple_grid::Grid;
40 /// // construct a 2x3 (width x height) grid of chars
41 /// let grid = Grid::new(2, 3, "abcdef".chars().collect());
42 /// println!("{}", grid.to_pretty_string());
43 /// // prints:
44 /// // a b
45 /// // c d
46 /// // e f
47 /// ```
48 pub fn new(width: usize, height: usize, data: Vec<T>) -> Self {
49 if width * height != data.len() {
50 panic!(
51 "width * height was {}, but must be equal to data.len(), which was {}",
52 width * height,
53 data.len()
54 );
55 }
56 panic_if_width_xor_height_is_zero(width, height);
57
58 Self {
59 width,
60 height,
61 data,
62 }
63 }
64
65 /// Construct a `Grid` from another, by converting each element.
66 ///
67 /// ## Example
68 /// ```rust
69 /// # use simple_grid::Grid;
70 /// let u32_grid: Grid<u32> = Grid::new(2, 2, vec![1, 2, 3, 4]);
71 /// let f64_grid: Grid<f64> = Grid::from_grid(u32_grid);
72 /// assert_eq!(f64_grid, Grid::new(2, 2, vec![1.0, 2.0, 3.0, 4.0]));
73 /// ```
74 pub fn from_grid<U>(other: Grid<U>) -> Grid<T>
75 where
76 T: From<U>,
77 {
78 let (width, height) = other.dimensions();
79 let mut new_data = Vec::with_capacity(other.area());
80 for item in other.take_data() {
81 new_data.push(T::from(item));
82 }
83
84 Grid::new(width, height, new_data)
85 }
86
87 /// Returns the width (number of columns) of the `Grid`.
88 pub fn width(&self) -> usize {
89 self.width
90 }
91
92 /// Returns the height (number of rows) of the `Grid`.
93 pub fn height(&self) -> usize {
94 self.height
95 }
96
97 /// Consumes the `Grid`, creating a new one from a subset of the original.
98 ///
99 /// ## Arguments
100 /// * `column_start` - Left bound for the subgrid.
101 /// * `row_start` - Upper bound for the subgrid.
102 /// * `width` - Number of columns in the subgrid.
103 /// * `height` - Number of rows in the subgrid.
104 ///
105 /// ## Panics
106 /// * If `width` or `height` (but not both) are 0. If both are 0, the resulting subgrid will be an empty (0 by 0) `Grid`.
107 /// * If `column_start` is out of bounds.
108 /// * If `row_start` is out of bounds.
109 ///
110 /// ## Example
111 /// ```rust
112 /// # use simple_grid::Grid;
113 /// let original: Grid<u32> = Grid::new(3, 3, (1..=9).collect());
114 /// let subgrid = original.subgrid(1, 0, 2, 2);
115 /// assert_eq!(subgrid, Grid::new(2, 2, vec![2, 3, 5, 6]));
116 /// ```
117 pub fn subgrid(
118 self,
119 column_start: usize,
120 row_start: usize,
121 width: usize,
122 height: usize,
123 ) -> Grid<T> {
124 panic_if_width_xor_height_is_zero(width, height);
125 panic_if_column_out_of_bounds(&self, column_start);
126 panic_if_row_out_of_bounds(&self, row_start);
127
128 let column_end = column_start + width;
129 let row_end = row_start + height;
130
131 let is_within_bounds = |idx: GridIndex| {
132 idx.column() >= column_start
133 && idx.column() < column_end
134 && idx.row() >= row_start
135 && idx.row() < row_end
136 };
137
138 let indices = self.indices();
139 let mut data = self.data;
140
141 for idx in indices.rev() {
142 if !is_within_bounds(idx) {
143 let linear_idx = idx.to_linear_idx_in(self.width);
144 data.remove(linear_idx);
145 }
146 }
147
148 Grid::new(width, height, data)
149 }
150
151 /// Returns a tuple containing the (width, height) of the grid.
152 /// ## Example
153 /// ```rust
154 /// # use simple_grid::Grid;
155 /// let grid = Grid::new(2, 3, vec![1, 2, 3, 4, 5, 6]);
156 /// assert_eq!(grid.dimensions(), (2, 3));
157 /// ```
158 pub fn dimensions(&self) -> (usize, usize) {
159 (self.width, self.height)
160 }
161
162 /// Checks if the Grid is square (number of columns and rows is equal).
163 ///
164 /// Note: an empty Grid is not square (even though columns and rows is 0).
165 /// ## Example
166 /// ```rust
167 /// # use simple_grid::Grid;
168 /// let grid = Grid::new(2, 2, vec![1, 2, 3, 4]);
169 /// assert!(grid.is_square());
170 /// let grid = Grid::new(2, 3, vec![1, 2, 3, 4, 5, 6]);
171 /// assert!(!grid.is_square());
172 /// ```
173 pub fn is_square(&self) -> bool {
174 !self.is_empty() && self.width == self.height
175 }
176
177 /// Returns the size of this Grid, panicking if the Grid is not square.
178 #[cfg(feature = "linalg")]
179 fn square_size(&self) -> usize {
180 panic_if_not_square(self);
181
182 self.width()
183 }
184
185 fn is_empty(&self) -> bool {
186 let ans = self.width == 0 || self.height == 0;
187 if ans {
188 debug_assert!(self.width == 0);
189 debug_assert!(self.height == 0);
190 }
191 ans
192 }
193
194 /// Returns the area (number of columns * number of rows) of the grid.
195 /// ## Example
196 /// ```rust
197 /// # use simple_grid::Grid;
198 /// let grid = Grid::new(2, 3, vec![2, 4, 8, 16, 32, 64]);
199 /// assert_eq!(grid.area(), 6);
200 /// ```
201 pub fn area(&self) -> usize {
202 self.width * self.height
203 }
204
205 /// Attempts to get a reference to the element at `idx`.
206 ///
207 /// Returns `None` if `idx` is out of bounds.
208 /// ## Example
209 /// ```rust
210 /// # use simple_grid::Grid;
211 /// let grid = Grid::new(2, 3, vec![2, 4, 8, 16, 32, 64]);
212 /// assert_eq!(grid.get((1, 1)), Some(&16));
213 /// assert!(grid.get((10, 15)).is_none());
214 /// ```
215 pub fn get<I>(&self, idx: I) -> Option<&T>
216 where
217 GridIndex: From<I>,
218 {
219 let index: usize = self.linear_idx(GridIndex::from(idx)).ok()?;
220
221 Some(&self.data[index])
222 }
223
224 /// Attempts to get a mutable reference to the element at `idx`
225 ///
226 /// Returns `None` if `idx` is out of bounds.
227 pub fn get_mut<I>(&mut self, idx: I) -> Option<&mut T>
228 where
229 GridIndex: From<I>,
230 {
231 let index: usize = self.linear_idx(GridIndex::from(idx)).ok()?;
232
233 Some(&mut self.data[index])
234 }
235
236 /// Return an iterator over the cells in the grid.
237 ///
238 /// Iterates from left to right (starting with row 0, then row 1 etc.).
239 pub fn cell_iter(&self) -> impl DoubleEndedIterator<Item = &T> {
240 self.data.iter()
241 }
242
243 /// Return an iterator over the columns in the row with index `row`.
244 ///
245 /// ## Panics
246 /// * If `row >= self.height`
247 ///
248 /// ## Example
249 /// ```
250 /// # use simple_grid::Grid;
251 /// let grid = Grid::new(10, 10, (1..=100).collect());
252 /// let items_in_row_2: Vec<u32> = grid.row_iter(2).cloned().collect();
253 /// assert_eq!(items_in_row_2, vec![21, 22, 23, 24, 25, 26, 27, 28, 29, 30]);
254 /// ```
255 pub fn row_iter(&self, row: usize) -> impl DoubleEndedIterator<Item = &T> {
256 panic_if_row_out_of_bounds(self, row);
257
258 (0..self.width).map(move |column| &self[(column, row)])
259 }
260
261 /// Return an iterator over the rows in the column with index `column`.
262 ///
263 /// ## Panics
264 /// * If `column >= self.width`
265 ///
266 /// ## Example
267 /// ```
268 /// # use simple_grid::Grid;
269 /// let grid = Grid::new(10, 10, (1..=100).collect());
270 /// let items_in_column_2: Vec<u32> = grid.column_iter(2).cloned().collect();
271 /// assert_eq!(items_in_column_2, vec![3, 13, 23, 33, 43, 53, 63, 73, 83, 93]);
272 /// ```
273 pub fn column_iter(&self, column: usize) -> impl DoubleEndedIterator<Item = &T> {
274 panic_if_column_out_of_bounds(self, column);
275 (0..self.height).map(move |row| &self[(column, row)])
276 }
277
278 /// Insert a row at index `row`, shifting all other rows downward (row `n` becomes row `n+1` and so on).
279 ///
280 /// ## Panics
281 /// * If `row_contents.is_empty()`
282 /// * If `row_contents.len() != self.width`
283 /// * If `row > self.height` (note that `row == self.height` is allowed, to add a row at the bottom of the `Grid`)
284 ///
285 /// ## Example
286 /// ```
287 /// # use simple_grid::Grid;
288 /// let mut grid = Grid::new(2, 2, "abcd".chars().collect());
289 /// grid.insert_row(1, "xx".chars().collect());
290 /// assert_eq!(grid, Grid::new(2, 3, "abxxcd".chars().collect()));
291 /// println!("{}", grid.to_pretty_string());
292 /// // prints:
293 /// // a b
294 /// // x x
295 /// // c d
296 /// ```
297 pub fn insert_row(&mut self, row: usize, row_contents: Vec<T>) {
298 panic_if_row_is_empty(&row_contents);
299
300 if self.is_empty() && row == 0 {
301 // special case, if the grid is empty, we can insert a row of any width
302 self.width = row_contents.len();
303 self.height = 1;
304 self.data = row_contents;
305 return;
306 }
307
308 panic_if_row_length_is_not_equal_to_width(self, row_contents.len());
309
310 if row > self.height {
311 // for example, if the height of the grid is 1,
312 // we still want to support adding a column at the bottom
313 panic!(
314 "row insertion index (is {}) should be <= height (is {})",
315 row, self.height
316 );
317 }
318
319 let start_idx = GridIndex::new(0, row).to_linear_idx_in(self.width);
320
321 for (elem, idx) in row_contents.into_iter().zip(start_idx..) {
322 self.data.insert(idx, elem);
323 }
324
325 self.height += 1;
326 }
327
328 /// Add a row to the bottom of the `Grid`.
329 ///
330 /// ## Example
331 /// ```rust
332 /// # use simple_grid::Grid;
333 /// let mut grid = Grid::new(2, 2, "abcd".chars().collect());
334 /// grid.push_row(vec!['x', 'x']);
335 /// assert_eq!(grid, Grid::new(2, 3, "abcdxx".chars().collect()));
336 /// println!("{}", grid.to_pretty_string());
337 /// // prints
338 /// // a b
339 /// // c d
340 /// // x x
341 /// ```
342 pub fn push_row(&mut self, row_contents: Vec<T>) {
343 self.insert_row(self.height(), row_contents);
344 }
345
346 /// Replace the contents in a row.
347 ///
348 /// Returns the old elements of the row.
349 ///
350 /// ## Panics
351 /// * If `row >= self.height`
352 /// * If `data.len() != self.width`
353 pub fn replace_row(&mut self, row: usize, data: Vec<T>) -> Vec<T> {
354 panic_if_row_out_of_bounds(self, row);
355 panic_if_row_length_is_not_equal_to_width(self, data.len());
356
357 let mut old = Vec::with_capacity(self.width);
358 for (column, elem) in data.into_iter().enumerate() {
359 let old_value = self.replace_cell((column, row), elem);
360 old.push(old_value);
361 }
362 old
363 }
364
365 /// Remove row at `row`, shifting all rows with higher indices "upward" (row `n` becomes row `n-1`).
366 ///
367 /// Returns the row that was removed.
368 ///
369 /// ## Panics
370 /// * If `row >= self.height`
371 ///
372 /// ## Example
373 /// ```
374 /// # use simple_grid::Grid;
375 /// let mut grid = Grid::new(2, 2, "abcd".chars().collect());
376 /// grid.remove_row(1);
377 /// assert_eq!(grid, Grid::new(2, 1, "ab".chars().collect()));
378 /// println!("{}", grid.to_pretty_string());
379 /// // prints:
380 /// // a b
381 /// ```
382 pub fn remove_row(&mut self, row: usize) -> Vec<T> {
383 panic_if_row_out_of_bounds(self, row);
384
385 let start_idx = self.linear_idx(GridIndex::new(0, row)).unwrap();
386
387 let r: Vec<T> = self.data.drain(start_idx..start_idx + self.width).collect();
388 self.height -= 1;
389
390 if self.height == 0 {
391 // no rows remain, so the grid is empty
392 self.width = 0;
393 }
394 r
395 }
396
397 /// Remove the bottom row, returning it (if it exists).
398 ///
399 /// Returns `None` if the height of the `Grid` is zero.
400 ///
401 /// ## Example
402 /// ```rust
403 /// # use simple_grid::Grid;
404 /// let mut grid = Grid::new(2, 2, "abcd".chars().collect());
405 /// let bottom_row = grid.pop_row();
406 /// assert_eq!(bottom_row, Some(vec!['c', 'd']));
407 /// assert_eq!(grid, Grid::new(2, 1, "ab".chars().collect()));
408 /// ```
409 pub fn pop_row(&mut self) -> Option<Vec<T>> {
410 if self.height() == 0 {
411 None
412 } else {
413 Some(self.remove_row(self.height() - 1))
414 }
415 }
416
417 /// Swap two rows in the grid.
418 ///
419 /// ## Panics
420 /// * If either of the row indices are out of bounds.
421 pub fn swap_rows(&mut self, row1: usize, row2: usize) {
422 panic_if_row_out_of_bounds(self, row1);
423 panic_if_row_out_of_bounds(self, row2);
424
425 if row1 != row2 {
426 for column in self.columns() {
427 let linear_idx1 = self.linear_idx(GridIndex::new(column, row1)).unwrap();
428 let linear_idx2 = self.linear_idx(GridIndex::new(column, row2)).unwrap();
429 self.data.swap(linear_idx1, linear_idx2);
430 }
431 }
432 }
433
434 /// Insert a column at index `column`, shifting all other columns to the right (column `n` becomes column `n+1` and so on).
435 ///
436 /// ## Panics
437 /// * If `column_contents.is_empty()`
438 /// * If `column_contents.len() != self.height`
439 /// * If `column > self.width` (note that `column == self.width` is allowed, to add a column at the right of the `Grid`)
440 ///
441 /// ## Example
442 /// ```
443 /// # use simple_grid::Grid;
444 /// let mut grid = Grid::new(2, 2, "abcd".chars().collect());
445 /// grid.insert_column(1, "xx".chars().collect());
446 /// assert_eq!(grid, Grid::new(3, 2, "axbcxd".chars().collect()));
447 /// println!("{}", grid.to_pretty_string());
448 /// // prints:
449 /// // a x b
450 /// // c x d
451 /// ```
452 pub fn insert_column(&mut self, column: usize, column_contents: Vec<T>) {
453 panic_if_column_is_empty(&column_contents);
454
455 if self.is_empty() && column == 0 {
456 // special case, if the grid is empty, we can insert a column of any height
457 self.height = column_contents.len();
458 self.width = 1;
459 self.data = column_contents;
460 return;
461 }
462
463 panic_if_column_length_is_not_equal_to_height(self, column_contents.len());
464
465 if column > self.width {
466 // for example, if the width of the grid is 1,
467 // we still want to support adding a column at the furthest right
468 panic!(
469 "column insertion index (is {}) should be <= width (is {})",
470 column, self.width
471 );
472 }
473
474 let indices: Vec<usize> = (0..column_contents.len())
475 .map(|row| GridIndex::new(column, row).to_linear_idx_in(self.width + 1))
476 .collect();
477
478 for (elem, idx) in column_contents.into_iter().zip(indices.into_iter()) {
479 self.data.insert(idx, elem);
480 }
481
482 self.width += 1;
483 }
484
485 /// Add a column to the right of the `Grid`.
486 ///
487 /// ## Example
488 /// ```rust
489 /// # use simple_grid::Grid;
490 /// let mut grid = Grid::new(2, 2, "abcd".chars().collect());
491 /// grid.push_column(vec!['x', 'x']);
492 /// assert_eq!(grid, Grid::new(3, 2, "abxcdx".chars().collect()));
493 /// println!("{}", grid.to_pretty_string());
494 /// // prints
495 /// // a b x
496 /// // c d x
497 /// ```
498 pub fn push_column(&mut self, column_contents: Vec<T>) {
499 self.insert_column(self.width(), column_contents);
500 }
501
502 /// Replace the contents in a column.
503 ///
504 /// Returns the old elements of the column.
505 ///
506 /// ## Panics
507 /// * If `column >= self.width`
508 /// * If `data.len() != self.height`
509 pub fn replace_column(&mut self, column: usize, data: Vec<T>) -> Vec<T> {
510 panic_if_column_out_of_bounds(self, column);
511 panic_if_column_length_is_not_equal_to_height(self, data.len());
512
513 let mut old = Vec::with_capacity(self.height);
514 for (row, elem) in data.into_iter().enumerate() {
515 let old_value = self.replace_cell((column, row), elem);
516 old.push(old_value);
517 }
518
519 old
520 }
521
522 /// Swap two columns in the grid.
523 ///
524 /// ## Panics
525 /// * If either of the column indices are out of bounds.
526 pub fn swap_columns(&mut self, column1: usize, column2: usize) {
527 panic_if_column_out_of_bounds(self, column1);
528 panic_if_column_out_of_bounds(self, column2);
529
530 if column1 != column2 {
531 for row in self.rows() {
532 let linear_idx1 = self.linear_idx(GridIndex::new(column1, row)).unwrap();
533 let linear_idx2 = self.linear_idx(GridIndex::new(column2, row)).unwrap();
534 self.data.swap(linear_idx1, linear_idx2);
535 }
536 }
537 }
538
539 /// Remove column at `column`, shifting all columns with higher indices "left" (column `n` becomes column `n-1`).
540 ///
541 /// Returns the column that was removed.
542 ///
543 /// ## Panics
544 /// * If `column >= self.width`
545 ///
546 /// ## Example
547 /// ```
548 /// # use simple_grid::Grid;
549 /// let mut grid = Grid::new(2, 2, "abcd".chars().collect());
550 /// grid.remove_column(1);
551 /// assert_eq!(grid, Grid::new(1, 2, "ac".chars().collect()));
552 /// println!("{}", grid.to_pretty_string());
553 /// // prints:
554 /// // a
555 /// // c
556 /// ```
557 pub fn remove_column(&mut self, column: usize) -> Vec<T> {
558 panic_if_column_out_of_bounds(self, column);
559
560 let indices: Vec<usize> = self
561 .rows()
562 .map(|row| self.linear_idx(GridIndex::new(column, row)).unwrap())
563 .collect();
564
565 let mut c = Vec::with_capacity(self.height);
566
567 for idx in indices.into_iter().rev() {
568 let elem = self.data.remove(idx);
569 c.insert(0, elem);
570 }
571
572 self.width -= 1;
573 if self.width == 0 {
574 // no columns remain, so the grid is empty
575 self.height = 0;
576 }
577
578 c
579 }
580
581 /// Remove the rightmost column, returning it (if it exists).
582 ///
583 /// Returns `None` if the width of the `Grid` is zero.
584 ///
585 /// ## Example
586 /// ```rust
587 /// # use simple_grid::Grid;
588 /// let mut grid = Grid::new(2, 2, "abcd".chars().collect());
589 /// let rightmost_column = grid.pop_column();
590 /// assert_eq!(rightmost_column, Some(vec!['b', 'd']));
591 /// assert_eq!(grid, Grid::new(1, 2, "ac".chars().collect()));
592 /// ```
593 pub fn pop_column(&mut self) -> Option<Vec<T>> {
594 if self.width() == 0 {
595 None
596 } else {
597 Some(self.remove_column(self.width() - 1))
598 }
599 }
600
601 /// Swap the values in two cells in the grid.
602 ///
603 /// ## Panics
604 /// * If either index is out of bounds.
605 ///
606 /// ## Example
607 /// ```rust
608 /// # use simple_grid::Grid;
609 /// let mut grid = Grid::new(2, 3, vec![1, 2, 3, 4, 5, 6]);
610 /// grid.swap_cells((1, 1), (0, 2));
611 /// assert_eq!(grid, Grid::new(2, 3, vec![1, 2, 3, 5, 4, 6]));
612 /// ```
613 pub fn swap_cells<I>(&mut self, a: I, b: I)
614 where
615 GridIndex: From<I>,
616 {
617 let a_idx = GridIndex::from(a);
618 let b_idx = GridIndex::from(b);
619
620 panic_if_index_out_of_bounds(self, a_idx);
621 panic_if_index_out_of_bounds(self, b_idx);
622
623 let a_linear = self.linear_idx(a_idx).unwrap();
624 let b_linear = self.linear_idx(b_idx).unwrap();
625 self.data.swap(a_linear, b_linear);
626 }
627
628 /// Replace the contents in a cell.
629 ///
630 /// Returns the old element of the cell.
631 ///
632 /// ## Panics
633 /// * If `idx` is out of bounds.
634 pub fn replace_cell<I>(&mut self, idx: I, elem: T) -> T
635 where
636 GridIndex: From<I>,
637 {
638 let idx = GridIndex::from(idx);
639 panic_if_index_out_of_bounds(self, idx);
640 let linear = self.linear_idx_unchecked(idx);
641 std::mem::replace(&mut self.data[linear], elem)
642 }
643
644 /// Rotate the grid counter-clockwise 90 degrees.
645 ///
646 /// ## Example
647 /// ```
648 /// # use simple_grid::Grid;
649 /// let mut grid = Grid::new(2, 2, "abcd".chars().collect());
650 /// println!("{}", grid.to_pretty_string());
651 /// // prints:
652 /// // a b
653 /// // c d
654 ///
655 /// grid.rotate_ccw();
656 /// assert_eq!(grid, Grid::new(2, 2, "bdac".chars().collect()));
657 /// println!("{}", grid.to_pretty_string());
658 /// // prints:
659 /// // b d
660 /// // a c
661 /// ```
662 pub fn rotate_ccw(&mut self) {
663 if self.is_empty() {
664 return;
665 }
666
667 let mut target_index = HashMap::new();
668 let mut current_target = 0;
669 for column in self.columns().rev() {
670 for row in self.rows() {
671 let from = self.linear_idx(GridIndex::new(column, row)).unwrap();
672 target_index.insert(from, current_target);
673 current_target += 1;
674 }
675 }
676
677 self.transform(target_index);
678
679 std::mem::swap(&mut self.width, &mut self.height);
680 }
681
682 /// Rotate the grid clockwise 90 degrees.
683 ///
684 /// ## Example
685 /// ```
686 /// # use simple_grid::Grid;
687 /// let mut grid = Grid::new(2, 2, "abcd".chars().collect());
688 /// println!("{}", grid.to_pretty_string());
689 /// // prints:
690 /// // a b
691 /// // c d
692 ///
693 /// grid.rotate_cw();
694 /// assert_eq!(grid, Grid::new(2, 2, "cadb".chars().collect()));
695 /// println!("{}", grid.to_pretty_string());
696 /// // prints:
697 /// // c a
698 /// // d b
699 /// ```
700 pub fn rotate_cw(&mut self) {
701 if self.is_empty() {
702 return;
703 }
704
705 let mut target_index = HashMap::new();
706 let mut current_target = 0;
707 for column in self.columns() {
708 for row in self.rows().rev() {
709 let from = self.linear_idx(GridIndex::new(column, row)).unwrap();
710 target_index.insert(from, current_target);
711 current_target += 1;
712 }
713 }
714
715 self.transform(target_index);
716
717 std::mem::swap(&mut self.width, &mut self.height);
718 }
719
720 /// Flip the grid horizontally, so that the first column becomes the last.
721 ///
722 /// ## Example
723 /// ```
724 /// # use simple_grid::Grid;
725 /// let mut grid = Grid::new(2, 2, "abcd".chars().collect());
726 /// println!("{}", grid.to_pretty_string());
727 /// // prints:
728 /// // a b
729 /// // c d
730 ///
731 /// grid.flip_horizontally();
732 /// assert_eq!(grid, Grid::new(2, 2, "badc".chars().collect()));
733 /// println!("{}", grid.to_pretty_string());
734 /// // prints:
735 /// // b a
736 /// // d c
737 /// ```
738 pub fn flip_horizontally(&mut self) {
739 if self.is_empty() {
740 return;
741 }
742
743 let mut target_index = HashMap::new();
744 let mut current_target = 0;
745 for row in self.rows() {
746 for column in self.columns().rev() {
747 let from = self.linear_idx(GridIndex::new(column, row)).unwrap();
748 target_index.insert(from, current_target);
749 current_target += 1;
750 }
751 }
752
753 self.transform(target_index);
754 }
755
756 /// Flip the grid vertically, so that the first row becomes the last.
757 ///
758 /// ## Example
759 /// ```
760 /// # use simple_grid::Grid;
761 /// let mut grid = Grid::new(2, 2, "abcd".chars().collect());
762 /// println!("{}", grid.to_pretty_string());
763 /// // prints:
764 /// // a b
765 /// // c d
766 ///
767 /// grid.flip_vertically();
768 /// assert_eq!(grid, Grid::new(2, 2, "cdab".chars().collect()));
769 /// println!("{}", grid.to_pretty_string());
770 /// // prints:
771 /// // c d
772 /// // a b
773 /// ```
774 pub fn flip_vertically(&mut self) {
775 if self.is_empty() {
776 return;
777 }
778
779 let mut target_index = HashMap::new();
780 let mut current_target = 0;
781 for row in self.rows().rev() {
782 for column in self.columns() {
783 let from = self.linear_idx(GridIndex::new(column, row)).unwrap();
784 target_index.insert(from, current_target);
785 current_target += 1;
786 }
787 }
788
789 self.transform(target_index);
790 }
791
792 /// Transpose the grid along the diagonal, so that cells at index (x, y) end up at index (y, x).
793 ///
794 /// ## Example
795 /// ```
796 /// # use simple_grid::Grid;
797 /// let mut grid = Grid::new(2, 3, "abcdef".chars().collect());
798 /// println!("{}", grid.to_pretty_string());
799 /// // prints:
800 /// // a b
801 /// // c d
802 /// // e f
803 ///
804 /// grid.transpose();
805 /// assert_eq!(grid, Grid::new(3, 2, "acebdf".chars().collect()));
806 /// println!("{}", grid.to_pretty_string());
807 /// // prints:
808 /// // a c e
809 /// // b d f
810 /// ```
811 pub fn transpose(&mut self) {
812 if self.is_empty() {
813 return;
814 }
815
816 let mut target_index = HashMap::new();
817 let mut current_target = 0;
818 for column in self.columns() {
819 for row in self.rows() {
820 let idx = GridIndex::new(column, row);
821 let from = self.linear_idx(idx).unwrap();
822 target_index.insert(from, current_target);
823 current_target += 1;
824 }
825 }
826
827 self.transform(target_index);
828
829 std::mem::swap(&mut self.width, &mut self.height);
830 }
831
832 /// Transforms the Grid, moving the contents of cells to new indices based on a hashmap.
833 fn transform(&mut self, mut target_index: HashMap<usize, usize>) {
834 while !target_index.is_empty() {
835 let current = *target_index.keys().next().unwrap();
836 let mut target = target_index.remove(¤t).unwrap();
837
838 loop {
839 // swap current with its target until a cycle has been reached
840 self.data.swap(current, target);
841 match target_index.remove(&target) {
842 Some(t) => target = t,
843 None => {
844 break;
845 }
846 }
847 }
848 }
849 }
850
851 /// Convert a GridIndex into an index in the internal data of the Grid.
852 fn linear_idx(&self, idx: GridIndex) -> Result<usize, LinearIndexError> {
853 if idx.row() >= self.height {
854 Err(LinearIndexError::RowTooHigh)
855 } else if idx.column() >= self.width {
856 Err(LinearIndexError::ColumnTooHigh)
857 } else {
858 Ok(idx.to_linear_idx_in(self.width))
859 }
860 }
861
862 /// Same as `linear_idx`, but panics when `idx` is out of bounds.
863 fn linear_idx_unchecked(&self, idx: GridIndex) -> usize {
864 panic_if_index_out_of_bounds(self, idx);
865 idx.to_linear_idx_in(self.width)
866 }
867
868 /// Return an iterator over the row indices in this grid. Allows you to write `for row in grid.rows()` instead of `for row in 0..grid.height()`.
869 ///
870 /// ## Example
871 /// ```rust
872 /// # use simple_grid::Grid;
873 /// let grid: Grid<u32> = Grid::new_default(3, 5);
874 /// let rows: Vec<usize> = grid.rows().collect();
875 /// assert_eq!(rows, vec![0, 1, 2, 3, 4]);
876 /// ```
877 pub fn rows(&self) -> impl DoubleEndedIterator<Item = usize> {
878 0..self.height
879 }
880
881 /// Return an iterator over the column indices in this grid. Allows you to write `for column in grid.columns()` instead of `for column in 0..grid.width()`.
882 ///
883 /// ## Example
884 /// ```rust
885 /// # use simple_grid::Grid;
886 /// let grid: Grid<u32> = Grid::new_default(2, 5);
887 /// let rows: Vec<usize> = grid.columns().collect();
888 /// assert_eq!(rows, vec![0, 1]);
889 /// ```
890 pub fn columns(&self) -> impl DoubleEndedIterator<Item = usize> {
891 0..self.width
892 }
893
894 /// Searches for an element in the `Grid` matching a predicate, returning its index.
895 ///
896 /// Iterates from left to right (looks through row 0 followed by row 1 etc.).
897 ///
898 /// Returns the index of the first element that matches the predicate.
899 ///
900 /// ## Example
901 /// ```rust
902 /// # use simple_grid::{Grid, GridIndex};
903 /// let grid = Grid::new(2, 3, vec![1, 2, 3, 4, 5, 6]);
904 /// let position_of_4 = grid.position(|&e| e == 4);
905 /// assert_eq!(position_of_4, Some(GridIndex::new(1, 1)));
906 /// ```
907 pub fn position<P>(&self, predicate: P) -> Option<GridIndex>
908 where
909 P: Fn(&T) -> bool,
910 {
911 for idx in self.indices() {
912 let elem = &self[idx];
913 if predicate(elem) {
914 return Some(idx);
915 }
916 }
917 None
918 }
919
920 /// Return an iterator over the cell indices in this grid. Iterates from top to bottom, left to right.
921 ///
922 /// ## Example
923 /// ```rust
924 /// # use simple_grid::{Grid, GridIndex};
925 /// let two_by_three: Grid<u32> = Grid::new(2, 3, vec![1, 2, 3, 4, 5, 6]);
926 /// let indices: Vec<GridIndex> = two_by_three.indices().collect();
927 /// assert_eq!(indices, vec![GridIndex::new(0, 0), GridIndex::new(1, 0), GridIndex::new(0, 1), GridIndex::new(1, 1), GridIndex::new(0, 2), GridIndex::new(1, 2)]);
928 /// ```
929 pub fn indices(&self) -> impl DoubleEndedIterator<Item = GridIndex> {
930 let height = self.height;
931 let width = self.width;
932 (0..height).flat_map(move |row| (0..width).map(move |column| GridIndex::new(column, row)))
933 }
934
935 /// Return an iterator over the cells in the grid, together with their indices.
936 ///
937 /// ## Example
938 /// ```rust
939 /// # use simple_grid::{Grid, GridIndex};
940 /// let grid = Grid::new(2, 2, "abcd".chars().collect());
941 /// // a b
942 /// // c d
943 /// assert_eq!(grid.cells_with_indices_iter().collect::<Vec<_>>(), vec![(GridIndex::new(0, 0), &'a'), (GridIndex::new(1, 0), &'b'), (GridIndex::new(0, 1), &'c'), (GridIndex::new(1, 1), &'d')]);
944 /// ```
945 pub fn cells_with_indices_iter(&self) -> impl DoubleEndedIterator<Item = (GridIndex, &T)> {
946 self.indices().map(move |idx| (idx, &self[idx]))
947 }
948
949 /// Returns `true` if `idx` is within the bounds of this `Grid`, `false` otherwise.
950 ///
951 /// ## Example
952 /// ```rust
953 /// # use simple_grid::{Grid, GridIndex};
954 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
955 /// // a b
956 /// // c d
957 /// assert!(two_by_two.contains_index(GridIndex::new(1, 1)));
958 /// assert!(!two_by_two.contains_index(GridIndex::new(2, 1)));
959 /// ```
960 pub fn contains_index(&self, idx: GridIndex) -> bool {
961 idx.row() < self.height() && idx.column() < self.width()
962 }
963
964 /// Returns an iterator over the indices of the cardinal and ordinal neighbors of the cell at `idx`.
965 ///
966 /// Returns the neighbors in clockwise order: `[up, up_right, right, down_right, down, down_left, left, up_left]`.
967 ///
968 /// ## Example
969 /// ```rust
970 /// # use simple_grid::{Grid, GridIndex};
971 /// let three_by_three = Grid::new(3, 3, "abcdefghi".chars().collect());
972 /// // a b c
973 /// // d e f
974 /// // g h i
975 /// let neighbors: Vec<_> = three_by_three.neighbor_indices_of((1, 1)).collect();
976 /// assert_eq!(neighbors, vec![
977 /// (1, 0).into(), // up
978 /// (2, 0).into(), // up_right
979 /// (2, 1).into(), // right
980 /// (2, 2).into(), // down_right
981 /// (1, 2).into(), // down
982 /// (0, 2).into(), // down_left
983 /// (0, 1).into(), // left
984 /// (0, 0).into(), // up_left
985 /// ]);
986 /// ```
987 pub fn neighbor_indices_of<I>(&'_ self, idx: I) -> impl Iterator<Item = GridIndex> + '_
988 where
989 I: Into<GridIndex>,
990 {
991 let idx: GridIndex = idx.into();
992 idx.neighbors().filter(move |i| self.contains_index(*i))
993 }
994
995 /// Returns an iterator over the contents of the cardinal and ordinal neighbors of the cell at `idx`.
996 ///
997 /// Returns the neighbors in clockwise order: `[up, up_right, right, down_right, down, down_left, left, up_left]`.
998 ///
999 /// ## Example
1000 /// ```rust
1001 /// # use simple_grid::{Grid, GridIndex};
1002 /// let three_by_three = Grid::new(3, 3, "abcdefghi".chars().collect());
1003 /// // a b c
1004 /// // d e f
1005 /// // g h i
1006 /// let neighbors: Vec<_> = three_by_three.neighbor_cells_of((1, 1)).collect();
1007 /// assert_eq!(neighbors, vec![
1008 /// &'b', // up
1009 /// &'c', // up_right
1010 /// &'f', // right
1011 /// &'i', // down_right
1012 /// &'h', // down
1013 /// &'g', // down_left
1014 /// &'d', // left
1015 /// &'a', // up_left
1016 /// ]);
1017 /// ```
1018 pub fn neighbor_cells_of<I>(&self, idx: I) -> impl Iterator<Item = &T>
1019 where
1020 I: Into<GridIndex>,
1021 {
1022 self.neighbor_indices_of(idx).map(move |i| &self[i])
1023 }
1024
1025 /// Returns an iterator over the indices of the cardinal neighbors of the cell at `idx`.
1026 ///
1027 /// Returns the neighbors in clockwise order: `[up, right, down, left]`.
1028 ///
1029 /// ## Example
1030 /// ```rust
1031 /// # use simple_grid::{Grid, GridIndex};
1032 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1033 /// // a b
1034 /// // c d
1035 /// let neighbors: Vec<_> = two_by_two.cardinal_neighbor_indices_of((1, 1)).collect();
1036 /// assert_eq!(
1037 /// neighbors,
1038 /// vec![GridIndex::new(1, 0), GridIndex::new(0, 1)]
1039 /// );
1040 /// ```
1041 pub fn cardinal_neighbor_indices_of<I>(&'_ self, idx: I) -> impl Iterator<Item = GridIndex> + '_
1042 where
1043 I: Into<GridIndex>,
1044 {
1045 let idx: GridIndex = idx.into();
1046 idx.cardinal_neighbors()
1047 .filter(move |i| self.contains_index(*i))
1048 }
1049
1050 /// Returns an iterator over the contents of the cardinal neighbors of the cell at `idx`.
1051 ///
1052 /// Returns the neighbors in clockwise order: `[up, right, down, left]`.
1053 ///
1054 /// ## Example
1055 /// ```rust
1056 /// # use simple_grid::{Grid, GridIndex};
1057 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1058 /// // a b
1059 /// // c d
1060 /// let neighbors: Vec<_> = two_by_two.cardinal_neighbor_cells_of((1, 1)).collect();
1061 /// assert_eq!(neighbors, vec![&'b', &'c']);
1062 /// ```
1063 pub fn cardinal_neighbor_cells_of<I>(&self, idx: I) -> impl Iterator<Item = &T>
1064 where
1065 I: Into<GridIndex>,
1066 {
1067 let idx: GridIndex = idx.into();
1068 self.cardinal_neighbor_indices_of(idx)
1069 .map(move |i| &self[i])
1070 }
1071
1072 /// Returns the `GridIndex` above `idx`, if it exists.
1073 ///
1074 /// ## Example
1075 /// ```rust
1076 /// # use simple_grid::{Grid, GridIndex};
1077 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1078 /// // a b
1079 /// // c d
1080 /// assert_eq!(two_by_two.up_index((1, 1)), Some(GridIndex::new(1, 0)));
1081 /// assert_eq!(two_by_two.up_index((1, 0)), None);
1082 /// ```
1083 pub fn up_index<I>(&self, idx: I) -> Option<GridIndex>
1084 where
1085 I: Into<GridIndex>,
1086 {
1087 let idx: GridIndex = idx.into();
1088 if let Some(up) = idx.up() {
1089 if self.contains_index(up) {
1090 return Some(up);
1091 }
1092 }
1093 None
1094 }
1095
1096 /// Returns a reference to the contents of the cell above `idx`, if it exists in this `Grid`.
1097 ///
1098 /// ## Example
1099 /// ```rust
1100 /// # use simple_grid::{Grid, GridIndex};
1101 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1102 /// // a b
1103 /// // c d
1104 /// assert_eq!(two_by_two.up_cell((1, 1)), Some(&'b'));
1105 /// assert_eq!(two_by_two.up_cell((1, 0)), None);
1106 /// ```
1107 pub fn up_cell<I>(&self, idx: I) -> Option<&T>
1108 where
1109 I: Into<GridIndex>,
1110 {
1111 self.up_index(idx).map(|i| &self[i])
1112 }
1113
1114 /// Returns the `GridIndex` above and to the right of `idx`, if it exists in this `Grid`.
1115 ///
1116 /// ## Example
1117 /// ```rust
1118 /// # use simple_grid::{Grid, GridIndex};
1119 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1120 /// // a b
1121 /// // c d
1122 /// assert_eq!(two_by_two.up_right_index((0, 1)), Some(GridIndex::new(1, 0)));
1123 /// assert_eq!(two_by_two.up_right_index((1, 0)), None);
1124 /// ```
1125 pub fn up_right_index<I>(&self, idx: I) -> Option<GridIndex>
1126 where
1127 I: Into<GridIndex>,
1128 {
1129 self.up_index(idx).and_then(|up| self.right_index(up))
1130 }
1131
1132 /// Returns a reference to the contents of the cell above and to the right of `idx`, if it exists in this `Grid`.
1133 ///
1134 /// ## Example
1135 /// ```rust
1136 /// # use simple_grid::{Grid, GridIndex};
1137 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1138 /// // a b
1139 /// // c d
1140 /// assert_eq!(two_by_two.up_cell((1, 1)), Some(&'b'));
1141 /// assert_eq!(two_by_two.up_cell((1, 0)), None);
1142 /// ```
1143 pub fn up_right_cell<I>(&self, idx: I) -> Option<&T>
1144 where
1145 I: Into<GridIndex>,
1146 {
1147 self.up_right_index(idx).map(|i| &self[i])
1148 }
1149
1150 /// Returns the `GridIndex` to the right of `idx`, if it exists in this `Grid`.
1151 ///
1152 /// ## Example
1153 /// ```rust
1154 /// # use simple_grid::{Grid, GridIndex};
1155 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1156 /// // a b
1157 /// // c d
1158 /// assert_eq!(two_by_two.right_index((0, 0)), Some(GridIndex::new(1, 0)));
1159 /// assert_eq!(two_by_two.right_index((1, 0)), None);
1160 /// ```
1161 pub fn right_index<I>(&self, idx: I) -> Option<GridIndex>
1162 where
1163 I: Into<GridIndex>,
1164 {
1165 let idx: GridIndex = idx.into();
1166 let right = idx.right()?;
1167 if self.contains_index(right) {
1168 Some(right)
1169 } else {
1170 None
1171 }
1172 }
1173
1174 /// Returns a reference to the contents of the cell to the right of `idx`, if it exists in this `Grid`.
1175 ///
1176 /// ## Example
1177 /// ```rust
1178 /// # use simple_grid::{Grid, GridIndex};
1179 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1180 /// // a b
1181 /// // c d
1182 /// assert_eq!(two_by_two.right_cell((0, 1)), Some(&'d'));
1183 /// assert_eq!(two_by_two.right_cell((1, 0)), None);
1184 /// ```
1185 pub fn right_cell<I>(&self, idx: I) -> Option<&T>
1186 where
1187 I: Into<GridIndex>,
1188 {
1189 self.right_index(idx).map(|i| &self[i])
1190 }
1191
1192 /// Returns the `GridIndex` below and to the right of `idx`, if it exists in this `Grid`.
1193 ///
1194 /// ## Example
1195 /// ```rust
1196 /// # use simple_grid::{Grid, GridIndex};
1197 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1198 /// // a b
1199 /// // c d
1200 /// assert_eq!(two_by_two.down_right_index((0, 0)), Some(GridIndex::new(1,1)));
1201 /// assert_eq!(two_by_two.down_right_index((1, 0)), None);
1202 /// ```
1203 pub fn down_right_index<I>(&self, idx: I) -> Option<GridIndex>
1204 where
1205 I: Into<GridIndex>,
1206 {
1207 let idx: GridIndex = idx.into();
1208 let down_right = idx.down_right()?;
1209 if self.contains_index(down_right) {
1210 Some(down_right)
1211 } else {
1212 None
1213 }
1214 }
1215
1216 /// Returns a reference to the contents of the cell below and to the right of `idx`, if it exists in this `Grid`.
1217 ///
1218 /// ## Example
1219 /// ```rust
1220 /// # use simple_grid::{Grid, GridIndex};
1221 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1222 /// // a b
1223 /// // c d
1224 /// assert_eq!(two_by_two.down_right_cell((0, 0)), Some(&'d'));
1225 /// assert_eq!(two_by_two.down_right_cell((1, 0)), None);
1226 /// ```
1227 pub fn down_right_cell<I>(&self, idx: I) -> Option<&T>
1228 where
1229 I: Into<GridIndex>,
1230 {
1231 self.down_right_index(idx).map(|i| &self[i])
1232 }
1233
1234 /// Returns the `GridIndex` below `idx`, if it exists in this `Grid`.
1235 ///
1236 /// ## Example
1237 /// ```rust
1238 /// # use simple_grid::{Grid, GridIndex};
1239 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1240 /// // a b
1241 /// // c d
1242 /// assert_eq!(two_by_two.down_index((0, 0)), Some(GridIndex::new(0, 1)));
1243 /// assert_eq!(two_by_two.down_index((0, 1)), None);
1244 /// ```
1245 pub fn down_index<I>(&self, idx: I) -> Option<GridIndex>
1246 where
1247 I: Into<GridIndex>,
1248 {
1249 let idx: GridIndex = idx.into();
1250 let down = idx.down()?;
1251 if self.contains_index(down) {
1252 Some(down)
1253 } else {
1254 None
1255 }
1256 }
1257
1258 /// Returns a reference to the contents of the cell below `idx`, if it exists in this `Grid`.
1259 ///
1260 /// ## Example
1261 /// ```rust
1262 /// # use simple_grid::{Grid, GridIndex};
1263 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1264 /// // a b
1265 /// // c d
1266 /// assert_eq!(two_by_two.down_cell((0, 0)), Some(&'c'));
1267 /// assert_eq!(two_by_two.down_cell((0, 1)), None);
1268 /// ```
1269 pub fn down_cell<I>(&self, idx: I) -> Option<&T>
1270 where
1271 I: Into<GridIndex>,
1272 {
1273 self.down_index(idx).map(|i| &self[i])
1274 }
1275
1276 /// Returns the `GridIndex` below and to the left of `idx`, if it exists in this `Grid`.
1277 ///
1278 /// ## Example
1279 /// ```rust
1280 /// # use simple_grid::{Grid, GridIndex};
1281 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1282 /// // a b
1283 /// // c d
1284 /// assert_eq!(two_by_two.down_left_index((1, 0)), Some(GridIndex::new(0,1)));
1285 /// assert_eq!(two_by_two.down_left_index((0, 0)), None);
1286 /// ```
1287 pub fn down_left_index<I>(&self, idx: I) -> Option<GridIndex>
1288 where
1289 I: Into<GridIndex>,
1290 {
1291 let idx: GridIndex = idx.into();
1292 let down_left = idx.down_left()?;
1293 if self.contains_index(down_left) {
1294 Some(down_left)
1295 } else {
1296 None
1297 }
1298 }
1299
1300 /// Returns a reference to the contents of the cell below and to the left of `idx`, if it exists in this `Grid`.
1301 ///
1302 /// ## Example
1303 /// ```rust
1304 /// # use simple_grid::{Grid, GridIndex};
1305 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1306 /// // a b
1307 /// // c d
1308 /// assert_eq!(two_by_two.down_left_cell((1, 0)), Some(&'c'));
1309 /// assert_eq!(two_by_two.down_left_cell((0, 0)), None);
1310 /// ```
1311 pub fn down_left_cell<I>(&self, idx: I) -> Option<&T>
1312 where
1313 I: Into<GridIndex>,
1314 {
1315 self.down_left_index(idx).map(|i| &self[i])
1316 }
1317
1318 /// Returns the `GridIndex` to the left of `idx`, if it exists in this `Grid`.
1319 ///
1320 /// ## Example
1321 /// ```rust
1322 /// # use simple_grid::{Grid, GridIndex};
1323 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1324 /// // a b
1325 /// // c d
1326 /// assert_eq!(two_by_two.left_index((1, 0)), Some(GridIndex::new(0, 0)));
1327 /// assert_eq!(two_by_two.left_index((0, 0)), None);
1328 /// ```
1329 pub fn left_index<I>(&self, idx: I) -> Option<GridIndex>
1330 where
1331 I: Into<GridIndex>,
1332 {
1333 let idx: GridIndex = idx.into();
1334 let left = idx.left()?;
1335 if self.contains_index(left) {
1336 Some(left)
1337 } else {
1338 None
1339 }
1340 }
1341
1342 /// Returns a reference to the contents of the cell to the left of `idx`, if it exists in this `Grid`.
1343 ///
1344 /// ## Example
1345 /// ```rust
1346 /// # use simple_grid::{Grid, GridIndex};
1347 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1348 /// // a b
1349 /// // c d
1350 /// assert_eq!(two_by_two.left_cell((1, 0)), Some(&'a'));
1351 /// assert_eq!(two_by_two.left_cell((0, 0)), None);
1352 /// ```
1353 pub fn left_cell<I>(&self, idx: I) -> Option<&T>
1354 where
1355 I: Into<GridIndex>,
1356 {
1357 self.left_index(idx).map(|i| &self[i])
1358 }
1359
1360 /// Returns the `GridIndex` above and to the left of `idx`, if it exists in this `Grid`.
1361 ///
1362 /// ## Example
1363 /// ```rust
1364 /// # use simple_grid::{Grid, GridIndex};
1365 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1366 /// // a b
1367 /// // c d
1368 /// assert_eq!(two_by_two.up_left_index((1, 1)), Some(GridIndex::new(0, 0)));
1369 /// assert_eq!(two_by_two.up_left_index((0, 0)), None);
1370 /// ```
1371 pub fn up_left_index<I>(&self, idx: I) -> Option<GridIndex>
1372 where
1373 I: Into<GridIndex>,
1374 {
1375 let idx: GridIndex = idx.into();
1376 let up_left = idx.up_left()?;
1377 if self.contains_index(up_left) {
1378 Some(up_left)
1379 } else {
1380 None
1381 }
1382 }
1383
1384 /// Returns a reference to the contents of the cell above and to the left of `idx`, if it exists in this `Grid`.
1385 ///
1386 /// ## Example
1387 /// ```rust
1388 /// # use simple_grid::{Grid, GridIndex};
1389 /// let two_by_two = Grid::new(2, 2, "abcd".chars().collect());
1390 /// // a b
1391 /// // c d
1392 /// assert_eq!(two_by_two.up_left_cell((1, 1)), Some(&'a'));
1393 /// assert_eq!(two_by_two.up_left_cell((0, 0)), None);
1394 /// ```
1395 pub fn up_left_cell<I>(&self, idx: I) -> Option<&T>
1396 where
1397 I: Into<GridIndex>,
1398 {
1399 self.up_left_index(idx).map(|i| &self[i])
1400 }
1401 pub(crate) fn take_data(self) -> Vec<T> {
1402 self.data
1403 }
1404}
1405
1406impl<T> Grid<T>
1407where
1408 T: Default,
1409{
1410 /// Create a grid filled with default values.
1411 ///
1412 /// ## Example
1413 /// ```rust
1414 /// # use simple_grid::Grid;
1415 /// let grid: Grid<bool> = Grid::new_default(2, 2);
1416 /// assert_eq!(grid, Grid::new(2, 2, vec![false, false, false, false]));
1417 /// ```
1418 pub fn new_default(width: usize, height: usize) -> Grid<T> {
1419 let mut data = Vec::with_capacity(width * height);
1420 for _ in 0..data.capacity() {
1421 data.push(T::default());
1422 }
1423 Self::new(width, height, data)
1424 }
1425}
1426
1427impl<T> Grid<T>
1428where
1429 T: PartialEq,
1430{
1431 /// Returns `true` if the grid contains some element equal to `value`.
1432 ///
1433 /// ## Example
1434 /// ```
1435 /// # use simple_grid::Grid;
1436 /// let grid = Grid::new(2, 2, "abcd".chars().collect());
1437 /// assert!(grid.contains(&'a'));
1438 /// assert!(!grid.contains(&'e'));
1439 /// ```
1440 pub fn contains(&self, value: &T) -> bool {
1441 self.cell_iter().any(|element| element == value)
1442 }
1443}
1444
1445impl<T> Grid<T>
1446where
1447 T: Display,
1448{
1449 /// Format this `Grid` as a string. This can look weird when the `Display` output of `T` has varying length.
1450 ///
1451 /// ## Example
1452 /// ```rust
1453 /// # use simple_grid::Grid;
1454 /// let grid = Grid::new(10, 10, (1..=100).collect::<Vec<u32>>());
1455 /// assert_eq!(grid.get((5, 2)).unwrap(), &26);
1456 ///
1457 /// println!("{}", grid.to_pretty_string());
1458 /// // prints:
1459 /// // 1 2 3 4 5 6 7 8 9 10
1460 /// // 11 12 13 14 15 16 17 18 19 20
1461 /// // 21 22 23 24 25 26 27 28 29 30
1462 /// // 31 32 33 34 35 36 37 38 39 40
1463 /// // 41 42 43 44 45 46 47 48 49 50
1464 /// // 51 52 53 54 55 56 57 58 59 60
1465 /// // 61 62 63 64 65 66 67 68 69 70
1466 /// // 71 72 73 74 75 76 77 78 79 80
1467 /// // 81 82 83 84 85 86 87 88 89 90
1468 /// // 91 92 93 94 95 96 97 98 99 100
1469 /// ```
1470 pub fn to_pretty_string(&self) -> String {
1471 let output = if let Some(max_length) = self.cell_iter().map(|c| c.to_string().len()).max() {
1472 let padded_string = |orig: &str| {
1473 let mut padding: String = " ".repeat(max_length - orig.len());
1474 padding.push_str(orig);
1475 padding
1476 };
1477 self.rows()
1478 .map(|r| {
1479 self.columns()
1480 .map(|c| padded_string(&self[(c, r)].to_string()))
1481 .collect::<Vec<String>>()
1482 .join(" ")
1483 })
1484 .collect::<Vec<String>>()
1485 .join("\n")
1486 } else {
1487 "".to_string()
1488 };
1489 output
1490 }
1491}
1492
1493impl<T> IntoIterator for Grid<T> {
1494 type Item = T;
1495 type IntoIter = std::vec::IntoIter<Self::Item>;
1496
1497 fn into_iter(self) -> Self::IntoIter {
1498 self.data.into_iter()
1499 }
1500}
1501
1502impl<'a, T> IntoIterator for &'a Grid<T> {
1503 type Item = &'a T;
1504
1505 type IntoIter = std::slice::Iter<'a, T>;
1506
1507 fn into_iter(self) -> Self::IntoIter {
1508 self.data.iter()
1509 }
1510}
1511
1512impl<T, I> Index<I> for Grid<T>
1513where
1514 GridIndex: From<I>,
1515{
1516 type Output = T;
1517
1518 fn index(&self, index: I) -> &Self::Output {
1519 let index: GridIndex = GridIndex::from(index);
1520
1521 let linear = self.linear_idx_unchecked(index);
1522
1523 &self.data[linear]
1524 }
1525}
1526
1527impl<T, I> IndexMut<I> for Grid<T>
1528where
1529 GridIndex: From<I>,
1530{
1531 fn index_mut(&mut self, index: I) -> &mut Self::Output {
1532 let index: GridIndex = GridIndex::from(index);
1533
1534 let linear = self.linear_idx_unchecked(index);
1535
1536 &mut self.data[linear]
1537 }
1538}
1539
1540#[cfg(test)]
1541#[allow(unused)]
1542mod tests {
1543 use super::*;
1544 use std::fmt::{Debug, Display};
1545
1546 /// 1 2 3 4 5 6 7 8 9 10
1547 ///
1548 /// 11 12 13 14 15 16 17 18 19 20
1549 ///
1550 /// 21 22 23 24 25 26 27 28 29 30
1551 ///
1552 /// 31 32 33 34 35 36 37 38 39 40
1553 ///
1554 /// 41 42 43 44 45 46 47 48 49 50
1555 ///
1556 /// 51 52 53 54 55 56 57 58 59 60
1557 ///
1558 /// 61 62 63 64 65 66 67 68 69 70
1559 ///
1560 /// 71 72 73 74 75 76 77 78 79 80
1561 ///
1562 /// 81 82 83 84 85 86 87 88 89 90
1563 ///
1564 /// 91 92 93 94 95 96 97 98 99 100
1565 fn example_grid_u32() -> Grid<u32> {
1566 let grid = Grid::new(10, 10, (1..=100).collect());
1567
1568 println!("Grid<u32>: ");
1569 println!("{}", grid.to_pretty_string());
1570
1571 grid
1572 }
1573
1574 /// a b
1575 ///
1576 /// c d
1577 ///
1578 /// e f
1579 fn small_example_grid() -> Grid<char> {
1580 let grid = Grid::new(2, 3, "abcdef".chars().collect());
1581
1582 println!("Grid<char>: ");
1583 println!("{}", grid.to_pretty_string());
1584
1585 grid
1586 }
1587
1588 #[test]
1589 fn index_test() {
1590 let grid = example_grid_u32();
1591
1592 assert_eq!(grid.get((5, 2)).unwrap(), &26);
1593
1594 let mut counter = 0;
1595 for row in 0..grid.height {
1596 for col in 0..grid.width {
1597 counter += 1;
1598 assert_eq!(grid[(col, row)], counter);
1599 }
1600 }
1601
1602 // this should fail
1603 let result = std::panic::catch_unwind(|| grid[(11, 11)]);
1604 assert!(result.is_err());
1605 }
1606
1607 #[test]
1608 fn set_value_test() {
1609 let mut grid = small_example_grid();
1610
1611 *grid.get_mut((0, 1)).unwrap() = 'x';
1612
1613 assert_grid_equal(&grid, &Grid::new(2, 3, "abxdef".chars().collect()));
1614
1615 grid[(0, 2)] = 'y';
1616
1617 assert_grid_equal(&grid, &Grid::new(2, 3, "abxdyf".chars().collect()));
1618 }
1619
1620 #[test]
1621 fn iter_test() {
1622 let grid = small_example_grid();
1623
1624 for x in &grid {}
1625 }
1626
1627 #[test]
1628 fn row_iter_test() {
1629 let grid = example_grid_u32();
1630
1631 let actual_items_in_row: Vec<u32> = grid.row_iter(2).copied().collect();
1632
1633 assert_eq!(
1634 actual_items_in_row,
1635 vec![21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
1636 );
1637
1638 let actual_items_in_row_rev: Vec<u32> = grid.row_iter(2).rev().copied().collect();
1639
1640 assert_eq!(
1641 actual_items_in_row_rev,
1642 vec![30, 29, 28, 27, 26, 25, 24, 23, 22, 21]
1643 );
1644 }
1645
1646 #[test]
1647 fn col_iter_test() {
1648 let grid = example_grid_u32();
1649
1650 let actual_items_in_col: Vec<u32> = grid.column_iter(2).copied().collect();
1651
1652 assert_eq!(
1653 actual_items_in_col,
1654 vec![3, 13, 23, 33, 43, 53, 63, 73, 83, 93]
1655 );
1656 }
1657
1658 #[test]
1659 fn new_default_test() {
1660 let grid: Grid<u32> = Grid::new_default(10, 1);
1661
1662 assert_eq!(grid.data, vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0,]);
1663 }
1664
1665 #[test]
1666 fn insert_row_in_middle_test() {
1667 let mut grid = example_grid_u32();
1668
1669 let items_in_row_1: Vec<u32> = grid.row_iter(1).copied().collect();
1670
1671 assert_eq!(items_in_row_1, vec![11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);
1672 assert_eq!(grid.height, 10);
1673
1674 grid.insert_row(1, vec![10, 9, 8, 7, 6, 5, 4, 3, 2, 1]);
1675 assert_eq!(grid.height, 11);
1676 }
1677
1678 #[test]
1679 fn insert_row_at_end_test() {
1680 let mut grid = small_example_grid();
1681 let new_row: Vec<char> = "xx".chars().collect();
1682
1683 grid.insert_row(3, new_row.clone());
1684
1685 let items_in_bottom_row: Vec<char> = grid.row_iter(3).copied().collect();
1686
1687 assert_eq!(items_in_bottom_row, new_row);
1688
1689 assert_grid_equal(
1690 &grid,
1691 &Grid::new(2, 4, "abcdefxx".chars().collect::<Vec<_>>()),
1692 );
1693 }
1694
1695 #[test]
1696 fn remove_row_test() {
1697 let mut grid = small_example_grid();
1698 let items_in_row_1: Vec<char> = grid.row_iter(1).cloned().collect();
1699
1700 assert_eq!(items_in_row_1, vec!['c', 'd']);
1701 assert_eq!(grid.height, 3);
1702
1703 let removed_row = grid.remove_row(1);
1704 assert_eq!(removed_row, items_in_row_1);
1705 assert_eq!(grid.height, 2);
1706 }
1707
1708 #[test]
1709 fn remove_row_until_empty_test() {
1710 let mut grid = small_example_grid();
1711
1712 grid.remove_row(0);
1713 grid.remove_row(0);
1714 grid.remove_row(0);
1715
1716 assert_grid_equal(&grid, &Grid::new(0, 0, Vec::new()));
1717 assert_eq!(grid.height, 0);
1718 assert_eq!(grid.width, 0);
1719 assert!(grid.is_empty());
1720
1721 // since the grid is now empty, we can add a row of any non-zero length
1722 grid.insert_row(0, vec!['a', 'b', 'c']);
1723
1724 assert_grid_equal(&grid, &Grid::new(3, 1, vec!['a', 'b', 'c']));
1725 }
1726
1727 #[test]
1728 fn insert_column_in_middle_test() {
1729 let mut grid = small_example_grid();
1730
1731 let items_in_column_1: Vec<char> = grid.column_iter(1).copied().collect();
1732
1733 assert_eq!(items_in_column_1, "bdf".chars().collect::<Vec<_>>());
1734 assert_eq!(grid.width, 2);
1735
1736 grid.insert_column(1, "xxx".chars().collect());
1737
1738 let items_in_column_1: Vec<char> = grid.column_iter(1).copied().collect();
1739
1740 assert_eq!(items_in_column_1, "xxx".chars().collect::<Vec<_>>());
1741 assert_eq!(grid.width, 3);
1742 }
1743
1744 #[test]
1745 fn insert_column_at_end_test() {
1746 let mut grid = small_example_grid();
1747 let new_column: Vec<char> = "xxx".chars().collect();
1748 grid.insert_column(2, new_column.clone());
1749
1750 let items_in_column_2: Vec<char> = grid.column_iter(2).copied().collect();
1751
1752 assert_eq!(items_in_column_2, new_column);
1753
1754 assert_grid_equal(
1755 &grid,
1756 &Grid::new(3, 3, "abxcdxefx".chars().collect::<Vec<_>>()),
1757 );
1758 }
1759
1760 #[test]
1761 fn remove_column_test() {
1762 let mut grid = small_example_grid();
1763 let items_in_column_1: Vec<_> = grid.column_iter(1).cloned().collect();
1764
1765 assert_eq!(items_in_column_1, vec!['b', 'd', 'f']);
1766 assert_eq!(grid.width, 2);
1767
1768 let removed = grid.remove_column(1);
1769 assert_eq!(removed, items_in_column_1);
1770 assert_eq!(grid.width, 1);
1771 }
1772
1773 #[test]
1774 fn remove_column_until_empty_test() {
1775 let mut grid = small_example_grid();
1776
1777 grid.remove_column(0);
1778 grid.remove_column(0);
1779
1780 assert_grid_equal(&grid, &Grid::new(0, 0, Vec::new()));
1781 assert_eq!(grid.height, 0);
1782 assert_eq!(grid.width, 0);
1783 assert!(grid.is_empty());
1784
1785 // since the grid is now empty, we can add a column of any non-zero length
1786 grid.insert_column(0, vec!['a', 'b', 'c']);
1787
1788 assert_grid_equal(&grid, &Grid::new(1, 3, vec!['a', 'b', 'c']));
1789 }
1790
1791 #[test]
1792 fn rotate_cw_test() {
1793 let mut grid = small_example_grid();
1794
1795 grid.rotate_cw();
1796
1797 assert_grid_equal(&grid, &Grid::new(3, 2, vec!['e', 'c', 'a', 'f', 'd', 'b']));
1798 }
1799
1800 #[test]
1801 fn rotate_ccw_test() {
1802 let mut grid = small_example_grid();
1803
1804 grid.rotate_ccw();
1805
1806 assert_grid_equal(&grid, &Grid::new(3, 2, vec!['b', 'd', 'f', 'a', 'c', 'e']));
1807 }
1808
1809 #[test]
1810 fn flip_horizontally_test() {
1811 let mut grid = small_example_grid();
1812
1813 grid.flip_horizontally();
1814
1815 assert_grid_equal(&grid, &Grid::new(2, 3, vec!['b', 'a', 'd', 'c', 'f', 'e']));
1816 }
1817
1818 #[test]
1819 fn flip_vertically_test() {
1820 let mut grid = small_example_grid();
1821
1822 grid.flip_vertically();
1823
1824 assert_grid_equal(&grid, &Grid::new(2, 3, vec!['e', 'f', 'c', 'd', 'a', 'b']));
1825 }
1826
1827 #[test]
1828 fn transpose_test() {
1829 let original_grid = small_example_grid();
1830 let mut grid = original_grid.clone();
1831 grid.transpose();
1832
1833 assert_grid_equal(&grid, &Grid::new(3, 2, "acebdf".chars().collect()));
1834
1835 grid.transpose();
1836
1837 assert_grid_equal(&grid, &original_grid);
1838 }
1839
1840 #[test]
1841 fn contains_test() {
1842 let grid = small_example_grid();
1843
1844 assert!(grid.contains(&'a'));
1845 assert!(!grid.contains(&'g'));
1846 }
1847
1848 #[test]
1849 fn is_empty_test() {
1850 let mut grid = small_example_grid();
1851
1852 assert!(!grid.is_empty());
1853
1854 grid.remove_row(0);
1855 assert!(!grid.is_empty());
1856
1857 grid.remove_row(0);
1858 assert!(!grid.is_empty());
1859
1860 grid.remove_row(0);
1861 assert!(grid.is_empty());
1862
1863 grid.insert_row(0, vec!['g', 'h', 'i', 'j', 'k']);
1864
1865 assert!(!grid.is_empty());
1866 assert_eq!(grid.width, 5);
1867 }
1868
1869 #[test]
1870 fn replace_row_test() {
1871 let mut grid = small_example_grid();
1872
1873 let items_in_row_1: Vec<char> = grid.row_iter(1).copied().collect();
1874 let old_row = grid.replace_row(1, vec!['x', 'x']);
1875
1876 assert_eq!(old_row, items_in_row_1);
1877 assert_grid_equal(&grid, &Grid::new(2, 3, "abxxef".chars().collect()));
1878 }
1879
1880 #[test]
1881 fn replace_column_test() {
1882 let mut grid = small_example_grid();
1883
1884 let items_in_column_0: Vec<char> = grid.column_iter(0).copied().collect();
1885 let old_column = grid.replace_column(0, vec!['x', 'x', 'x']);
1886
1887 assert_eq!(old_column, items_in_column_0);
1888 assert_grid_equal(&grid, &Grid::new(2, 3, "xbxdxf".chars().collect()));
1889 }
1890
1891 #[test]
1892 fn swap_columns_test() {
1893 let mut grid = small_example_grid();
1894
1895 grid.swap_columns(0, 1);
1896
1897 assert_grid_equal(&grid, &Grid::new(2, 3, "badcfe".chars().collect()));
1898 }
1899
1900 #[test]
1901 fn swap_rows_test() {
1902 let mut grid = small_example_grid();
1903
1904 grid.swap_rows(1, 2);
1905
1906 assert_grid_equal(&grid, &Grid::new(2, 3, "abefcd".chars().collect()));
1907 }
1908
1909 #[test]
1910 fn swap_cells_test() {
1911 let mut grid = small_example_grid();
1912 grid.swap_cells((1, 1), (0, 2));
1913
1914 assert_grid_equal(&grid, &Grid::new(2, 3, "abcedf".chars().collect()));
1915 }
1916
1917 #[test]
1918 fn subgrid_test() {
1919 let grid = example_grid_u32();
1920 let subgrid = grid.subgrid(2, 1, 3, 5);
1921 assert_grid_equal(
1922 &subgrid,
1923 &Grid::new(
1924 3,
1925 5,
1926 vec![13, 14, 15, 23, 24, 25, 33, 34, 35, 43, 44, 45, 53, 54, 55],
1927 ),
1928 );
1929 }
1930
1931 #[test]
1932 fn replace_cell_test() {
1933 let mut grid = small_example_grid();
1934 let old_value = grid.replace_cell((0, 1), 'x');
1935 assert_eq!(old_value, 'c');
1936 assert_grid_equal(&grid, &Grid::new(2, 3, "abxdef".chars().collect()));
1937 }
1938
1939 #[test]
1940 fn indices_test() {
1941 let grid: Grid<u32> = Grid::new_default(3, 2);
1942 let indices: Vec<GridIndex> = grid.indices().collect();
1943 assert_eq!(
1944 indices,
1945 vec![
1946 GridIndex::new(0, 0),
1947 GridIndex::new(1, 0),
1948 GridIndex::new(2, 0),
1949 GridIndex::new(0, 1),
1950 GridIndex::new(1, 1),
1951 GridIndex::new(2, 1)
1952 ]
1953 );
1954 }
1955
1956 #[test]
1957 #[cfg(feature = "serde")]
1958 fn serialize_test() {
1959 let mut grid = small_example_grid();
1960
1961 let json = serde_json::to_string(&grid).unwrap();
1962
1963 println!("{}", json);
1964 }
1965
1966 fn assert_grid_equal<T>(actual: &Grid<T>, expected: &Grid<T>)
1967 where
1968 T: Display + PartialEq + Debug,
1969 {
1970 println!("actual:");
1971 println!("{}", actual.to_pretty_string());
1972 println!("expected:");
1973 println!("{}", expected.to_pretty_string());
1974 assert_eq!(actual, expected);
1975 }
1976}