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(&current).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}