grid_math/
lib.rs

1//! Basic representation of Grid, Cell, and assosiated mathematical operations. Helpful in CLI-based gamedev.
2//!
3//! This module contains the [`Cell`] type, representing the basic unit of [`Grid`],
4//! the [`Grid`] type, representing a two-dimentional field of [`Cell`]s,
5//! the [`Cells`] type, representing an iterator over every [`Cell`] on the [`Grid`],
6//! the [`Rows`] and the [`Columns`] types, representing iterators over subgrids of [`Grid`],
7//! and the [`GridMap<T>`] type, representing a wrapper around the [`HashMap<Cell, T>`]
8//!
9//! # Usecases
10//!
11//! One of the best usecases of this crate is for developing `CLI` based games:
12//! `Cell` has two fields representing position on the `Grid`, which are both `u8`,
13//! and the `Grid` consists of the `start` and the `end` `Cell`s,
14//! making the largest possible `Grid` to be 255x255, which is enough for most terminal games.
15//!
16//! # Note
17//!
18//! - `Cell`'s global position currently represented in the `u8` for simplicity,
19//!   and because this is enough for most terminal games. This may be changed to be a scalar generic in the future.
20//! - Error handling is currently rather stupid (just checks with panic!), but this may change in the future.
21//! - Crate is in the "work in progress" state, so the public API may change in the future. Feel free to contribute!
22//!
23//! # Examples
24//!
25//! Perform some basic calculations for `Cell`:
26//! ```
27//! use grid_math::{Cell, Grid};
28//!
29//! let grid = Grid::new(10, 10);
30//! let start = grid.start();
31//! let next = start.saturating_right(grid, 5).wrapping_down(grid, 15).strict_left(grid, 1);
32//!
33//! assert!(next.within(grid));
34//! assert_eq!(next, Cell::new(4, 5));
35//! ```
36//!
37//! Map every `Cell` on the `Grid` to the custom `String` representation:
38//! ```
39//! use grid_math::{Cell, Grid};
40//!
41//! let grid = Grid::new(3, 3);
42//! let grid_string = grid
43//!     .rows()
44//!     .map(|row| {
45//!         row.cells().map(|_| " [#]")
46//!             .chain(std::iter::once("\n\n"))
47//!             .collect::<String>()
48//!     })
49//!     .collect::<String>();
50//! assert_eq!(grid_string,
51//! " \
52//!  [#] [#] [#]
53//!
54//!  [#] [#] [#]
55//!
56//!  [#] [#] [#]
57//!
58//! "
59//! );
60//! ```
61//!
62//! Store some actual data on the `Grid`, using `GridMap`:
63//! ```
64//! use grid_math::{Cell, Grid, GridMap};
65//!
66//! let grid = Grid::new(5, 5);
67//! let mut map: GridMap<char> = GridMap::from(grid);
68//! map.insert(map.grid().start(), '#');
69//! map.insert(map.grid().end(), '@');
70//!
71//! assert_eq!(map.len(), 2);
72//! assert_eq!(map.get(&Cell::new(0, 0)).unwrap(), &'#');
73//! ```
74
75use std::collections::HashMap;
76use std::convert::{From, Into};
77use std::fmt;
78use std::ops::{Deref, DerefMut};
79
80/// `Cell` represents the basic unit of `Grid`.
81///
82/// Consists of global positions `global_width: u8` and `global_depth: u8`, alongside with methods implementing
83/// common mathematical operations for safe interactions with grids and other cells
84///
85/// Due to low memory size, `Cell` implements `Copy` trait, so all methods take `self` (copy) as first argument
86///
87/// # Examples
88///
89/// You can create Cell using new(global_width, global_depth):
90/// ```
91/// use grid_math::Cell;
92///
93/// let cell = Cell::new(10, 15);
94/// ```
95///
96/// Or use functionality of implemented `From` and `Into` traits:
97/// ```
98/// use grid_math::Cell;
99///
100/// let cell = Cell::from((9, 9));
101/// let cell: Cell = (6, 7).into();
102/// ```
103///
104/// To read global_width or global_depth values, use getters:
105/// ```
106/// use grid_math::Cell;
107///
108/// let cell = Cell::new(10, 10);
109/// let w = cell.global_width();
110/// let d = cell.global_depth();
111/// ```
112/// Or use `into()` provided by `Into` trait:
113/// ```
114/// use grid_math::Cell;
115///
116/// let cell = Cell::new(10, 10);
117/// let (w, d): (u8, u8) = cell.into();
118/// ```
119///
120/// 'Cell' implements `Display` and `Debug` trait, so you can easily print it out:
121/// ```
122/// use grid_math::Cell;
123///
124/// let cell = Cell::new(10, 10);
125/// println!("Cell: {cell}"); // Cell: (10, 10)
126/// assert_eq!(format!("{cell}"), "(10, 10)");
127/// ```
128///
129/// Other methods involve interactions with `Grid`
130///
131/// `Cell` is designed to not mutate it's contents.
132/// Instead, all operations return new instances of `Cell`
133///
134/// Also worth noting, that all operations on `Cell` are verified to be logically correct,
135/// otherwise logically incorrect operations will be met with panic!
136///
137/// Here is a brief overview of `Cell` and `Grid` interactions:
138///
139/// Check if `Cell` is within the `Grid`:
140/// ```
141/// use grid_math::{Cell, Grid};
142///
143/// let cell = Cell::new(3, 4);
144/// let grid = Grid::new(10, 10); // 10x10 grid starting at (0,0)
145/// assert!(cell.within(grid));
146/// ```
147///
148/// Get relative to the `Grid` position of `Cell`:
149/// (`Grid` can start not only from (0,0))
150/// ```
151/// use grid_math::{Cell, Grid};
152///
153/// let cell = Cell::new(3, 4);
154/// let grid = Grid::indented(8, 8, (2, 1)); // 8x8 grid starting at (2,1)
155/// let (width, depth) = (cell.width(grid), cell.depth(grid));
156/// // cell's width on grid = cell.global_width - grid.start.global_width
157/// // cell's depth on grid = cell.global_depth - grid.start.global_depth
158/// assert_eq!((width, depth), (1, 3));
159/// // get gaps between width and depth grid borders and cell:
160/// let (width_gap, depth_gap) = (cell.width_gap(grid), cell.depth_gap(grid));
161/// assert_eq!((width_gap, depth_gap), (6, 4));
162/// // get member of grid by relative position:
163/// let member = grid.member(width, depth);
164/// assert_eq!(cell, member);
165/// ```
166///
167/// Perform some move calculations of `Cell` on `Grid`:
168/// ```
169/// use grid_math::{Cell, Grid};
170///
171/// let grid = Grid::new(10, 10);
172/// let cell = grid.start(); // get grid's first cell
173/// let next = cell.strict_right(grid, 3); // move to the right by 3, panics if grid bounds overflow occures
174/// assert_eq!(next, Cell::new(3, 0));
175/// let next = cell.saturating_down(grid, 15); // move down by 15, returns grid bound if overflow occures
176/// assert_eq!(next, Cell::new(0, 9));
177/// let next = cell.wrapping_right(grid, 5).strict_left(grid, 2).project_down(grid); // chain of movements
178/// assert_eq!(next, Cell::new(3, 9));
179/// ```
180///
181/// To get more examples, look at `Cell` and `Grid` methods documentation.
182///
183///
184#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
185pub struct Cell {
186    global_width: u8,
187    global_depth: u8,
188}
189
190/// `Grid` represents the field of `Cell`
191///
192/// Consists of `start: Cell` and `end: Cell` fields, alongside with methods implementing
193/// common mathematical operations for safe interactions with cells and other grids
194///
195/// `Grid` has two axis: width, and depth:
196///
197/// (0,0) [#] [#] [#] [#] (5,0)
198///
199///  [#]  [#] [#] [#] [#]  [#]
200///
201///  [#]  [#] [#] [#] [#]  [#]
202///
203///  [#]  [#] [#] [#] [#]  [#]
204///
205///  [#]  [#] [#] [#] [#]  [#]
206///
207/// (0,5) [#] [#] [#] [#] (5,5)
208///
209/// Due to low memory size, `Grid` implements `Copy` trait, so all methods take `self` (copy) as first argument
210///
211/// # Examples
212///
213/// You can create Grid using new(width, depth) or indented(width, depth, indent):
214/// ```
215/// use grid_math::Grid;
216///
217/// let grid = Grid::new(5, 5); // new 5x5 grid, starting at (0,0)
218/// let grid = Grid::indented(5, 5, (1, 2)); // new 5x5 grid, starting at (1,2)
219/// ```
220///
221/// Or use functionality of implemented `From` and `Into` traits:
222/// ```
223/// use grid_math::{Grid, Cell};
224///
225/// let grid = Grid::from(((1, 2), (5, 6))); // new field where `start` is (1,2), `end` is (5,6)
226/// let grid: Grid = ((1, 2), (5, 6)).into();
227/// //same for (cell, cell):
228/// let grid = Grid::from((Cell::new(1, 2), Cell::new(5, 6)));
229/// let grid: Grid = (Cell::new(1, 2), Cell::new(5, 6)).into();
230/// // backwards:
231/// let (start, end) = grid.into();
232/// assert_eq!((start, end), (Cell::new(1, 2), Cell::new(5, 6)));
233/// let ((w1, d1), (w2, d2)) = grid.into();
234/// assert_eq!(((w1, d1), (w2, d2)), ((1, 2), (5, 6)));
235/// ```
236///
237/// Important:
238/// When creating `Grid` from cells, you specify `start` and `end` cell, not width and depth
239/// This means that if you create grid with `start` (1, 2) and `end` (5, 6),
240/// this will be 5x5 grid, not 4x4 as you can think (5 - 1 = 4, 6 - 2 = 4)
241/// this is because `start` and `end` bounds included, they are actual members of grid,
242/// where the `start` is the first cell on the grid, and `end` is the last cell on grid
243///
244/// To read `start` and `end` fields, or to calculate other common attributes, use getters:
245/// ```
246/// use grid_math::{Grid, Cell};
247///
248/// let grid = Grid::indented(8, 8, (3, 3)); // 8x8 grid, starting at (3,3)
249/// let (start, end) = (grid.start(), grid.end());
250/// assert_eq!((start, end), (Cell::new(3, 3), Cell::new(10, 10)));
251/// let (width, depth) = (grid.width(), grid.depth());
252/// assert_eq!((width, depth), (8, 8));
253/// let size = grid.size();
254/// assert_eq!(size, 64);
255/// ```
256///
257/// 'Grid' implements `Display` and `Debug` trait, so you can easily print it out:
258/// ```
259/// use grid_math::Grid;
260///
261/// let grid = Grid::new(10, 10);
262/// println!("Grid: {grid}"); // Grid: [(0, 0):(9, 9)]
263/// assert_eq!(format!("{grid}"), "[(0, 0):(9, 9)]");
264/// ```
265///
266/// Other advanced operations include interactions with other grids and cells:
267///
268/// Check if cell or subgrid is within grid:
269/// ```
270/// use grid_math::{Grid, Cell};
271///
272/// let grid = Grid::new(10, 10);
273/// let cell = Cell::new(3, 4);
274/// let subgrid = Grid::indented(5, 5, (2, 2));
275/// assert!(subgrid.within(grid));
276/// assert!(cell.within(grid));
277/// ```
278///
279/// Get `Cell` from `Grid` by relative position:
280/// ```
281/// use grid_math::{Grid, Cell};
282///
283/// let grid = Grid::indented(5, 5, (2, 2));
284/// let member = grid.member(2, 2);
285///
286/// assert_eq!(member, Cell::new(4, 4));
287/// ```
288///
289/// Important:
290/// When creating `Grid`, we specify `width` and `depth` in terms of length
291/// But when we address member of `Grid`, we specify `width` and `depth` in terms of indexes
292/// This means that `Grid` with `width` 5, and start at (0,*), will has `end` at (4,*),
293/// because we have (0,*) (1,*) (2,*) (3,*) (4,*), which is 5 elements in total
294/// So we used `width` 5 at `Grid` creation and got `Grid` with last cell (4,*)
295/// But if we use `width` 5 when indexing member of `Grid`, we will get an error, because indexing starts at 0
296///
297/// Get subgrid from `Grid` by relative position:
298/// ```
299/// use grid_math::{Grid, Cell};
300///
301/// let grid = Grid::indented(5, 5, (2, 2));
302/// assert_eq!(format!("{grid}"), "[(2, 2):(6, 6)]");
303/// // get subgrid starting at current grid start, with specified width and depth:
304/// let area = grid.area(3, 3);
305/// assert_eq!(format!("{area}"), "[(2, 2):(4, 4)]");
306/// // get subgrid starting at indent from current grid start and specified width and depth:
307/// let slice = grid.slice(3, 3, (1, 1));
308/// assert_eq!(format!("{slice}"), "[(3, 3):(5, 5)]");
309/// ```
310///
311/// Perform some move calculations of `Cell` on `Grid`:
312/// ```
313/// use grid_math::{Cell, Grid};
314///
315/// let grid = Grid::new(10, 10);
316/// let cell = grid.start(); // get grid's first cell
317/// let next = cell.strict_right(grid, 3); // move to the right by 3, panics if grid bounds overflow occures
318/// assert_eq!(next, Cell::new(3, 0));
319/// let next = cell.saturating_down(grid, 15); // move down by 15, returns grid bound if overflow occures
320/// assert_eq!(next, Cell::new(0, 9));
321/// let next = cell.wrapping_right(grid, 5).strict_left(grid, 2).project_down(grid); // chain of movements
322/// assert_eq!(next, Cell::new(3, 9));
323/// ```
324///
325/// Perform some actually usefull operations, using `Iterator` functionality:
326/// ```
327/// use grid_math::{Cell, Grid};
328///
329/// let grid = Grid::new(3, 3);
330/// let grid_string = grid
331///     .rows()
332///     .map(|row| {
333///         row.cells().map(|_| " [#]")
334///             .chain(std::iter::once("\n\n"))
335///             .collect::<String>()
336///     })
337///     .collect::<String>();
338/// assert_eq!(grid_string,
339/// " \
340///  [#] [#] [#]
341///
342///  [#] [#] [#]
343///
344///  [#] [#] [#]
345///
346/// "
347/// );
348/// ```
349///
350/// To get more examples, look at `Cell` and `Grid` methods documentation.
351///
352///
353#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
354pub struct Grid {
355    start: Cell,
356    end: Cell,
357}
358
359/// `Cells` represents an iterator over every `Cell` on the `Grid`
360///
361/// # Examples
362///
363/// Get every `Cell` on `width` and `depth` axis:
364/// ```
365/// use grid_math::{Cell, Grid};
366///
367/// let grid = Grid::new(3, 3);
368///
369/// let axis_cells: Vec<Cell> = grid
370///     .cells()
371///     .filter(|cell| {
372///         cell.global_width() == grid.start().global_width() || cell.global_depth() == grid.start().global_depth()
373///     })
374///     .collect();
375/// assert_eq!(axis_cells, vec![
376///     Cell::new(0, 0),
377///     Cell::new(1, 0),
378///     Cell::new(2, 0),
379///     Cell::new(0, 1),
380///     Cell::new(0, 2),
381/// ]);
382/// ```
383///
384#[derive(Debug, Clone, Copy, PartialEq, Eq)]
385pub struct Cells {
386    grid: Grid,
387    current: Cell,
388    consumed: bool,
389}
390
391/// `Rows` represents an iterator over every row of `Cell` on the `Grid`
392///
393/// Every element of 'Rows' returns `Grid`
394///
395/// # Examples
396///
397/// Print out `Grid` in custom format:
398/// ```
399/// use grid_math::{Cell, Grid};
400///
401/// let grid = Grid::new(3, 3);
402/// let grid_string = grid
403///     .rows()
404///     .map(|row| {
405///         row.cells().map(|_| " [#]")
406///             .chain(std::iter::once("\n\n"))
407///             .collect::<String>()
408///     })
409///     .collect::<String>();
410/// assert_eq!(grid_string,
411/// " \
412///  [#] [#] [#]
413///
414///  [#] [#] [#]
415///
416///  [#] [#] [#]
417///
418/// "
419/// );
420/// ```
421///
422#[derive(Debug, Clone, Copy, PartialEq, Eq)]
423pub struct Rows {
424    grid: Grid,
425    current: Grid,
426    consumed: bool,
427}
428
429/// `Columns` represents an iterator over every column of `Cell` on the `Grid`
430///
431/// Every element of 'Columns' returns `Grid`
432///
433/// # Examples
434///
435/// Get every `Cell` on the first column of `Grid`:
436/// ```
437/// use grid_math::{Cell, Grid};
438///
439/// let grid = Grid::new(3, 3);
440///
441/// let first_column_cells: Vec<Cell> = grid
442///     .columns()
443///     .next()
444///     .unwrap()
445///     .cells()
446///     .collect();
447///
448/// assert_eq!(first_column_cells, vec![
449///     Cell::new(0, 0),
450///     Cell::new(0, 1),
451///     Cell::new(0, 2),
452/// ]);
453/// ```
454#[derive(Debug, Clone, Copy, PartialEq, Eq)]
455pub struct Columns {
456    grid: Grid,
457    current: Grid,
458    consumed: bool,
459}
460
461/// `GridMap<V>` represents a wrapper around the `HashMap<Cell, T>`
462///
463/// `GridMap` is helpful for storing some actual data on the `Grid`.
464/// It implements `Deref` and `DerefMut` traits, so we can call methods from `HashMap`
465/// directly on the `GridMap`. Also It reimplements `insert` method and adds aditional conditions
466/// to check if the target `key: Cell` is within the inner `Grid` bounds.
467///
468/// `GridMap` currently has rather stupid error handling inside the `insert` method, but this may change in the future
469///
470/// # Examples
471///
472/// ```
473/// use grid_math::{Cell, Grid, GridMap};
474///
475/// let grid = Grid::new(5, 5);
476/// let mut map: GridMap<char> = GridMap::from(grid);
477/// map.insert(map.grid().start(), '#');
478/// map.insert(map.grid().end(), '@');
479/// assert_eq!(map.len(), 2);
480/// assert_eq!(map.get(&Cell::new(0, 0)).unwrap(), &'#');
481/// ```
482///
483/// ```should_panic
484/// use grid_math::{Cell, Grid, GridMap};
485///
486/// let grid = Grid::new(5, 5);
487/// let cell = Cell::new(6, 6);
488/// let mut map: GridMap<char> = GridMap::from(grid);
489/// map.insert(cell, '#'); // panic!
490/// ```
491pub struct GridMap<V> {
492    grid: Grid,
493    hashmap: HashMap<Cell, V>,
494}
495
496impl Cell {
497    /// Creates new `Cell` with specified `global_width: u8` and `global_depth: u8` global position
498    ///
499    /// # Examples
500    ///
501    /// ```
502    /// use grid_math::Cell;
503    ///
504    /// let cell = Cell::new(10, 15);
505    /// ```
506    pub fn new(global_width: u8, global_depth: u8) -> Self {
507        Self {
508            global_width,
509            global_depth,
510        }
511    }
512
513    /// Checks if the `Cell` is within the given `Grid`
514    ///
515    /// # Examples
516    ///
517    /// ```
518    /// use grid_math::{Cell, Grid};
519    ///
520    /// let grid = Grid::new(10, 10);
521    /// let cell = Cell::new(5, 5);
522    /// assert!(cell.within(grid));
523    ///
524    /// let cell = Cell::new(9, 15);
525    /// assert!(!cell.within(grid));
526    /// ```
527    pub fn within(self, grid: Grid) -> bool {
528        (grid.start.global_width..=grid.end.global_width).contains(&self.global_width)
529            && (grid.start.global_depth..=grid.end.global_depth).contains(&self.global_depth)
530    }
531
532    /// Checks if the `Cell` is within the given `Grid`
533    ///
534    /// # Panics
535    /// Panics if the `Cell` is not within the given `Grid`
536    ///
537    /// # Examples
538    ///
539    /// ```should_panic
540    /// use grid_math::{Cell, Grid};
541    ///
542    /// let grid = Grid::new(10, 10);
543    /// let cell = Cell::new(9, 15);
544    /// cell.within_panic(grid);
545    /// ```
546    pub fn within_panic(self, grid: Grid) {
547        if !self.within(grid) {
548            panic!("cell is not within given grid! cell:{self}, grid:{grid}")
549        }
550    }
551
552    /// Returns `global_width` field of `Cell`
553    ///
554    /// # Examples
555    ///
556    /// ```
557    /// use grid_math::Cell;
558    ///
559    /// let cell = Cell::new(8, 8);
560    /// let w = cell.global_width();
561    /// assert_eq!(w, 8);
562    /// ```
563    pub fn global_width(self) -> u8 {
564        self.global_width
565    }
566
567    /// Returns `global_depth` field of `Cell`
568    ///
569    /// # Examples
570    ///
571    /// ```
572    /// use grid_math::Cell;
573    ///
574    /// let cell = Cell::new(8, 8);
575    /// let d = cell.global_depth();
576    /// assert_eq!(d, 8);
577    /// ```
578    pub fn global_depth(self) -> u8 {
579        self.global_depth
580    }
581
582    /// Calculates the `width` of the `Cell` relative to the given `Grid`
583    /// `width` here means position / index / x of `Cell` on width axis
584    ///
585    /// # Panics
586    /// Panics if the `Cell` is not within the given `Grid`
587    ///
588    /// # Examples
589    ///
590    /// ```
591    /// use grid_math::{Cell, Grid};
592    ///
593    /// let cell = Cell::new(8, 8);
594    /// let grid = Grid::indented(7, 7, (4, 4)); // 7x7 grid starting at (4,4)
595    /// let width = cell.width(grid); // width = 4
596    /// assert_eq!(width, 4);
597    /// ```
598    pub fn width(self, grid: Grid) -> u8 {
599        self.within_panic(grid);
600        self.global_width - grid.start.global_width
601    }
602
603    /// Calculates the gap between the `width` of `Cell` and the `width` of `Grid`
604    ///
605    /// # Panics
606    /// Panics if the `Cell` is not within the given `Grid`
607    ///
608    /// # Examples
609    ///
610    /// ```
611    /// use grid_math::{Cell, Grid};
612    ///
613    /// let cell = Cell::new(8, 8);
614    /// let grid = Grid::indented(7, 7, (4, 4)); // 7x7 grid starting at (4,4)
615    /// let width_gap = cell.width_gap(grid); // width_gap = 2
616    /// assert_eq!(width_gap, 2);
617    /// ```
618    pub fn width_gap(self, grid: Grid) -> u8 {
619        self.within_panic(grid);
620        grid.end.global_width - self.global_width
621    }
622
623    /// Calculates the `depth` of `Cell` relative to the given `Grid`
624    /// `depth` here means position / index / y of `Cell` on depth axis
625    ///
626    /// # Panics
627    /// Panics if the `Cell` is not within the given `Grid`
628    ///
629    /// # Examples
630    ///
631    /// ```
632    /// use grid_math::{Cell, Grid};
633    ///
634    /// let cell = Cell::new(8, 8);
635    /// let grid = Grid::indented(7, 7, (4, 4)); // 7x7 grid starting at (4,4)
636    /// let depth = cell.depth(grid); // depth = 4
637    /// assert_eq!(depth, 4);
638    /// ```
639    pub fn depth(self, grid: Grid) -> u8 {
640        self.within_panic(grid);
641        self.global_depth - grid.start.global_depth
642    }
643
644    /// Calculates the gap between the `depth` of `Cell` and the `depth` of `Grid`
645    ///
646    /// # Panics
647    /// Panics if the `Cell` is not within the given `Grid`
648    ///
649    /// # Examples
650    ///
651    /// ```
652    /// use grid_math::{Cell, Grid};
653    ///
654    /// let cell = Cell::new(8, 8);
655    /// let grid = Grid::indented(7, 7, (4, 4)); // 7x7 grid starting at (4,4)
656    /// let depth_gap = cell.depth_gap(grid); // depth_gap = 2
657    /// assert_eq!(depth_gap, 2);
658    /// ```
659    pub fn depth_gap(self, grid: Grid) -> u8 {
660        self.within_panic(grid);
661        grid.end.global_depth - self.global_depth
662    }
663
664    /// Checks if the `up` operation on `Cell` will violate the given `Grid` upper border
665    ///
666    /// # Panics
667    /// Panics if the `Cell` is not within the given `Grid`
668    ///
669    /// # Examples
670    ///
671    /// ```
672    /// use grid_math::{Cell, Grid};
673    ///
674    /// let grid = Grid::new(10, 10);
675    /// let cell = Cell::new(2, 2);
676    /// assert!(cell.will_underflow_depth(grid, 3));
677    /// assert!(!cell.will_underflow_depth(grid, 2));
678    /// ```
679    pub fn will_underflow_depth(self, grid: Grid, step: u8) -> bool {
680        self.within_panic(grid);
681        self.global_depth < step || self.global_depth - step < grid.start.global_depth
682    }
683
684    /// Checks if the `down` operation on `Cell` will violate the given `Grid` lower border
685    ///
686    /// # Panics
687    /// Panics if the `Cell` is not within the given `Grid`
688    ///
689    /// # Examples
690    ///
691    /// ```
692    /// use grid_math::{Cell, Grid};
693    ///
694    /// let grid = Grid::new(10, 10);
695    /// let cell = Cell::new(7, 7);
696    /// assert!(cell.will_overflow_depth(grid, 3));
697    /// assert!(!cell.will_overflow_depth(grid, 2));
698    /// ```
699    pub fn will_overflow_depth(self, grid: Grid, step: u8) -> bool {
700        self.within_panic(grid);
701        self.global_depth > u8::MAX - step || self.global_depth + step > grid.end.global_depth
702    }
703
704    /// Checks if the `left` operation on `Cell` will violate the given `Grid` left border
705    ///
706    /// # Panics
707    /// Panics if the `Cell` is not within the given `Grid`
708    ///
709    /// # Examples
710    ///
711    /// ```
712    /// use grid_math::{Cell, Grid};
713    ///
714    /// let grid = Grid::new(10, 10);
715    /// let cell = Cell::new(2, 2);
716    /// assert!(cell.will_underflow_width(grid, 3));
717    /// assert!(!cell.will_underflow_width(grid, 2));
718    /// ```
719    pub fn will_underflow_width(self, grid: Grid, step: u8) -> bool {
720        self.within_panic(grid);
721        self.global_width < step || self.global_width - step < grid.start.global_width
722    }
723
724    /// Checks if the `right` operation on `Cell` will violate the given `Grid` right border
725    ///
726    /// # Panics
727    /// Panics if the `Cell` is not within the given `Grid`
728    ///
729    /// # Examples
730    ///
731    /// ```
732    /// use grid_math::{Cell, Grid};
733    ///
734    /// let grid = Grid::new(10, 10);
735    /// let cell = Cell::new(7, 7);
736    /// assert!(cell.will_overflow_width(grid, 3));
737    /// assert!(!cell.will_overflow_width(grid, 2));
738    /// ```
739    pub fn will_overflow_width(self, grid: Grid, step: u8) -> bool {
740        self.within_panic(grid);
741        self.global_width > u8::MAX - step || self.global_width + step > grid.end.global_width
742    }
743
744    /// Moves current `Cell` upwards by `step` relative to the given `Grid`
745    /// This operation does not mutate current `Cell` fields,
746    /// instead it calculates new position and returns new `Cell`
747    ///
748    /// # Panics
749    /// Panics if the `Cell` is not within the given `Grid`
750    /// Panics if this operation will violate the given `Grid` upper border
751    ///
752    /// # Examples
753    ///
754    /// ```
755    /// use grid_math::{Cell, Grid};
756    ///
757    /// let grid = Grid::new(10, 10);
758    /// let cell = Cell::new(2, 2);
759    /// let next = cell.strict_up(grid, 2);
760    /// assert_eq!(next, Cell::new(2, 0));
761    /// ```
762    ///
763    /// ```should_panic
764    /// use grid_math::{Cell, Grid};
765    ///
766    /// let grid = Grid::new(10, 10);
767    /// let cell = Cell::new(2, 2);
768    /// let next = cell.strict_up(grid, 3); // panic!
769    /// ```
770    pub fn strict_up(self, grid: Grid, step: u8) -> Cell {
771        if self.will_underflow_depth(grid, step) {
772            panic!(
773                "this operation will violate grid upper bounds! cell:{self}, grid:{grid}, step:{step}"
774            );
775        }
776        Cell {
777            global_width: self.global_width,
778            global_depth: self.global_depth - step,
779        }
780    }
781
782    /// Moves current `Cell` downwards by `step` relative to the given `Grid`
783    /// This operation does not mutate current `Cell` fields,
784    /// instead it calculates new position and returns new `Cell`
785    ///
786    /// # Panics
787    /// Panics if the `Cell` is not within the given `Grid`
788    /// Panics if this operation will violate the given `Grid` lower border
789    ///
790    /// # Examples
791    ///
792    /// ```
793    /// use grid_math::{Cell, Grid};
794    ///
795    /// let grid = Grid::new(10, 10);
796    /// let cell = Cell::new(7, 7);
797    /// let next = cell.strict_down(grid, 2);
798    /// assert_eq!(next, Cell::new(7, 9));
799    /// ```
800    ///
801    /// ```should_panic
802    /// use grid_math::{Cell, Grid};
803    ///
804    /// let grid = Grid::new(10, 10);
805    /// let cell = Cell::new(7, 7);
806    /// let next = cell.strict_down(grid, 3); // panic!
807    /// ```
808    pub fn strict_down(self, grid: Grid, step: u8) -> Cell {
809        if self.will_overflow_depth(grid, step) {
810            panic!(
811                "this operation will violate grid lower bounds! cell:{self}, grid:{grid}, step:{step}"
812            );
813        }
814        Cell {
815            global_width: self.global_width,
816            global_depth: self.global_depth + step,
817        }
818    }
819
820    /// Moves current `Cell` to the left by `step` relative to the given `Grid`
821    /// This operation does not mutate current `Cell` fields,
822    /// instead it calculates new position and returns new `Cell`
823    ///
824    /// # Panics
825    /// Panics if the `Cell` is not within the given `Grid`
826    /// Panics if this operation will violate the given `Grid` left border
827    ///
828    /// # Examples
829    ///
830    /// ```
831    /// use grid_math::{Cell, Grid};
832    ///
833    /// let grid = Grid::new(10, 10);
834    /// let cell = Cell::new(2, 2);
835    /// let next = cell.strict_left(grid, 2);
836    /// assert_eq!(next, Cell::new(0, 2));
837    /// ```
838    ///
839    /// ```should_panic
840    /// use grid_math::{Cell, Grid};
841    ///
842    /// let grid = Grid::new(10, 10);
843    /// let cell = Cell::new(2, 2);
844    /// let next = cell.strict_left(grid, 3); // panic!
845    /// ```
846    pub fn strict_left(self, grid: Grid, step: u8) -> Cell {
847        if self.will_underflow_width(grid, step) {
848            panic!(
849                "this operation will violate grid left bounds! cell:{self}, grid:{grid}, step:{step}"
850            );
851        }
852        Cell {
853            global_width: self.global_width - step,
854            global_depth: self.global_depth,
855        }
856    }
857
858    /// Moves current `Cell` to the right by `step` relative to the given `Grid`
859    /// This operation does not mutate current `Cell` fields,
860    /// instead it calculates new position and returns new `Cell`
861    ///
862    /// # Panics
863    /// Panics if the `Cell` is not within the given `Grid`
864    /// Panics if this operation will violate the given `Grid` right border
865    ///
866    /// # Examples
867    ///
868    /// ```
869    /// use grid_math::{Cell, Grid};
870    ///
871    /// let grid = Grid::new(10, 10);
872    /// let cell = Cell::new(7, 7);
873    /// let next = cell.strict_right(grid, 2);
874    /// assert_eq!(next, Cell::new(9, 7));
875    /// ```
876    ///
877    /// ```should_panic
878    /// use grid_math::{Cell, Grid};
879    ///
880    /// let grid = Grid::new(10, 10);
881    /// let cell = Cell::new(7, 7);
882    /// let next = cell.strict_right(grid, 3); // panic!
883    /// ```
884    pub fn strict_right(self, grid: Grid, step: u8) -> Cell {
885        if self.will_overflow_width(grid, step) {
886            panic!(
887                "this operation will violate grid right bounds! cell:{self}, grid:{grid}, step:{step}"
888            );
889        }
890        Cell {
891            global_width: self.global_width + step,
892            global_depth: self.global_depth,
893        }
894    }
895
896    /// Moves current `Cell` upwards by `step` relative to the given `Grid`
897    ///
898    /// This operation does not mutate current `Cell` fields,
899    /// instead it calculates new position and returns new `Cell`
900    ///
901    /// If this operation will cross `Grid` upper border,
902    /// returns `Cell` with `depth` = `Grid` upper depth limit
903    ///
904    /// # Panics
905    /// Panics if the `Cell` is not within the given `Grid`
906    ///
907    /// # Examples
908    ///
909    /// ```
910    /// use grid_math::{Cell, Grid};
911    ///
912    /// let grid = Grid::new(10, 10);
913    /// let cell = Cell::new(2, 2);
914    /// let next = cell.saturating_up(grid, 2);
915    /// assert_eq!(next, Cell::new(2, 0));
916    /// let next = cell.saturating_up(grid, 5);
917    /// assert_eq!(next, Cell::new(2, 0));
918    /// ```
919    pub fn saturating_up(self, grid: Grid, step: u8) -> Cell {
920        let next_depth = if self.will_underflow_depth(grid, step) {
921            grid.start.global_depth
922        } else {
923            self.global_depth - step
924        };
925        Cell {
926            global_width: self.global_width,
927            global_depth: next_depth,
928        }
929    }
930
931    /// Moves current `Cell` downwards by `step` relative to the given `Grid`
932    ///
933    /// This operation does not mutate current `Cell` fields,
934    /// instead it calculates new position and returns new `Cell`
935    ///
936    /// If this operation will cross `Grid` lower border,
937    /// returns `Cell` with `depth` = `Grid` lower depth limit
938    ///
939    /// # Panics
940    /// Panics if the `Cell` is not within the given `Grid`
941    ///
942    /// # Examples
943    ///
944    /// ```
945    /// use grid_math::{Cell, Grid};
946    ///
947    /// let grid = Grid::new(10, 10);
948    /// let cell = Cell::new(7, 7);
949    /// let next = cell.saturating_down(grid, 2);
950    /// assert_eq!(next, Cell::new(7, 9));
951    /// let next = cell.saturating_down(grid, 5);
952    /// assert_eq!(next, Cell::new(7, 9));
953    /// ```
954    pub fn saturating_down(self, grid: Grid, step: u8) -> Cell {
955        let next_depth = if self.will_overflow_depth(grid, step) {
956            grid.end.global_depth
957        } else {
958            self.global_depth + step
959        };
960        Cell {
961            global_width: self.global_width,
962            global_depth: next_depth,
963        }
964    }
965
966    /// Moves current `Cell` to the left by `step` relative to the given `Grid`
967    ///
968    /// This operation does not mutate current `Cell` fields,
969    /// instead it calculates new position and returns new `Cell`
970    ///
971    /// If this operation will cross `Grid` left border,
972    /// returns `Cell` with `width` = `Grid` left width limit
973    ///
974    /// # Panics
975    /// Panics if the `Cell` is not within the given `Grid`
976    ///
977    /// # Examples
978    ///
979    /// ```
980    /// use grid_math::{Cell, Grid};
981    ///
982    /// let grid = Grid::new(10, 10);
983    /// let cell = Cell::new(2, 2);
984    /// let next = cell.saturating_left(grid, 2);
985    /// assert_eq!(next, Cell::new(0, 2));
986    /// let next = cell.saturating_left(grid, 5);
987    /// assert_eq!(next, Cell::new(0, 2));
988    /// ```
989    pub fn saturating_left(self, grid: Grid, step: u8) -> Cell {
990        let next_width = if self.will_underflow_width(grid, step) {
991            grid.start.global_width
992        } else {
993            self.global_width - step
994        };
995        Cell {
996            global_width: next_width,
997            global_depth: self.global_depth,
998        }
999    }
1000
1001    /// Moves current `Cell` to the right by `step` relative to the given `Grid`
1002    ///
1003    /// This operation does not mutate current `Cell` fields,
1004    /// instead it calculates new position and returns new `Cell`
1005    ///
1006    /// If this operation will cross `Grid` right border,
1007    /// returns `Cell` with `width` = `Grid` right width limit
1008    ///
1009    /// # Panics
1010    /// Panics if the `Cell` is not within the given `Grid`
1011    ///
1012    /// # Examples
1013    ///
1014    /// ```
1015    /// use grid_math::{Cell, Grid};
1016    ///
1017    /// let grid = Grid::new(10, 10);
1018    /// let cell = Cell::new(7, 7);
1019    /// let next = cell.saturating_right(grid, 2);
1020    /// assert_eq!(next, Cell::new(9, 7));
1021    /// let next = cell.saturating_right(grid, 5);
1022    /// assert_eq!(next, Cell::new(9, 7));
1023    /// ```
1024    pub fn saturating_right(self, grid: Grid, step: u8) -> Cell {
1025        let next_width = if self.will_overflow_width(grid, step) {
1026            grid.end.global_width
1027        } else {
1028            self.global_width + step
1029        };
1030        Cell {
1031            global_width: next_width,
1032            global_depth: self.global_depth,
1033        }
1034    }
1035
1036    /// Moves current `Cell` upwards by `step` relative to the given `Grid`
1037    ///
1038    /// This operation does not mutate current `Cell` fields,
1039    /// instead it calculates new position and returns new `Cell` and `bool`
1040    ///
1041    /// This operation is similar to the overflowing operations on integer types
1042    /// It returns new `Cell` and 'bool' signaling that overflow happened
1043    ///
1044    /// # Panics
1045    /// Panics if the `Cell` is not within the given `Grid`
1046    ///
1047    /// # Examples
1048    ///
1049    /// ```
1050    /// use grid_math::{Cell, Grid};
1051    ///
1052    /// let grid = Grid::new(10, 10);
1053    /// let cell = Cell::new(2, 2);
1054    /// let (next, overflowed) = cell.overflowing_up(grid, 2);
1055    /// assert_eq!((next, overflowed), (Cell::new(2, 0), false));
1056    /// let (next, overflowed) = cell.overflowing_up(grid, 5);
1057    /// assert_eq!((next, overflowed), (Cell::new(2, 7), true));
1058    /// ```
1059    pub fn overflowing_up(self, grid: Grid, step: u8) -> (Cell, bool) {
1060        let underflowed = self.will_underflow_depth(grid, step);
1061        let next_depth = if underflowed {
1062            grid.end.global_depth - ((step - self.depth(grid) - 1) % grid.depth())
1063        } else {
1064            self.global_depth - step
1065        };
1066        (
1067            Cell {
1068                global_width: self.global_width,
1069                global_depth: next_depth,
1070            },
1071            underflowed,
1072        )
1073    }
1074
1075    /// Moves current `Cell` downwards by `step` relative to the given `Grid`
1076    ///
1077    /// This operation does not mutate current `Cell` fields,
1078    /// instead it calculates new position and returns new `Cell` and `bool`
1079    ///
1080    /// This operation is similar to the overflowing operations on integer types
1081    /// It returns new `Cell` and 'bool' signaling that overflow happened
1082    ///
1083    /// # Panics
1084    /// Panics if the `Cell` is not within the given `Grid`
1085    ///
1086    /// # Examples
1087    ///
1088    /// ```
1089    /// use grid_math::{Cell, Grid};
1090    ///
1091    /// let grid = Grid::new(10, 10);
1092    /// let cell = Cell::new(7, 7);
1093    /// let (next, overflowed) = cell.overflowing_down(grid, 2);
1094    /// assert_eq!((next, overflowed), (Cell::new(7, 9), false));
1095    /// let (next, overflowed) = cell.overflowing_down(grid, 5);
1096    /// assert_eq!((next, overflowed), (Cell::new(7, 2), true));
1097    /// ```
1098    pub fn overflowing_down(self, grid: Grid, step: u8) -> (Cell, bool) {
1099        let overflowed = self.will_overflow_depth(grid, step);
1100        let next_depth = if overflowed {
1101            grid.start.global_depth + ((step - self.depth_gap(grid) - 1) % grid.depth())
1102        } else {
1103            self.global_depth + step
1104        };
1105        (
1106            Cell {
1107                global_width: self.global_width,
1108                global_depth: next_depth,
1109            },
1110            overflowed,
1111        )
1112    }
1113
1114    /// Moves current `Cell` to the left by `step` relative to the given `Grid`
1115    ///
1116    /// This operation does not mutate current `Cell` fields,
1117    /// instead it calculates new position and returns new `Cell` and `bool`
1118    ///
1119    /// This operation is similar to the overflowing operations on integer types
1120    /// It returns new `Cell` and 'bool' signaling that overflow happened
1121    ///
1122    /// # Panics
1123    /// Panics if the `Cell` is not within the given `Grid`
1124    ///
1125    /// # Examples
1126    ///
1127    /// ```
1128    /// use grid_math::{Cell, Grid};
1129    ///
1130    /// let grid = Grid::new(10, 10);
1131    /// let cell = Cell::new(2, 2);
1132    /// let (next, overflowed) = cell.overflowing_left(grid, 2);
1133    /// assert_eq!((next, overflowed), (Cell::new(0, 2), false));
1134    /// let (next, overflowed) = cell.overflowing_left(grid, 5);
1135    /// assert_eq!((next, overflowed), (Cell::new(7, 2), true));
1136    /// ```
1137    pub fn overflowing_left(self, grid: Grid, step: u8) -> (Cell, bool) {
1138        let underflowed = self.will_underflow_width(grid, step);
1139        let next_width = if underflowed {
1140            grid.end.global_width - ((step - self.width(grid) - 1) % grid.width())
1141        } else {
1142            self.global_width - step
1143        };
1144        (
1145            Cell {
1146                global_width: next_width,
1147                global_depth: self.global_depth,
1148            },
1149            underflowed,
1150        )
1151    }
1152
1153    /// Moves current `Cell` to the right by `step` relative to the given `Grid`
1154    ///
1155    /// This operation does not mutate current `Cell` fields,
1156    /// instead it calculates new position and returns new `Cell` and `bool`
1157    ///
1158    /// This operation is similar to the overflowing operations on integer types
1159    /// It returns new `Cell` and 'bool' signaling that overflow happened
1160    ///
1161    /// # Panics
1162    /// Panics if the `Cell` is not within the given `Grid`
1163    ///
1164    /// # Examples
1165    ///
1166    /// ```
1167    /// use grid_math::{Cell, Grid};
1168    ///
1169    /// let grid = Grid::new(10, 10);
1170    /// let cell = Cell::new(7, 7);
1171    /// let (next, overflowed) = cell.overflowing_right(grid, 2);
1172    /// assert_eq!((next, overflowed), (Cell::new(9, 7), false));
1173    /// let (next, overflowed) = cell.overflowing_right(grid, 5);
1174    /// assert_eq!((next, overflowed), (Cell::new(2, 7), true));
1175    /// ```
1176    pub fn overflowing_right(self, grid: Grid, step: u8) -> (Cell, bool) {
1177        let overflowed = self.will_overflow_width(grid, step);
1178        let next_width = if overflowed {
1179            grid.start.global_width + ((step - self.width_gap(grid) - 1) % grid.width())
1180        } else {
1181            self.global_width + step
1182        };
1183        (
1184            Cell {
1185                global_width: next_width,
1186                global_depth: self.global_depth,
1187            },
1188            overflowed,
1189        )
1190    }
1191
1192    /// Moves current `Cell` upwards by `step` relative to the given `Grid`
1193    ///
1194    /// This operation is a wrapper around the `overflowing_up()` method,
1195    /// and returns only new `Cell`, without `bool`
1196    ///
1197    /// # Panics
1198    /// Panics if the `Cell` is not within the given `Grid`
1199    ///
1200    /// # Examples
1201    ///
1202    /// ```
1203    /// use grid_math::{Cell, Grid};
1204    ///
1205    /// let grid = Grid::new(10, 10);
1206    /// let cell = Cell::new(2, 2);
1207    /// let next = cell.wrapping_up(grid, 2);
1208    /// assert_eq!(next, Cell::new(2, 0));
1209    /// let next = cell.wrapping_up(grid, 5);
1210    /// assert_eq!(next, Cell::new(2, 7));
1211    /// ```
1212    pub fn wrapping_up(self, grid: Grid, step: u8) -> Cell {
1213        self.overflowing_up(grid, step).0
1214    }
1215
1216    /// Moves current `Cell` downwards by `step` relative to the given `Grid`
1217    ///
1218    /// This operation is a wrapper around the `overflowing_down()` method,
1219    /// and returns only new `Cell`, without `bool`
1220    ///
1221    /// # Panics
1222    /// Panics if the `Cell` is not within the given `Grid`
1223    ///
1224    /// # Examples
1225    ///
1226    /// ```
1227    /// use grid_math::{Cell, Grid};
1228    ///
1229    /// let grid = Grid::new(10, 10);
1230    /// let cell = Cell::new(7, 7);
1231    /// let next = cell.wrapping_down(grid, 2);
1232    /// assert_eq!(next, Cell::new(7, 9));
1233    /// let next = cell.wrapping_down(grid, 5);
1234    /// assert_eq!(next, Cell::new(7, 2));
1235    /// ```
1236    pub fn wrapping_down(self, grid: Grid, step: u8) -> Cell {
1237        self.overflowing_down(grid, step).0
1238    }
1239
1240    /// Moves current `Cell` to the left by `step` relative to the given `Grid`
1241    ///
1242    /// This operation is a wrapper around the `overflowing_left()` method,
1243    /// and returns only new `Cell`, without `bool`
1244    ///
1245    /// # Panics
1246    /// Panics if the `Cell` is not within the given `Grid`
1247    ///
1248    /// # Examples
1249    ///
1250    /// ```
1251    /// use grid_math::{Cell, Grid};
1252    ///
1253    /// let grid = Grid::new(10, 10);
1254    /// let cell = Cell::new(2, 2);
1255    /// let next = cell.wrapping_left(grid, 2);
1256    /// assert_eq!(next, Cell::new(0, 2));
1257    /// let next = cell.wrapping_left(grid, 5);
1258    /// assert_eq!(next, Cell::new(7, 2));
1259    /// ```
1260    pub fn wrapping_left(self, grid: Grid, step: u8) -> Cell {
1261        self.overflowing_left(grid, step).0
1262    }
1263
1264    /// Moves current `Cell` to the right by `step` relative to the given `Grid`
1265    ///
1266    /// This operation is a wrapper around the `overflowing_right()` method,
1267    /// and returns only new `Cell`, without `bool`
1268    ///
1269    /// # Panics
1270    /// Panics if the `Cell` is not within the given `Grid`
1271    ///
1272    /// # Examples
1273    ///
1274    /// ```
1275    /// use grid_math::{Cell, Grid};
1276    ///
1277    /// let grid = Grid::new(10, 10);
1278    /// let cell = Cell::new(7, 7);
1279    /// let next = cell.wrapping_right(grid, 2);
1280    /// assert_eq!(next, Cell::new(9, 7));
1281    /// let next = cell.wrapping_right(grid, 5);
1282    /// assert_eq!(next, Cell::new(2, 7));
1283    /// ```
1284    pub fn wrapping_right(self, grid: Grid, step: u8) -> Cell {
1285        self.overflowing_right(grid, step).0
1286    }
1287
1288    /// Projects current `Cell` onto the top side of the given `Grid`
1289    ///
1290    /// This operation does not mutate current `Cell` fields,
1291    /// instead it calculates new position and returns new `Cell`
1292    ///
1293    /// # Panics
1294    /// Panics if the `Cell` is not within the given `Grid`
1295    ///
1296    /// # Examples
1297    ///
1298    /// ```
1299    /// use grid_math::{Cell, Grid};
1300    ///
1301    /// let grid = Grid::new(10, 10);
1302    /// let cell = Cell::new(2, 2);
1303    /// let next = cell.project_up(grid);
1304    /// assert_eq!(next, Cell::new(2, 0));
1305    /// ```
1306    pub fn project_up(self, grid: Grid) -> Cell {
1307        self.saturating_up(grid, u8::MAX)
1308    }
1309
1310    /// Projects current `Cell` onto the bottom side of the given `Grid`
1311    ///
1312    /// This operation does not mutate current `Cell` fields,
1313    /// instead it calculates new position and returns new `Cell`
1314    ///
1315    /// # Panics
1316    /// Panics if the `Cell` is not within the given `Grid`
1317    ///
1318    /// # Examples
1319    ///
1320    /// ```
1321    /// use grid_math::{Cell, Grid};
1322    ///
1323    /// let grid = Grid::new(10, 10);
1324    /// let cell = Cell::new(7, 7);
1325    /// let next = cell.project_down(grid);
1326    /// assert_eq!(next, Cell::new(7, 9));
1327    /// ```
1328    pub fn project_down(self, grid: Grid) -> Cell {
1329        self.saturating_down(grid, u8::MAX)
1330    }
1331
1332    /// Projects current `Cell` onto the left side of the given `Grid`
1333    ///
1334    /// This operation does not mutate current `Cell` fields,
1335    /// instead it calculates new position and returns new `Cell`
1336    ///
1337    /// # Panics
1338    /// Panics if the `Cell` is not within the given `Grid`
1339    ///
1340    /// # Examples
1341    ///
1342    /// ```
1343    /// use grid_math::{Cell, Grid};
1344    ///
1345    /// let grid = Grid::new(10, 10);
1346    /// let cell = Cell::new(2, 2);
1347    /// let next = cell.project_left(grid);
1348    /// assert_eq!(next, Cell::new(0, 2));
1349    /// ```
1350    pub fn project_left(self, grid: Grid) -> Cell {
1351        self.saturating_left(grid, u8::MAX)
1352    }
1353
1354    /// Projects current `Cell` onto the right side of the given `Grid`
1355    ///
1356    /// This operation does not mutate current `Cell` fields,
1357    /// instead it calculates new position and returns new `Cell`
1358    ///
1359    /// # Panics
1360    /// Panics if the `Cell` is not within the given `Grid`
1361    ///
1362    /// # Examples
1363    ///
1364    /// ```
1365    /// use grid_math::{Cell, Grid};
1366    ///
1367    /// let grid = Grid::new(10, 10);
1368    /// let cell = Cell::new(7, 7);
1369    /// let next = cell.project_right(grid);
1370    /// assert_eq!(next, Cell::new(9, 7));
1371    /// ```
1372    pub fn project_right(self, grid: Grid) -> Cell {
1373        self.saturating_right(grid, u8::MAX)
1374    }
1375}
1376
1377impl fmt::Display for Cell {
1378    /// implements display for `Cell`
1379    ///
1380    /// # Examples
1381    ///
1382    /// ```
1383    /// use grid_math::Cell;
1384    ///
1385    /// let cell = Cell::new(5, 6);
1386    /// assert_eq!(format!("{cell}"), "(5, 6)");
1387    /// ```
1388    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1389        write!(
1390            f,
1391            "({w}, {d})",
1392            w = self.global_width,
1393            d = self.global_depth
1394        )
1395    }
1396}
1397
1398impl From<(u8, u8)> for Cell {
1399    /// implements constructor for `Cell` from (u8, u8)
1400    ///
1401    /// # Examples
1402    ///
1403    /// ```
1404    /// use grid_math::Cell;
1405    ///
1406    /// let pos = (5, 6);
1407    /// let cell = Cell::from(pos);
1408    /// assert_eq!((pos.0, pos.1), (cell.global_width(), cell.global_depth()));
1409    /// ```
1410    fn from(value: (u8, u8)) -> Self {
1411        Self {
1412            global_width: value.0,
1413            global_depth: value.1,
1414        }
1415    }
1416}
1417
1418#[allow(clippy::from_over_into)]
1419impl Into<(u8, u8)> for Cell {
1420    /// implements conversion from `Cell` into (u8, u8)
1421    ///
1422    /// # Examples
1423    ///
1424    /// ```
1425    /// use grid_math::Cell;
1426    ///
1427    /// let cell = Cell::new(5, 6);
1428    /// let pos: (u8, u8) = cell.into();
1429    /// assert_eq!((pos.0, pos.1), (cell.global_width(), cell.global_depth()));
1430    /// ```
1431    fn into(self) -> (u8, u8) {
1432        (self.global_width, self.global_depth)
1433    }
1434}
1435
1436impl Grid {
1437    /// Creates new `Grid` with specified `width: u8` and `depth: u8`, starting at (0,0)
1438    ///
1439    /// # Panics
1440    /// Panics if `width` or `depth` parameters < 1
1441    ///
1442    /// # Examples
1443    ///
1444    /// ```
1445    /// use grid_math::Grid;
1446    ///
1447    /// let grid = Grid::new(10, 10);
1448    /// assert_eq!(format!("{grid}"), "[(0, 0):(9, 9)]");
1449    /// ```
1450    pub fn new(width: u8, depth: u8) -> Self {
1451        if width < 1 || depth < 1 {
1452            panic!("can't create grid with width < 0 or depth < 0!")
1453        }
1454        Self {
1455            start: Cell {
1456                global_width: 0,
1457                global_depth: 0,
1458            },
1459            end: Cell {
1460                global_width: width - 1,
1461                global_depth: depth - 1,
1462            },
1463        }
1464    }
1465
1466    /// Creates new `Grid` with specified `width: u8` and `depth: u8`, starting at indent
1467    ///
1468    /// # Panics
1469    /// Panics if `width` or `depth` parameters < 1
1470    ///
1471    /// # Examples
1472    ///
1473    /// ```
1474    /// use grid_math::{Grid, Cell};
1475    ///
1476    /// let grid = Grid::indented(5, 5, (2, 2));
1477    /// assert_eq!(format!("{grid}"), "[(2, 2):(6, 6)]");
1478    ///
1479    /// // use `Cell` as indent:
1480    /// let cell = Cell::new(2, 2);
1481    /// let grid = Grid::indented(5, 5, cell.into());
1482    /// assert_eq!(format!("{grid}"), "[(2, 2):(6, 6)]");
1483    /// ```
1484    pub fn indented(width: u8, depth: u8, indent: (u8, u8)) -> Self {
1485        if width < 1 || depth < 1 {
1486            panic!("can't create grid with width < 0 or depth < 0!")
1487        }
1488        Self {
1489            start: Cell {
1490                global_width: indent.0,
1491                global_depth: indent.1,
1492            },
1493            end: Cell {
1494                global_width: indent.0 + width - 1,
1495                global_depth: indent.1 + depth - 1,
1496            },
1497        }
1498    }
1499
1500    /// Checks if the `Grid` is within the another `Grid`
1501    ///
1502    /// # Examples
1503    ///
1504    /// ```
1505    /// use grid_math::Grid;
1506    ///
1507    /// let grid = Grid::new(10, 10);
1508    /// let subgrid = grid.area(5, 5);
1509    /// assert!(subgrid.within(grid));
1510    ///
1511    /// let subgrid = Grid::new(10, 12);
1512    /// assert!(!subgrid.within(grid));
1513    /// ```
1514    pub fn within(self, grid: Grid) -> bool {
1515        self.start.within(grid) && self.end.within(grid)
1516    }
1517
1518    /// Checks if the `Grid` is within the another `Grid`
1519    ///
1520    /// # Panics
1521    /// Panics if the `Grid` is not within the another `Grid`
1522    ///
1523    /// # Examples
1524    ///
1525    /// ```should_panic
1526    /// use grid_math::Grid;
1527    ///
1528    /// let grid = Grid::new(10, 10);
1529    /// let subgrid = Grid::new(10, 12);
1530    /// subgrid.within_panic(grid);
1531    /// ```
1532    pub fn within_panic(self, grid: Grid) {
1533        if !self.within(grid) {
1534            panic!("subgrid is not within given grid! subgrid:{self}, grid:{grid}")
1535        }
1536    }
1537
1538    /// Returns new `Cell` by `width: u8` and `depth: u8` relative to the current `Grid`
1539    ///
1540    /// # Panics
1541    /// Panics if `width` or `depth` of the requested member exceeds borders of the current `Grid`
1542    ///
1543    /// # Examples
1544    ///
1545    /// ```
1546    /// use grid_math::{Grid, Cell};
1547    ///
1548    /// let grid = Grid::indented(5, 5, (2, 2)); // 5x5 grid, starting at (2,2)
1549    /// let member = grid.member(4, 4);
1550    /// assert_eq!(member, Cell::new(6, 6));
1551    /// ```
1552    pub fn member(self, width: u8, depth: u8) -> Cell {
1553        self.start
1554            .strict_right(self, width)
1555            .strict_down(self, depth)
1556    }
1557
1558    /// Returns new `Grid` with `width: u8` and `depth: u8`, which is a subgrid
1559    /// of current `Grid`, starting at current `Grid` start
1560    ///
1561    /// # Panics
1562    /// Panics if `width` or `depth` parameters < 1
1563    /// Panics if `width` or `depth` of the requested area exceeds borders of the current `Grid`
1564    ///
1565    /// # Examples
1566    ///
1567    /// ```
1568    /// use grid_math::{Grid, Cell};
1569    ///
1570    /// let grid = Grid::indented(5, 5, (2, 2)); // 5x5 grid, starting at (2,2)
1571    /// let area = grid.area(3, 3);
1572    /// assert_eq!(format!("{area}"), "[(2, 2):(4, 4)]");
1573    /// ```
1574    pub fn area(self, width: u8, depth: u8) -> Grid {
1575        if width < 1 || depth < 1 {
1576            panic!("can't create grid with width < 0 or depth < 0!")
1577        }
1578        Grid {
1579            start: self.start,
1580            end: self
1581                .start
1582                .strict_right(self, width - 1)
1583                .strict_down(self, depth - 1),
1584        }
1585    }
1586
1587    /// Returns new `Grid` with `width: u8` and `depth: u8`, which is a subgrid
1588    /// of current `Grid`, starting at current `Grid` start + indent
1589    ///
1590    /// # Panics
1591    /// Panics if `width` or `depth` parameters < 1
1592    /// Panics if `width` or `depth` of the requested slice exceeds borders of the current `Grid`
1593    /// Panics if `indent` of the requested slice exceeds borders of the current `Grid`
1594    ///
1595    /// # Examples
1596    ///
1597    /// ```
1598    /// use grid_math::{Grid, Cell};
1599    ///
1600    /// let grid = Grid::new(10, 10);
1601    /// let slice = grid.slice(3, 3, (2, 2));
1602    /// assert_eq!(format!("{slice}"), "[(2, 2):(4, 4)]");
1603    ///
1604    /// // use `Cell` as indent:
1605    /// let cell = Cell::new(2, 2);
1606    /// let slice = grid.slice(3, 3, cell.into());
1607    /// assert_eq!(format!("{slice}"), "[(2, 2):(4, 4)]");
1608    /// ```
1609    pub fn slice(self, width: u8, depth: u8, indent: (u8, u8)) -> Grid {
1610        if width < 1 || depth < 1 {
1611            panic!("can't create grid with width < 0 or depth < 0!")
1612        }
1613        Grid {
1614            start: self
1615                .start
1616                .strict_right(self, indent.0)
1617                .strict_down(self, indent.1),
1618            end: self
1619                .start
1620                .strict_right(self, indent.0 + width - 1)
1621                .strict_down(self, indent.1 + depth - 1),
1622        }
1623    }
1624
1625    /// Returns `start` cell of `Grid`
1626    ///
1627    /// # Examples
1628    ///
1629    /// ```
1630    /// use grid_math::{Grid, Cell};
1631    ///
1632    /// let grid = Grid::new(10, 10);
1633    /// let start = grid.start();
1634    /// assert_eq!(start, Cell::new(0, 0));
1635    /// ```
1636    pub fn start(self) -> Cell {
1637        self.start
1638    }
1639
1640    /// Returns `end` cell of `Grid`
1641    ///
1642    /// # Examples
1643    ///
1644    /// ```
1645    /// use grid_math::{Grid, Cell};
1646    ///
1647    /// let grid = Grid::new(10, 10);
1648    /// let end = grid.end();
1649    /// assert_eq!(end, Cell::new(9, 9));
1650    /// ```
1651    pub fn end(self) -> Cell {
1652        self.end
1653    }
1654
1655    /// Calculates `width` of `Grid`
1656    ///
1657    /// # Examples
1658    ///
1659    /// ```
1660    /// use grid_math::Grid;
1661    ///
1662    /// let grid = Grid::new(10, 10);
1663    /// let width = grid.width();
1664    /// assert_eq!(width, 10);
1665    /// ```
1666    pub fn width(self) -> u8 {
1667        self.end.global_width - self.start.global_width + 1
1668    }
1669
1670    /// Calculates `depth` of `Grid`
1671    ///
1672    /// # Examples
1673    ///
1674    /// ```
1675    /// use grid_math::Grid;
1676    ///
1677    /// let grid = Grid::new(10, 10);
1678    /// let depth = grid.depth();
1679    /// assert_eq!(depth, 10);
1680    /// ```
1681    pub fn depth(self) -> u8 {
1682        self.end.global_depth - self.start.global_depth + 1
1683    }
1684
1685    /// Calculates `size: u16` of `Grid`
1686    ///
1687    /// # Examples
1688    ///
1689    /// ```
1690    /// use grid_math::Grid;
1691    ///
1692    /// let grid = Grid::new(10, 10);
1693    /// let size = grid.size();
1694    /// assert_eq!(size, 100);
1695    /// ```
1696    pub fn size(self) -> u16 {
1697        self.width() as u16 * self.depth() as u16
1698    }
1699
1700    /// Returns `Cells`, which is an iterator over every cell of the `Grid`
1701    ///
1702    /// # Examples
1703    ///
1704    /// Get every `Cell` on `width` and `depth` axis:
1705    /// ```
1706    /// use grid_math::{Cell, Grid};
1707    ///
1708    /// let grid = Grid::new(3, 3);
1709    ///
1710    /// let axis_cells: Vec<Cell> = grid
1711    ///     .cells()
1712    ///     .filter(|cell| {
1713    ///         cell.global_width() == grid.start().global_width() || cell.global_depth() == grid.start().global_depth()
1714    ///     })
1715    ///     .collect();
1716    /// assert_eq!(axis_cells, vec![
1717    ///     Cell::new(0, 0),
1718    ///     Cell::new(1, 0),
1719    ///     Cell::new(2, 0),
1720    ///     Cell::new(0, 1),
1721    ///     Cell::new(0, 2),
1722    /// ]);
1723    /// ```
1724    pub fn cells(self) -> Cells {
1725        Cells::from(self)
1726    }
1727
1728    /// Returns `Rows`, which is an iterator over every row of the `Grid`
1729    ///
1730    /// # Examples
1731    ///
1732    /// Print out `Grid` in custom format:
1733    /// ```
1734    /// use grid_math::{Cell, Grid};
1735    ///
1736    /// let grid = Grid::new(3, 3);
1737    /// let grid_string = grid
1738    ///     .rows()
1739    ///     .map(|row| {
1740    ///         row.cells().map(|_| " [#]")
1741    ///             .chain(std::iter::once("\n\n"))
1742    ///             .collect::<String>()
1743    ///     })
1744    ///     .collect::<String>();
1745    /// assert_eq!(grid_string,
1746    /// " \
1747    ///  [#] [#] [#]
1748    ///
1749    ///  [#] [#] [#]
1750    ///
1751    ///  [#] [#] [#]
1752    ///
1753    /// "
1754    /// );
1755    /// ```
1756    pub fn rows(self) -> Rows {
1757        Rows::from(self)
1758    }
1759
1760    /// Returns `Columns`, which is an iterator over every column of the `Grid`
1761    ///
1762    /// # Examples
1763    ///
1764    /// Get every `Cell` on the first column of `Grid`:
1765    /// ```
1766    /// use grid_math::{Cell, Grid};
1767    ///
1768    /// let grid = Grid::new(3, 3);
1769    ///
1770    /// let first_column_cells: Vec<Cell> = grid
1771    ///     .columns()
1772    ///     .next()
1773    ///     .unwrap()
1774    ///     .cells()
1775    ///     .collect();
1776    ///
1777    /// assert_eq!(first_column_cells, vec![
1778    ///     Cell::new(0, 0),
1779    ///     Cell::new(0, 1),
1780    ///     Cell::new(0, 2),
1781    /// ]);
1782    /// ```
1783    pub fn columns(self) -> Columns {
1784        Columns::from(self)
1785    }
1786}
1787
1788impl From<(Cell, Cell)> for Grid {
1789    /// implements constructor for `Grid` from (Cell, Cell)
1790    ///
1791    /// # Examples
1792    ///
1793    /// ```
1794    /// use grid_math::{Cell, Grid};
1795    ///
1796    /// let cells = (Cell::new(2, 2), Cell::new(5, 5));
1797    /// let grid = Grid::from(cells);
1798    /// assert_eq!((cells.0, cells.1), (grid.start(), grid.end()));
1799    /// ```
1800    fn from(value: (Cell, Cell)) -> Self {
1801        let (start, end) = value;
1802        if start.global_width > end.global_width || start.global_depth > end.global_depth {
1803            panic!("start cell overflows end cell! start:{start}, end:{end}")
1804        }
1805        Self { start, end }
1806    }
1807}
1808
1809#[allow(clippy::from_over_into)]
1810impl Into<(Cell, Cell)> for Grid {
1811    /// implements conversion from `Grid` into (Cell, Cell)
1812    ///
1813    /// # Examples
1814    ///
1815    /// ```
1816    /// use grid_math::{Cell, Grid};
1817    ///
1818    /// let grid = Grid::new(5, 5);
1819    /// let cells: (Cell, Cell) = grid.into();
1820    /// assert_eq!((cells.0, cells.1), (grid.start(), grid.end()));
1821    /// ```
1822    fn into(self) -> (Cell, Cell) {
1823        (self.start, self.end)
1824    }
1825}
1826
1827impl From<((u8, u8), (u8, u8))> for Grid {
1828    /// implements constructor for `Grid` from ((u8, u8), (u8, u8))
1829    ///
1830    /// # Examples
1831    ///
1832    /// ```
1833    /// use grid_math::{Cell, Grid};
1834    ///
1835    /// let vals = ((2, 2), (5, 5));
1836    /// let grid = Grid::from(vals);
1837    /// assert_eq!((Cell::from(vals.0), Cell::from(vals.1)), (grid.start(), grid.end()));
1838    /// ```
1839    fn from(value: ((u8, u8), (u8, u8))) -> Self {
1840        let (start, end): (Cell, Cell) = (value.0.into(), value.1.into());
1841        if start.global_width > end.global_width || start.global_depth > end.global_depth {
1842            panic!("start cell overflows end cell! start:{start}, end:{end}")
1843        }
1844        Self { start, end }
1845    }
1846}
1847
1848#[allow(clippy::from_over_into)]
1849impl Into<((u8, u8), (u8, u8))> for Grid {
1850    /// implements conversion from `Grid` into ((u8, u8), (u8, u8))
1851    ///
1852    /// # Examples
1853    ///
1854    /// ```
1855    /// use grid_math::{Cell, Grid};
1856    ///
1857    /// let grid = Grid::new(5, 5);
1858    /// let vals: ((u8, u8), (u8, u8)) = grid.into();
1859    /// assert_eq!((Cell::from(vals.0), Cell::from(vals.1)), (grid.start(), grid.end()));
1860    /// ```
1861    fn into(self) -> ((u8, u8), (u8, u8)) {
1862        (self.start.into(), self.end.into())
1863    }
1864}
1865
1866impl fmt::Display for Grid {
1867    /// implements display for `Grid`
1868    ///
1869    /// # Examples
1870    ///
1871    /// ```
1872    /// use grid_math::Grid;
1873    ///
1874    /// let grid = Grid::new(5, 6);
1875    /// assert_eq!(format!("{grid}"), "[(0, 0):(4, 5)]");
1876    /// ```
1877    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1878        write!(f, "[{start}:{end}]", start = self.start, end = self.end)
1879    }
1880}
1881
1882impl From<Grid> for Cells {
1883    /// Creates new iterator over every `Cell` on the `Grid`
1884    ///
1885    /// # Examples:
1886    ///
1887    /// ```
1888    /// use grid_math::{Grid, Cells};
1889    ///
1890    /// let grid = Grid::new(5, 5);
1891    /// let cells = Cells::from(grid);
1892    /// ```
1893    fn from(grid: Grid) -> Self {
1894        Self {
1895            grid,
1896            current: grid.start,
1897            consumed: false,
1898        }
1899    }
1900}
1901
1902impl From<Grid> for Columns {
1903    /// Creates new iterator over every column on the `Grid`
1904    ///
1905    /// # Examples:
1906    ///
1907    /// ```
1908    /// use grid_math::{Grid, Columns};
1909    ///
1910    /// let grid = Grid::new(5, 5);
1911    /// let columns = Columns::from(grid);
1912    /// ```
1913    fn from(grid: Grid) -> Self {
1914        Self {
1915            grid,
1916            current: Grid {
1917                start: grid.start,
1918                end: grid.start.project_down(grid),
1919            },
1920            consumed: false,
1921        }
1922    }
1923}
1924
1925impl From<Grid> for Rows {
1926    /// Creates new iterator over every row on the `Grid`
1927    ///
1928    /// # Examples:
1929    ///
1930    /// ```
1931    /// use grid_math::{Grid, Rows};
1932    ///
1933    /// let grid = Grid::new(5, 5);
1934    /// let rows = Rows::from(grid);
1935    /// ```
1936    fn from(grid: Grid) -> Self {
1937        Self {
1938            grid,
1939            current: Grid {
1940                start: grid.start,
1941                end: grid.start.project_right(grid),
1942            },
1943            consumed: false,
1944        }
1945    }
1946}
1947
1948impl Iterator for Cells {
1949    type Item = Cell;
1950    fn next(&mut self) -> Option<Self::Item> {
1951        if self.consumed {
1952            return None;
1953        }
1954        if self.current == self.grid.end {
1955            self.consumed = true;
1956            return Some(self.current);
1957        }
1958        let previous = self.current;
1959        match self.current.overflowing_right(self.grid, 1) {
1960            (next, true) => self.current = next.wrapping_down(self.grid, 1),
1961            (next, false) => self.current = next,
1962        }
1963        Some(previous)
1964    }
1965}
1966
1967impl Iterator for Columns {
1968    type Item = Grid;
1969    fn next(&mut self) -> Option<Self::Item> {
1970        if self.consumed {
1971            return None;
1972        }
1973        if self.current.end == self.grid.end {
1974            self.consumed = true;
1975            return Some(self.current);
1976        }
1977        let previous = self.current;
1978        self.current = Grid {
1979            start: self.current.start.saturating_right(self.grid, 1),
1980            end: self.current.end.saturating_right(self.grid, 1),
1981        };
1982        Some(previous)
1983    }
1984}
1985
1986impl Iterator for Rows {
1987    type Item = Grid;
1988    fn next(&mut self) -> Option<Self::Item> {
1989        if self.consumed {
1990            return None;
1991        }
1992        if self.current.end == self.grid.end {
1993            self.consumed = true;
1994            return Some(self.current);
1995        }
1996        let previous = self.current;
1997        self.current = Grid {
1998            start: self.current.start.saturating_down(self.grid, 1),
1999            end: self.current.end.saturating_down(self.grid, 1),
2000        };
2001        Some(previous)
2002    }
2003}
2004
2005impl<V> From<Grid> for GridMap<V> {
2006    /// Creates new `GridMap` from the given `Grid` with empty `HashMap<Cell, T>`
2007    ///
2008    /// # Examples:
2009    ///
2010    /// ```
2011    /// use grid_math::{Grid, GridMap};
2012    ///
2013    /// let grid = Grid::new(5, 5);
2014    /// let map: GridMap<char> = GridMap::from(grid);
2015    /// ```
2016    fn from(grid: Grid) -> Self {
2017        Self {
2018            grid,
2019            hashmap: HashMap::new(),
2020        }
2021    }
2022}
2023
2024impl<V> GridMap<V> {
2025    /// Shadows `insert` method from the `HashMap`, and reimplements it
2026    /// so it checks first if the key (`Cell`) is within the `Grid`, and then inserts it into the `HashMap`.
2027    /// This method currently has bad error handling, but this may change in the future
2028    ///
2029    /// # Panics
2030    /// Panics, if the key (`Cell`) is not within the inner `Grid`
2031    ///
2032    /// # Examples:
2033    ///
2034    /// ```
2035    /// use grid_math::{Grid, GridMap};
2036    ///
2037    /// let grid = Grid::new(5, 5);
2038    /// let mut map: GridMap<char> = GridMap::from(grid);
2039    /// map.insert(map.grid().start(), '#');
2040    /// map.insert(map.grid().end(), '@');
2041    /// assert_eq!(map.len(), 2);
2042    /// ```
2043    ///
2044    /// ```should_panic
2045    /// use grid_math::{Cell, Grid, GridMap};
2046    ///
2047    /// let grid = Grid::new(5, 5);
2048    /// let cell = Cell::new(6, 6);
2049    /// let mut map: GridMap<char> = GridMap::from(grid);
2050    /// map.insert(cell, '#'); // panic!
2051    /// ```
2052    pub fn insert(&mut self, cell: Cell, value: V) -> Option<V> {
2053        cell.within_panic(self.grid);
2054        self.hashmap.insert(cell, value)
2055    }
2056
2057    /// Returns the inner `Grid`
2058    ///
2059    /// # Examples:
2060    ///
2061    /// ```
2062    /// use grid_math::{Grid, GridMap};
2063    ///
2064    /// let grid = Grid::new(5, 5);
2065    /// let map: GridMap<char> = GridMap::from(grid);
2066    ///
2067    /// assert_eq!(grid, map.grid());
2068    /// ```
2069    pub fn grid(&self) -> Grid {
2070        self.grid
2071    }
2072}
2073
2074/// Implements `Deref` trait for GridMap, to return ref to the inner `HashMap`,
2075/// so we can call methods from `HashMap` directly on the `GridMap`
2076///
2077/// # Examples:
2078///
2079/// ```
2080/// use grid_math::{Grid, GridMap};
2081///
2082/// let grid = Grid::new(5, 5);
2083/// let mut map: GridMap<char> = GridMap::from(grid);
2084/// map.insert(map.grid().start(), '#');
2085///
2086/// assert_eq!(map.len(), 1);
2087/// ```
2088impl<V> Deref for GridMap<V> {
2089    type Target = HashMap<Cell, V>;
2090    fn deref(&self) -> &Self::Target {
2091        &self.hashmap
2092    }
2093}
2094
2095/// Implements `DerefMut` trait for GridMap, to return mut ref to the inner `HashMap`,
2096/// so we can call methods from `HashMap` directly on the `GridMap`
2097///
2098/// # Examples:
2099///
2100/// ```
2101/// use grid_math::{Grid, GridMap};
2102///
2103/// let grid = Grid::new(5, 5);
2104/// let mut map: GridMap<char> = GridMap::from(grid);
2105/// map.insert(map.grid().start(), '#');
2106///
2107/// assert_eq!(map.len(), 1);
2108/// ```
2109impl<V> DerefMut for GridMap<V> {
2110    fn deref_mut(&mut self) -> &mut Self::Target {
2111        &mut self.hashmap
2112    }
2113}
2114
2115// 🦀!⭐!!!