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/// ```
491#[derive(Debug, Clone)]
492pub struct GridMap<V> {
493    grid: Grid,
494    hashmap: HashMap<Cell, V>,
495}
496
497impl Cell {
498    /// Creates new `Cell` with specified `global_width: u8` and `global_depth: u8` global position
499    ///
500    /// # Examples
501    ///
502    /// ```
503    /// use grid_math::Cell;
504    ///
505    /// let cell = Cell::new(10, 15);
506    /// ```
507    pub fn new(global_width: u8, global_depth: u8) -> Self {
508        Self {
509            global_width,
510            global_depth,
511        }
512    }
513
514    /// Checks if the `Cell` is within the given `Grid`
515    ///
516    /// # Examples
517    ///
518    /// ```
519    /// use grid_math::{Cell, Grid};
520    ///
521    /// let grid = Grid::new(10, 10);
522    /// let cell = Cell::new(5, 5);
523    /// assert!(cell.within(grid));
524    ///
525    /// let cell = Cell::new(9, 15);
526    /// assert!(!cell.within(grid));
527    /// ```
528    pub fn within(self, grid: Grid) -> bool {
529        (grid.start.global_width..=grid.end.global_width).contains(&self.global_width)
530            && (grid.start.global_depth..=grid.end.global_depth).contains(&self.global_depth)
531    }
532
533    /// Checks if the `Cell` is within the given `Grid`
534    ///
535    /// # Panics
536    /// Panics if the `Cell` is not within the given `Grid`
537    ///
538    /// # Examples
539    ///
540    /// ```should_panic
541    /// use grid_math::{Cell, Grid};
542    ///
543    /// let grid = Grid::new(10, 10);
544    /// let cell = Cell::new(9, 15);
545    /// cell.within_panic(grid);
546    /// ```
547    pub fn within_panic(self, grid: Grid) {
548        if !self.within(grid) {
549            panic!("cell is not within given grid! cell:{self}, grid:{grid}")
550        }
551    }
552
553    /// Returns `global_width` field of `Cell`
554    ///
555    /// # Examples
556    ///
557    /// ```
558    /// use grid_math::Cell;
559    ///
560    /// let cell = Cell::new(8, 8);
561    /// let w = cell.global_width();
562    /// assert_eq!(w, 8);
563    /// ```
564    pub fn global_width(self) -> u8 {
565        self.global_width
566    }
567
568    /// Returns `global_depth` field of `Cell`
569    ///
570    /// # Examples
571    ///
572    /// ```
573    /// use grid_math::Cell;
574    ///
575    /// let cell = Cell::new(8, 8);
576    /// let d = cell.global_depth();
577    /// assert_eq!(d, 8);
578    /// ```
579    pub fn global_depth(self) -> u8 {
580        self.global_depth
581    }
582
583    /// Calculates the `width` of the `Cell` relative to the given `Grid`
584    /// `width` here means position / index / x of `Cell` on width axis
585    ///
586    /// # Panics
587    /// Panics if the `Cell` is not within the given `Grid`
588    ///
589    /// # Examples
590    ///
591    /// ```
592    /// use grid_math::{Cell, Grid};
593    ///
594    /// let cell = Cell::new(8, 8);
595    /// let grid = Grid::indented(7, 7, (4, 4)); // 7x7 grid starting at (4,4)
596    /// let width = cell.width(grid); // width = 4
597    /// assert_eq!(width, 4);
598    /// ```
599    pub fn width(self, grid: Grid) -> u8 {
600        self.within_panic(grid);
601        self.global_width - grid.start.global_width
602    }
603
604    /// Calculates the gap between the `width` of `Cell` and the `width` of `Grid`
605    ///
606    /// # Panics
607    /// Panics if the `Cell` is not within the given `Grid`
608    ///
609    /// # Examples
610    ///
611    /// ```
612    /// use grid_math::{Cell, Grid};
613    ///
614    /// let cell = Cell::new(8, 8);
615    /// let grid = Grid::indented(7, 7, (4, 4)); // 7x7 grid starting at (4,4)
616    /// let width_gap = cell.width_gap(grid); // width_gap = 2
617    /// assert_eq!(width_gap, 2);
618    /// ```
619    pub fn width_gap(self, grid: Grid) -> u8 {
620        self.within_panic(grid);
621        grid.end.global_width - self.global_width
622    }
623
624    /// Calculates the `depth` of `Cell` relative to the given `Grid`
625    /// `depth` here means position / index / y of `Cell` on depth axis
626    ///
627    /// # Panics
628    /// Panics if the `Cell` is not within the given `Grid`
629    ///
630    /// # Examples
631    ///
632    /// ```
633    /// use grid_math::{Cell, Grid};
634    ///
635    /// let cell = Cell::new(8, 8);
636    /// let grid = Grid::indented(7, 7, (4, 4)); // 7x7 grid starting at (4,4)
637    /// let depth = cell.depth(grid); // depth = 4
638    /// assert_eq!(depth, 4);
639    /// ```
640    pub fn depth(self, grid: Grid) -> u8 {
641        self.within_panic(grid);
642        self.global_depth - grid.start.global_depth
643    }
644
645    /// Calculates the gap between the `depth` of `Cell` and the `depth` of `Grid`
646    ///
647    /// # Panics
648    /// Panics if the `Cell` is not within the given `Grid`
649    ///
650    /// # Examples
651    ///
652    /// ```
653    /// use grid_math::{Cell, Grid};
654    ///
655    /// let cell = Cell::new(8, 8);
656    /// let grid = Grid::indented(7, 7, (4, 4)); // 7x7 grid starting at (4,4)
657    /// let depth_gap = cell.depth_gap(grid); // depth_gap = 2
658    /// assert_eq!(depth_gap, 2);
659    /// ```
660    pub fn depth_gap(self, grid: Grid) -> u8 {
661        self.within_panic(grid);
662        grid.end.global_depth - self.global_depth
663    }
664
665    /// Checks if the `up` operation on `Cell` will violate the given `Grid` upper border
666    ///
667    /// # Panics
668    /// Panics if the `Cell` is not within the given `Grid`
669    ///
670    /// # Examples
671    ///
672    /// ```
673    /// use grid_math::{Cell, Grid};
674    ///
675    /// let grid = Grid::new(10, 10);
676    /// let cell = Cell::new(2, 2);
677    /// assert!(cell.will_underflow_depth(grid, 3));
678    /// assert!(!cell.will_underflow_depth(grid, 2));
679    /// ```
680    pub fn will_underflow_depth(self, grid: Grid, step: u8) -> bool {
681        self.within_panic(grid);
682        self.global_depth < step || self.global_depth - step < grid.start.global_depth
683    }
684
685    /// Checks if the `down` operation on `Cell` will violate the given `Grid` lower border
686    ///
687    /// # Panics
688    /// Panics if the `Cell` is not within the given `Grid`
689    ///
690    /// # Examples
691    ///
692    /// ```
693    /// use grid_math::{Cell, Grid};
694    ///
695    /// let grid = Grid::new(10, 10);
696    /// let cell = Cell::new(7, 7);
697    /// assert!(cell.will_overflow_depth(grid, 3));
698    /// assert!(!cell.will_overflow_depth(grid, 2));
699    /// ```
700    pub fn will_overflow_depth(self, grid: Grid, step: u8) -> bool {
701        self.within_panic(grid);
702        self.global_depth > u8::MAX - step || self.global_depth + step > grid.end.global_depth
703    }
704
705    /// Checks if the `left` operation on `Cell` will violate the given `Grid` left border
706    ///
707    /// # Panics
708    /// Panics if the `Cell` is not within the given `Grid`
709    ///
710    /// # Examples
711    ///
712    /// ```
713    /// use grid_math::{Cell, Grid};
714    ///
715    /// let grid = Grid::new(10, 10);
716    /// let cell = Cell::new(2, 2);
717    /// assert!(cell.will_underflow_width(grid, 3));
718    /// assert!(!cell.will_underflow_width(grid, 2));
719    /// ```
720    pub fn will_underflow_width(self, grid: Grid, step: u8) -> bool {
721        self.within_panic(grid);
722        self.global_width < step || self.global_width - step < grid.start.global_width
723    }
724
725    /// Checks if the `right` operation on `Cell` will violate the given `Grid` right border
726    ///
727    /// # Panics
728    /// Panics if the `Cell` is not within the given `Grid`
729    ///
730    /// # Examples
731    ///
732    /// ```
733    /// use grid_math::{Cell, Grid};
734    ///
735    /// let grid = Grid::new(10, 10);
736    /// let cell = Cell::new(7, 7);
737    /// assert!(cell.will_overflow_width(grid, 3));
738    /// assert!(!cell.will_overflow_width(grid, 2));
739    /// ```
740    pub fn will_overflow_width(self, grid: Grid, step: u8) -> bool {
741        self.within_panic(grid);
742        self.global_width > u8::MAX - step || self.global_width + step > grid.end.global_width
743    }
744
745    /// Moves current `Cell` upwards by `step` relative to the given `Grid`
746    /// This operation does not mutate current `Cell` fields,
747    /// instead it calculates new position and returns new `Cell`
748    ///
749    /// # Panics
750    /// Panics if the `Cell` is not within the given `Grid`
751    /// Panics if this operation will violate the given `Grid` upper border
752    ///
753    /// # Examples
754    ///
755    /// ```
756    /// use grid_math::{Cell, Grid};
757    ///
758    /// let grid = Grid::new(10, 10);
759    /// let cell = Cell::new(2, 2);
760    /// let next = cell.strict_up(grid, 2);
761    /// assert_eq!(next, Cell::new(2, 0));
762    /// ```
763    ///
764    /// ```should_panic
765    /// use grid_math::{Cell, Grid};
766    ///
767    /// let grid = Grid::new(10, 10);
768    /// let cell = Cell::new(2, 2);
769    /// let next = cell.strict_up(grid, 3); // panic!
770    /// ```
771    pub fn strict_up(self, grid: Grid, step: u8) -> Cell {
772        if self.will_underflow_depth(grid, step) {
773            panic!(
774                "this operation will violate grid upper bounds! cell:{self}, grid:{grid}, step:{step}"
775            );
776        }
777        Cell {
778            global_width: self.global_width,
779            global_depth: self.global_depth - step,
780        }
781    }
782
783    /// Moves current `Cell` downwards by `step` relative to the given `Grid`
784    /// This operation does not mutate current `Cell` fields,
785    /// instead it calculates new position and returns new `Cell`
786    ///
787    /// # Panics
788    /// Panics if the `Cell` is not within the given `Grid`
789    /// Panics if this operation will violate the given `Grid` lower border
790    ///
791    /// # Examples
792    ///
793    /// ```
794    /// use grid_math::{Cell, Grid};
795    ///
796    /// let grid = Grid::new(10, 10);
797    /// let cell = Cell::new(7, 7);
798    /// let next = cell.strict_down(grid, 2);
799    /// assert_eq!(next, Cell::new(7, 9));
800    /// ```
801    ///
802    /// ```should_panic
803    /// use grid_math::{Cell, Grid};
804    ///
805    /// let grid = Grid::new(10, 10);
806    /// let cell = Cell::new(7, 7);
807    /// let next = cell.strict_down(grid, 3); // panic!
808    /// ```
809    pub fn strict_down(self, grid: Grid, step: u8) -> Cell {
810        if self.will_overflow_depth(grid, step) {
811            panic!(
812                "this operation will violate grid lower bounds! cell:{self}, grid:{grid}, step:{step}"
813            );
814        }
815        Cell {
816            global_width: self.global_width,
817            global_depth: self.global_depth + step,
818        }
819    }
820
821    /// Moves current `Cell` to the left by `step` relative to the given `Grid`
822    /// This operation does not mutate current `Cell` fields,
823    /// instead it calculates new position and returns new `Cell`
824    ///
825    /// # Panics
826    /// Panics if the `Cell` is not within the given `Grid`
827    /// Panics if this operation will violate the given `Grid` left border
828    ///
829    /// # Examples
830    ///
831    /// ```
832    /// use grid_math::{Cell, Grid};
833    ///
834    /// let grid = Grid::new(10, 10);
835    /// let cell = Cell::new(2, 2);
836    /// let next = cell.strict_left(grid, 2);
837    /// assert_eq!(next, Cell::new(0, 2));
838    /// ```
839    ///
840    /// ```should_panic
841    /// use grid_math::{Cell, Grid};
842    ///
843    /// let grid = Grid::new(10, 10);
844    /// let cell = Cell::new(2, 2);
845    /// let next = cell.strict_left(grid, 3); // panic!
846    /// ```
847    pub fn strict_left(self, grid: Grid, step: u8) -> Cell {
848        if self.will_underflow_width(grid, step) {
849            panic!(
850                "this operation will violate grid left bounds! cell:{self}, grid:{grid}, step:{step}"
851            );
852        }
853        Cell {
854            global_width: self.global_width - step,
855            global_depth: self.global_depth,
856        }
857    }
858
859    /// Moves current `Cell` to the right by `step` relative to the given `Grid`
860    /// This operation does not mutate current `Cell` fields,
861    /// instead it calculates new position and returns new `Cell`
862    ///
863    /// # Panics
864    /// Panics if the `Cell` is not within the given `Grid`
865    /// Panics if this operation will violate the given `Grid` right border
866    ///
867    /// # Examples
868    ///
869    /// ```
870    /// use grid_math::{Cell, Grid};
871    ///
872    /// let grid = Grid::new(10, 10);
873    /// let cell = Cell::new(7, 7);
874    /// let next = cell.strict_right(grid, 2);
875    /// assert_eq!(next, Cell::new(9, 7));
876    /// ```
877    ///
878    /// ```should_panic
879    /// use grid_math::{Cell, Grid};
880    ///
881    /// let grid = Grid::new(10, 10);
882    /// let cell = Cell::new(7, 7);
883    /// let next = cell.strict_right(grid, 3); // panic!
884    /// ```
885    pub fn strict_right(self, grid: Grid, step: u8) -> Cell {
886        if self.will_overflow_width(grid, step) {
887            panic!(
888                "this operation will violate grid right bounds! cell:{self}, grid:{grid}, step:{step}"
889            );
890        }
891        Cell {
892            global_width: self.global_width + step,
893            global_depth: self.global_depth,
894        }
895    }
896
897    /// Moves current `Cell` upwards by `step` relative to the given `Grid`
898    ///
899    /// This operation does not mutate current `Cell` fields,
900    /// instead it calculates new position and returns new `Cell`
901    ///
902    /// If this operation will cross `Grid` upper border,
903    /// returns `Cell` with `depth` = `Grid` upper depth limit
904    ///
905    /// # Panics
906    /// Panics if the `Cell` is not within the given `Grid`
907    ///
908    /// # Examples
909    ///
910    /// ```
911    /// use grid_math::{Cell, Grid};
912    ///
913    /// let grid = Grid::new(10, 10);
914    /// let cell = Cell::new(2, 2);
915    /// let next = cell.saturating_up(grid, 2);
916    /// assert_eq!(next, Cell::new(2, 0));
917    /// let next = cell.saturating_up(grid, 5);
918    /// assert_eq!(next, Cell::new(2, 0));
919    /// ```
920    pub fn saturating_up(self, grid: Grid, step: u8) -> Cell {
921        let next_depth = if self.will_underflow_depth(grid, step) {
922            grid.start.global_depth
923        } else {
924            self.global_depth - step
925        };
926        Cell {
927            global_width: self.global_width,
928            global_depth: next_depth,
929        }
930    }
931
932    /// Moves current `Cell` downwards by `step` relative to the given `Grid`
933    ///
934    /// This operation does not mutate current `Cell` fields,
935    /// instead it calculates new position and returns new `Cell`
936    ///
937    /// If this operation will cross `Grid` lower border,
938    /// returns `Cell` with `depth` = `Grid` lower depth limit
939    ///
940    /// # Panics
941    /// Panics if the `Cell` is not within the given `Grid`
942    ///
943    /// # Examples
944    ///
945    /// ```
946    /// use grid_math::{Cell, Grid};
947    ///
948    /// let grid = Grid::new(10, 10);
949    /// let cell = Cell::new(7, 7);
950    /// let next = cell.saturating_down(grid, 2);
951    /// assert_eq!(next, Cell::new(7, 9));
952    /// let next = cell.saturating_down(grid, 5);
953    /// assert_eq!(next, Cell::new(7, 9));
954    /// ```
955    pub fn saturating_down(self, grid: Grid, step: u8) -> Cell {
956        let next_depth = if self.will_overflow_depth(grid, step) {
957            grid.end.global_depth
958        } else {
959            self.global_depth + step
960        };
961        Cell {
962            global_width: self.global_width,
963            global_depth: next_depth,
964        }
965    }
966
967    /// Moves current `Cell` to the left by `step` relative to the given `Grid`
968    ///
969    /// This operation does not mutate current `Cell` fields,
970    /// instead it calculates new position and returns new `Cell`
971    ///
972    /// If this operation will cross `Grid` left border,
973    /// returns `Cell` with `width` = `Grid` left width limit
974    ///
975    /// # Panics
976    /// Panics if the `Cell` is not within the given `Grid`
977    ///
978    /// # Examples
979    ///
980    /// ```
981    /// use grid_math::{Cell, Grid};
982    ///
983    /// let grid = Grid::new(10, 10);
984    /// let cell = Cell::new(2, 2);
985    /// let next = cell.saturating_left(grid, 2);
986    /// assert_eq!(next, Cell::new(0, 2));
987    /// let next = cell.saturating_left(grid, 5);
988    /// assert_eq!(next, Cell::new(0, 2));
989    /// ```
990    pub fn saturating_left(self, grid: Grid, step: u8) -> Cell {
991        let next_width = if self.will_underflow_width(grid, step) {
992            grid.start.global_width
993        } else {
994            self.global_width - step
995        };
996        Cell {
997            global_width: next_width,
998            global_depth: self.global_depth,
999        }
1000    }
1001
1002    /// Moves current `Cell` to the right by `step` relative to the given `Grid`
1003    ///
1004    /// This operation does not mutate current `Cell` fields,
1005    /// instead it calculates new position and returns new `Cell`
1006    ///
1007    /// If this operation will cross `Grid` right border,
1008    /// returns `Cell` with `width` = `Grid` right width limit
1009    ///
1010    /// # Panics
1011    /// Panics if the `Cell` is not within the given `Grid`
1012    ///
1013    /// # Examples
1014    ///
1015    /// ```
1016    /// use grid_math::{Cell, Grid};
1017    ///
1018    /// let grid = Grid::new(10, 10);
1019    /// let cell = Cell::new(7, 7);
1020    /// let next = cell.saturating_right(grid, 2);
1021    /// assert_eq!(next, Cell::new(9, 7));
1022    /// let next = cell.saturating_right(grid, 5);
1023    /// assert_eq!(next, Cell::new(9, 7));
1024    /// ```
1025    pub fn saturating_right(self, grid: Grid, step: u8) -> Cell {
1026        let next_width = if self.will_overflow_width(grid, step) {
1027            grid.end.global_width
1028        } else {
1029            self.global_width + step
1030        };
1031        Cell {
1032            global_width: next_width,
1033            global_depth: self.global_depth,
1034        }
1035    }
1036
1037    /// Moves current `Cell` upwards by `step` relative to the given `Grid`
1038    ///
1039    /// This operation does not mutate current `Cell` fields,
1040    /// instead it calculates new position and returns new `Cell` and `bool`
1041    ///
1042    /// This operation is similar to the overflowing operations on integer types
1043    /// It returns new `Cell` and 'bool' signaling that overflow happened
1044    ///
1045    /// # Panics
1046    /// Panics if the `Cell` is not within the given `Grid`
1047    ///
1048    /// # Examples
1049    ///
1050    /// ```
1051    /// use grid_math::{Cell, Grid};
1052    ///
1053    /// let grid = Grid::new(10, 10);
1054    /// let cell = Cell::new(2, 2);
1055    /// let (next, overflowed) = cell.overflowing_up(grid, 2);
1056    /// assert_eq!((next, overflowed), (Cell::new(2, 0), false));
1057    /// let (next, overflowed) = cell.overflowing_up(grid, 5);
1058    /// assert_eq!((next, overflowed), (Cell::new(2, 7), true));
1059    /// ```
1060    pub fn overflowing_up(self, grid: Grid, step: u8) -> (Cell, bool) {
1061        let underflowed = self.will_underflow_depth(grid, step);
1062        let next_depth = if underflowed {
1063            grid.end.global_depth - ((step - self.depth(grid) - 1) % grid.depth())
1064        } else {
1065            self.global_depth - step
1066        };
1067        (
1068            Cell {
1069                global_width: self.global_width,
1070                global_depth: next_depth,
1071            },
1072            underflowed,
1073        )
1074    }
1075
1076    /// Moves current `Cell` downwards by `step` relative to the given `Grid`
1077    ///
1078    /// This operation does not mutate current `Cell` fields,
1079    /// instead it calculates new position and returns new `Cell` and `bool`
1080    ///
1081    /// This operation is similar to the overflowing operations on integer types
1082    /// It returns new `Cell` and 'bool' signaling that overflow happened
1083    ///
1084    /// # Panics
1085    /// Panics if the `Cell` is not within the given `Grid`
1086    ///
1087    /// # Examples
1088    ///
1089    /// ```
1090    /// use grid_math::{Cell, Grid};
1091    ///
1092    /// let grid = Grid::new(10, 10);
1093    /// let cell = Cell::new(7, 7);
1094    /// let (next, overflowed) = cell.overflowing_down(grid, 2);
1095    /// assert_eq!((next, overflowed), (Cell::new(7, 9), false));
1096    /// let (next, overflowed) = cell.overflowing_down(grid, 5);
1097    /// assert_eq!((next, overflowed), (Cell::new(7, 2), true));
1098    /// ```
1099    pub fn overflowing_down(self, grid: Grid, step: u8) -> (Cell, bool) {
1100        let overflowed = self.will_overflow_depth(grid, step);
1101        let next_depth = if overflowed {
1102            grid.start.global_depth + ((step - self.depth_gap(grid) - 1) % grid.depth())
1103        } else {
1104            self.global_depth + step
1105        };
1106        (
1107            Cell {
1108                global_width: self.global_width,
1109                global_depth: next_depth,
1110            },
1111            overflowed,
1112        )
1113    }
1114
1115    /// Moves current `Cell` to the left by `step` relative to the given `Grid`
1116    ///
1117    /// This operation does not mutate current `Cell` fields,
1118    /// instead it calculates new position and returns new `Cell` and `bool`
1119    ///
1120    /// This operation is similar to the overflowing operations on integer types
1121    /// It returns new `Cell` and 'bool' signaling that overflow happened
1122    ///
1123    /// # Panics
1124    /// Panics if the `Cell` is not within the given `Grid`
1125    ///
1126    /// # Examples
1127    ///
1128    /// ```
1129    /// use grid_math::{Cell, Grid};
1130    ///
1131    /// let grid = Grid::new(10, 10);
1132    /// let cell = Cell::new(2, 2);
1133    /// let (next, overflowed) = cell.overflowing_left(grid, 2);
1134    /// assert_eq!((next, overflowed), (Cell::new(0, 2), false));
1135    /// let (next, overflowed) = cell.overflowing_left(grid, 5);
1136    /// assert_eq!((next, overflowed), (Cell::new(7, 2), true));
1137    /// ```
1138    pub fn overflowing_left(self, grid: Grid, step: u8) -> (Cell, bool) {
1139        let underflowed = self.will_underflow_width(grid, step);
1140        let next_width = if underflowed {
1141            grid.end.global_width - ((step - self.width(grid) - 1) % grid.width())
1142        } else {
1143            self.global_width - step
1144        };
1145        (
1146            Cell {
1147                global_width: next_width,
1148                global_depth: self.global_depth,
1149            },
1150            underflowed,
1151        )
1152    }
1153
1154    /// Moves current `Cell` to the right by `step` relative to the given `Grid`
1155    ///
1156    /// This operation does not mutate current `Cell` fields,
1157    /// instead it calculates new position and returns new `Cell` and `bool`
1158    ///
1159    /// This operation is similar to the overflowing operations on integer types
1160    /// It returns new `Cell` and 'bool' signaling that overflow happened
1161    ///
1162    /// # Panics
1163    /// Panics if the `Cell` is not within the given `Grid`
1164    ///
1165    /// # Examples
1166    ///
1167    /// ```
1168    /// use grid_math::{Cell, Grid};
1169    ///
1170    /// let grid = Grid::new(10, 10);
1171    /// let cell = Cell::new(7, 7);
1172    /// let (next, overflowed) = cell.overflowing_right(grid, 2);
1173    /// assert_eq!((next, overflowed), (Cell::new(9, 7), false));
1174    /// let (next, overflowed) = cell.overflowing_right(grid, 5);
1175    /// assert_eq!((next, overflowed), (Cell::new(2, 7), true));
1176    /// ```
1177    pub fn overflowing_right(self, grid: Grid, step: u8) -> (Cell, bool) {
1178        let overflowed = self.will_overflow_width(grid, step);
1179        let next_width = if overflowed {
1180            grid.start.global_width + ((step - self.width_gap(grid) - 1) % grid.width())
1181        } else {
1182            self.global_width + step
1183        };
1184        (
1185            Cell {
1186                global_width: next_width,
1187                global_depth: self.global_depth,
1188            },
1189            overflowed,
1190        )
1191    }
1192
1193    /// Moves current `Cell` upwards by `step` relative to the given `Grid`
1194    ///
1195    /// This operation is a wrapper around the `overflowing_up()` method,
1196    /// and returns only new `Cell`, without `bool`
1197    ///
1198    /// # Panics
1199    /// Panics if the `Cell` is not within the given `Grid`
1200    ///
1201    /// # Examples
1202    ///
1203    /// ```
1204    /// use grid_math::{Cell, Grid};
1205    ///
1206    /// let grid = Grid::new(10, 10);
1207    /// let cell = Cell::new(2, 2);
1208    /// let next = cell.wrapping_up(grid, 2);
1209    /// assert_eq!(next, Cell::new(2, 0));
1210    /// let next = cell.wrapping_up(grid, 5);
1211    /// assert_eq!(next, Cell::new(2, 7));
1212    /// ```
1213    pub fn wrapping_up(self, grid: Grid, step: u8) -> Cell {
1214        self.overflowing_up(grid, step).0
1215    }
1216
1217    /// Moves current `Cell` downwards by `step` relative to the given `Grid`
1218    ///
1219    /// This operation is a wrapper around the `overflowing_down()` method,
1220    /// and returns only new `Cell`, without `bool`
1221    ///
1222    /// # Panics
1223    /// Panics if the `Cell` is not within the given `Grid`
1224    ///
1225    /// # Examples
1226    ///
1227    /// ```
1228    /// use grid_math::{Cell, Grid};
1229    ///
1230    /// let grid = Grid::new(10, 10);
1231    /// let cell = Cell::new(7, 7);
1232    /// let next = cell.wrapping_down(grid, 2);
1233    /// assert_eq!(next, Cell::new(7, 9));
1234    /// let next = cell.wrapping_down(grid, 5);
1235    /// assert_eq!(next, Cell::new(7, 2));
1236    /// ```
1237    pub fn wrapping_down(self, grid: Grid, step: u8) -> Cell {
1238        self.overflowing_down(grid, step).0
1239    }
1240
1241    /// Moves current `Cell` to the left by `step` relative to the given `Grid`
1242    ///
1243    /// This operation is a wrapper around the `overflowing_left()` method,
1244    /// and returns only new `Cell`, without `bool`
1245    ///
1246    /// # Panics
1247    /// Panics if the `Cell` is not within the given `Grid`
1248    ///
1249    /// # Examples
1250    ///
1251    /// ```
1252    /// use grid_math::{Cell, Grid};
1253    ///
1254    /// let grid = Grid::new(10, 10);
1255    /// let cell = Cell::new(2, 2);
1256    /// let next = cell.wrapping_left(grid, 2);
1257    /// assert_eq!(next, Cell::new(0, 2));
1258    /// let next = cell.wrapping_left(grid, 5);
1259    /// assert_eq!(next, Cell::new(7, 2));
1260    /// ```
1261    pub fn wrapping_left(self, grid: Grid, step: u8) -> Cell {
1262        self.overflowing_left(grid, step).0
1263    }
1264
1265    /// Moves current `Cell` to the right by `step` relative to the given `Grid`
1266    ///
1267    /// This operation is a wrapper around the `overflowing_right()` method,
1268    /// and returns only new `Cell`, without `bool`
1269    ///
1270    /// # Panics
1271    /// Panics if the `Cell` is not within the given `Grid`
1272    ///
1273    /// # Examples
1274    ///
1275    /// ```
1276    /// use grid_math::{Cell, Grid};
1277    ///
1278    /// let grid = Grid::new(10, 10);
1279    /// let cell = Cell::new(7, 7);
1280    /// let next = cell.wrapping_right(grid, 2);
1281    /// assert_eq!(next, Cell::new(9, 7));
1282    /// let next = cell.wrapping_right(grid, 5);
1283    /// assert_eq!(next, Cell::new(2, 7));
1284    /// ```
1285    pub fn wrapping_right(self, grid: Grid, step: u8) -> Cell {
1286        self.overflowing_right(grid, step).0
1287    }
1288
1289    /// Projects current `Cell` onto the top side of the given `Grid`
1290    ///
1291    /// This operation does not mutate current `Cell` fields,
1292    /// instead it calculates new position and returns new `Cell`
1293    ///
1294    /// # Panics
1295    /// Panics if the `Cell` is not within the given `Grid`
1296    ///
1297    /// # Examples
1298    ///
1299    /// ```
1300    /// use grid_math::{Cell, Grid};
1301    ///
1302    /// let grid = Grid::new(10, 10);
1303    /// let cell = Cell::new(2, 2);
1304    /// let next = cell.project_up(grid);
1305    /// assert_eq!(next, Cell::new(2, 0));
1306    /// ```
1307    pub fn project_up(self, grid: Grid) -> Cell {
1308        self.saturating_up(grid, u8::MAX)
1309    }
1310
1311    /// Projects current `Cell` onto the bottom side of the given `Grid`
1312    ///
1313    /// This operation does not mutate current `Cell` fields,
1314    /// instead it calculates new position and returns new `Cell`
1315    ///
1316    /// # Panics
1317    /// Panics if the `Cell` is not within the given `Grid`
1318    ///
1319    /// # Examples
1320    ///
1321    /// ```
1322    /// use grid_math::{Cell, Grid};
1323    ///
1324    /// let grid = Grid::new(10, 10);
1325    /// let cell = Cell::new(7, 7);
1326    /// let next = cell.project_down(grid);
1327    /// assert_eq!(next, Cell::new(7, 9));
1328    /// ```
1329    pub fn project_down(self, grid: Grid) -> Cell {
1330        self.saturating_down(grid, u8::MAX)
1331    }
1332
1333    /// Projects current `Cell` onto the left side of the given `Grid`
1334    ///
1335    /// This operation does not mutate current `Cell` fields,
1336    /// instead it calculates new position and returns new `Cell`
1337    ///
1338    /// # Panics
1339    /// Panics if the `Cell` is not within the given `Grid`
1340    ///
1341    /// # Examples
1342    ///
1343    /// ```
1344    /// use grid_math::{Cell, Grid};
1345    ///
1346    /// let grid = Grid::new(10, 10);
1347    /// let cell = Cell::new(2, 2);
1348    /// let next = cell.project_left(grid);
1349    /// assert_eq!(next, Cell::new(0, 2));
1350    /// ```
1351    pub fn project_left(self, grid: Grid) -> Cell {
1352        self.saturating_left(grid, u8::MAX)
1353    }
1354
1355    /// Projects current `Cell` onto the right side of the given `Grid`
1356    ///
1357    /// This operation does not mutate current `Cell` fields,
1358    /// instead it calculates new position and returns new `Cell`
1359    ///
1360    /// # Panics
1361    /// Panics if the `Cell` is not within the given `Grid`
1362    ///
1363    /// # Examples
1364    ///
1365    /// ```
1366    /// use grid_math::{Cell, Grid};
1367    ///
1368    /// let grid = Grid::new(10, 10);
1369    /// let cell = Cell::new(7, 7);
1370    /// let next = cell.project_right(grid);
1371    /// assert_eq!(next, Cell::new(9, 7));
1372    /// ```
1373    pub fn project_right(self, grid: Grid) -> Cell {
1374        self.saturating_right(grid, u8::MAX)
1375    }
1376}
1377
1378impl fmt::Display for Cell {
1379    /// implements display for `Cell`
1380    ///
1381    /// # Examples
1382    ///
1383    /// ```
1384    /// use grid_math::Cell;
1385    ///
1386    /// let cell = Cell::new(5, 6);
1387    /// assert_eq!(format!("{cell}"), "(5, 6)");
1388    /// ```
1389    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1390        write!(
1391            f,
1392            "({w}, {d})",
1393            w = self.global_width,
1394            d = self.global_depth
1395        )
1396    }
1397}
1398
1399impl From<(u8, u8)> for Cell {
1400    /// implements constructor for `Cell` from (u8, u8)
1401    ///
1402    /// # Examples
1403    ///
1404    /// ```
1405    /// use grid_math::Cell;
1406    ///
1407    /// let pos = (5, 6);
1408    /// let cell = Cell::from(pos);
1409    /// assert_eq!((pos.0, pos.1), (cell.global_width(), cell.global_depth()));
1410    /// ```
1411    fn from(value: (u8, u8)) -> Self {
1412        Self {
1413            global_width: value.0,
1414            global_depth: value.1,
1415        }
1416    }
1417}
1418
1419#[allow(clippy::from_over_into)]
1420impl Into<(u8, u8)> for Cell {
1421    /// implements conversion from `Cell` into (u8, u8)
1422    ///
1423    /// # Examples
1424    ///
1425    /// ```
1426    /// use grid_math::Cell;
1427    ///
1428    /// let cell = Cell::new(5, 6);
1429    /// let pos: (u8, u8) = cell.into();
1430    /// assert_eq!((pos.0, pos.1), (cell.global_width(), cell.global_depth()));
1431    /// ```
1432    fn into(self) -> (u8, u8) {
1433        (self.global_width, self.global_depth)
1434    }
1435}
1436
1437impl Grid {
1438    /// Creates new `Grid` with specified `width: u8` and `depth: u8`, starting at (0,0)
1439    ///
1440    /// # Panics
1441    /// Panics if `width` or `depth` parameters < 1
1442    ///
1443    /// # Examples
1444    ///
1445    /// ```
1446    /// use grid_math::Grid;
1447    ///
1448    /// let grid = Grid::new(10, 10);
1449    /// assert_eq!(format!("{grid}"), "[(0, 0):(9, 9)]");
1450    /// ```
1451    pub fn new(width: u8, depth: u8) -> Self {
1452        if width < 1 || depth < 1 {
1453            panic!("can't create grid with width < 0 or depth < 0!")
1454        }
1455        Self {
1456            start: Cell {
1457                global_width: 0,
1458                global_depth: 0,
1459            },
1460            end: Cell {
1461                global_width: width - 1,
1462                global_depth: depth - 1,
1463            },
1464        }
1465    }
1466
1467    /// Creates new `Grid` with specified `width: u8` and `depth: u8`, starting at indent
1468    ///
1469    /// # Panics
1470    /// Panics if `width` or `depth` parameters < 1
1471    ///
1472    /// # Examples
1473    ///
1474    /// ```
1475    /// use grid_math::{Grid, Cell};
1476    ///
1477    /// let grid = Grid::indented(5, 5, (2, 2));
1478    /// assert_eq!(format!("{grid}"), "[(2, 2):(6, 6)]");
1479    ///
1480    /// // use `Cell` as indent:
1481    /// let cell = Cell::new(2, 2);
1482    /// let grid = Grid::indented(5, 5, cell.into());
1483    /// assert_eq!(format!("{grid}"), "[(2, 2):(6, 6)]");
1484    /// ```
1485    pub fn indented(width: u8, depth: u8, indent: (u8, u8)) -> Self {
1486        if width < 1 || depth < 1 {
1487            panic!("can't create grid with width < 0 or depth < 0!")
1488        }
1489        Self {
1490            start: Cell {
1491                global_width: indent.0,
1492                global_depth: indent.1,
1493            },
1494            end: Cell {
1495                global_width: indent.0 + width - 1,
1496                global_depth: indent.1 + depth - 1,
1497            },
1498        }
1499    }
1500
1501    /// Checks if the `Grid` is within the another `Grid`
1502    ///
1503    /// # Examples
1504    ///
1505    /// ```
1506    /// use grid_math::Grid;
1507    ///
1508    /// let grid = Grid::new(10, 10);
1509    /// let subgrid = grid.area(5, 5);
1510    /// assert!(subgrid.within(grid));
1511    ///
1512    /// let subgrid = Grid::new(10, 12);
1513    /// assert!(!subgrid.within(grid));
1514    /// ```
1515    pub fn within(self, grid: Grid) -> bool {
1516        self.start.within(grid) && self.end.within(grid)
1517    }
1518
1519    /// Checks if the `Grid` is within the another `Grid`
1520    ///
1521    /// # Panics
1522    /// Panics if the `Grid` is not within the another `Grid`
1523    ///
1524    /// # Examples
1525    ///
1526    /// ```should_panic
1527    /// use grid_math::Grid;
1528    ///
1529    /// let grid = Grid::new(10, 10);
1530    /// let subgrid = Grid::new(10, 12);
1531    /// subgrid.within_panic(grid);
1532    /// ```
1533    pub fn within_panic(self, grid: Grid) {
1534        if !self.within(grid) {
1535            panic!("subgrid is not within given grid! subgrid:{self}, grid:{grid}")
1536        }
1537    }
1538
1539    /// Returns new `Cell` by `width: u8` and `depth: u8` relative to the current `Grid`
1540    ///
1541    /// # Panics
1542    /// Panics if `width` or `depth` of the requested member exceeds borders of the current `Grid`
1543    ///
1544    /// # Examples
1545    ///
1546    /// ```
1547    /// use grid_math::{Grid, Cell};
1548    ///
1549    /// let grid = Grid::indented(5, 5, (2, 2)); // 5x5 grid, starting at (2,2)
1550    /// let member = grid.member(4, 4);
1551    /// assert_eq!(member, Cell::new(6, 6));
1552    /// ```
1553    pub fn member(self, width: u8, depth: u8) -> Cell {
1554        self.start
1555            .strict_right(self, width)
1556            .strict_down(self, depth)
1557    }
1558
1559    /// Returns new `Grid` with `width: u8` and `depth: u8`, which is a subgrid
1560    /// of current `Grid`, starting at current `Grid` start
1561    ///
1562    /// # Panics
1563    /// Panics if `width` or `depth` parameters < 1
1564    /// Panics if `width` or `depth` of the requested area exceeds borders of the current `Grid`
1565    ///
1566    /// # Examples
1567    ///
1568    /// ```
1569    /// use grid_math::{Grid, Cell};
1570    ///
1571    /// let grid = Grid::indented(5, 5, (2, 2)); // 5x5 grid, starting at (2,2)
1572    /// let area = grid.area(3, 3);
1573    /// assert_eq!(format!("{area}"), "[(2, 2):(4, 4)]");
1574    /// ```
1575    pub fn area(self, width: u8, depth: u8) -> Grid {
1576        if width < 1 || depth < 1 {
1577            panic!("can't create grid with width < 0 or depth < 0!")
1578        }
1579        Grid {
1580            start: self.start,
1581            end: self
1582                .start
1583                .strict_right(self, width - 1)
1584                .strict_down(self, depth - 1),
1585        }
1586    }
1587
1588    /// Returns new `Grid` with `width: u8` and `depth: u8`, which is a subgrid
1589    /// of current `Grid`, starting at current `Grid` start + indent
1590    ///
1591    /// # Panics
1592    /// Panics if `width` or `depth` parameters < 1
1593    /// Panics if `width` or `depth` of the requested slice exceeds borders of the current `Grid`
1594    /// Panics if `indent` of the requested slice exceeds borders of the current `Grid`
1595    ///
1596    /// # Examples
1597    ///
1598    /// ```
1599    /// use grid_math::{Grid, Cell};
1600    ///
1601    /// let grid = Grid::new(10, 10);
1602    /// let slice = grid.slice(3, 3, (2, 2));
1603    /// assert_eq!(format!("{slice}"), "[(2, 2):(4, 4)]");
1604    ///
1605    /// // use `Cell` as indent:
1606    /// let cell = Cell::new(2, 2);
1607    /// let slice = grid.slice(3, 3, cell.into());
1608    /// assert_eq!(format!("{slice}"), "[(2, 2):(4, 4)]");
1609    /// ```
1610    pub fn slice(self, width: u8, depth: u8, indent: (u8, u8)) -> Grid {
1611        if width < 1 || depth < 1 {
1612            panic!("can't create grid with width < 0 or depth < 0!")
1613        }
1614        Grid {
1615            start: self
1616                .start
1617                .strict_right(self, indent.0)
1618                .strict_down(self, indent.1),
1619            end: self
1620                .start
1621                .strict_right(self, indent.0 + width - 1)
1622                .strict_down(self, indent.1 + depth - 1),
1623        }
1624    }
1625
1626    /// Returns `start` cell of `Grid`
1627    ///
1628    /// # Examples
1629    ///
1630    /// ```
1631    /// use grid_math::{Grid, Cell};
1632    ///
1633    /// let grid = Grid::new(10, 10);
1634    /// let start = grid.start();
1635    /// assert_eq!(start, Cell::new(0, 0));
1636    /// ```
1637    pub fn start(self) -> Cell {
1638        self.start
1639    }
1640
1641    /// Returns `end` cell of `Grid`
1642    ///
1643    /// # Examples
1644    ///
1645    /// ```
1646    /// use grid_math::{Grid, Cell};
1647    ///
1648    /// let grid = Grid::new(10, 10);
1649    /// let end = grid.end();
1650    /// assert_eq!(end, Cell::new(9, 9));
1651    /// ```
1652    pub fn end(self) -> Cell {
1653        self.end
1654    }
1655
1656    /// Calculates `width` of `Grid`
1657    ///
1658    /// # Examples
1659    ///
1660    /// ```
1661    /// use grid_math::Grid;
1662    ///
1663    /// let grid = Grid::new(10, 10);
1664    /// let width = grid.width();
1665    /// assert_eq!(width, 10);
1666    /// ```
1667    pub fn width(self) -> u8 {
1668        self.end.global_width - self.start.global_width + 1
1669    }
1670
1671    /// Calculates `depth` of `Grid`
1672    ///
1673    /// # Examples
1674    ///
1675    /// ```
1676    /// use grid_math::Grid;
1677    ///
1678    /// let grid = Grid::new(10, 10);
1679    /// let depth = grid.depth();
1680    /// assert_eq!(depth, 10);
1681    /// ```
1682    pub fn depth(self) -> u8 {
1683        self.end.global_depth - self.start.global_depth + 1
1684    }
1685
1686    /// Calculates `size: u16` of `Grid`
1687    ///
1688    /// # Examples
1689    ///
1690    /// ```
1691    /// use grid_math::Grid;
1692    ///
1693    /// let grid = Grid::new(10, 10);
1694    /// let size = grid.size();
1695    /// assert_eq!(size, 100);
1696    /// ```
1697    pub fn size(self) -> u16 {
1698        self.width() as u16 * self.depth() as u16
1699    }
1700
1701    /// Returns `Cells`, which is an iterator over every cell of the `Grid`
1702    ///
1703    /// # Examples
1704    ///
1705    /// Get every `Cell` on `width` and `depth` axis:
1706    /// ```
1707    /// use grid_math::{Cell, Grid};
1708    ///
1709    /// let grid = Grid::new(3, 3);
1710    ///
1711    /// let axis_cells: Vec<Cell> = grid
1712    ///     .cells()
1713    ///     .filter(|cell| {
1714    ///         cell.global_width() == grid.start().global_width() || cell.global_depth() == grid.start().global_depth()
1715    ///     })
1716    ///     .collect();
1717    /// assert_eq!(axis_cells, vec![
1718    ///     Cell::new(0, 0),
1719    ///     Cell::new(1, 0),
1720    ///     Cell::new(2, 0),
1721    ///     Cell::new(0, 1),
1722    ///     Cell::new(0, 2),
1723    /// ]);
1724    /// ```
1725    pub fn cells(self) -> Cells {
1726        Cells::from(self)
1727    }
1728
1729    /// Returns `Rows`, which is an iterator over every row of the `Grid`
1730    ///
1731    /// # Examples
1732    ///
1733    /// Print out `Grid` in custom format:
1734    /// ```
1735    /// use grid_math::{Cell, Grid};
1736    ///
1737    /// let grid = Grid::new(3, 3);
1738    /// let grid_string = grid
1739    ///     .rows()
1740    ///     .map(|row| {
1741    ///         row.cells().map(|_| " [#]")
1742    ///             .chain(std::iter::once("\n\n"))
1743    ///             .collect::<String>()
1744    ///     })
1745    ///     .collect::<String>();
1746    /// assert_eq!(grid_string,
1747    /// " \
1748    ///  [#] [#] [#]
1749    ///
1750    ///  [#] [#] [#]
1751    ///
1752    ///  [#] [#] [#]
1753    ///
1754    /// "
1755    /// );
1756    /// ```
1757    pub fn rows(self) -> Rows {
1758        Rows::from(self)
1759    }
1760
1761    /// Returns `Columns`, which is an iterator over every column of the `Grid`
1762    ///
1763    /// # Examples
1764    ///
1765    /// Get every `Cell` on the first column of `Grid`:
1766    /// ```
1767    /// use grid_math::{Cell, Grid};
1768    ///
1769    /// let grid = Grid::new(3, 3);
1770    ///
1771    /// let first_column_cells: Vec<Cell> = grid
1772    ///     .columns()
1773    ///     .next()
1774    ///     .unwrap()
1775    ///     .cells()
1776    ///     .collect();
1777    ///
1778    /// assert_eq!(first_column_cells, vec![
1779    ///     Cell::new(0, 0),
1780    ///     Cell::new(0, 1),
1781    ///     Cell::new(0, 2),
1782    /// ]);
1783    /// ```
1784    pub fn columns(self) -> Columns {
1785        Columns::from(self)
1786    }
1787}
1788
1789impl From<(Cell, Cell)> for Grid {
1790    /// implements constructor for `Grid` from (Cell, Cell)
1791    ///
1792    /// # Examples
1793    ///
1794    /// ```
1795    /// use grid_math::{Cell, Grid};
1796    ///
1797    /// let cells = (Cell::new(2, 2), Cell::new(5, 5));
1798    /// let grid = Grid::from(cells);
1799    /// assert_eq!((cells.0, cells.1), (grid.start(), grid.end()));
1800    /// ```
1801    fn from(value: (Cell, Cell)) -> Self {
1802        let (start, end) = value;
1803        if start.global_width > end.global_width || start.global_depth > end.global_depth {
1804            panic!("start cell overflows end cell! start:{start}, end:{end}")
1805        }
1806        Self { start, end }
1807    }
1808}
1809
1810#[allow(clippy::from_over_into)]
1811impl Into<(Cell, Cell)> for Grid {
1812    /// implements conversion from `Grid` into (Cell, Cell)
1813    ///
1814    /// # Examples
1815    ///
1816    /// ```
1817    /// use grid_math::{Cell, Grid};
1818    ///
1819    /// let grid = Grid::new(5, 5);
1820    /// let cells: (Cell, Cell) = grid.into();
1821    /// assert_eq!((cells.0, cells.1), (grid.start(), grid.end()));
1822    /// ```
1823    fn into(self) -> (Cell, Cell) {
1824        (self.start, self.end)
1825    }
1826}
1827
1828impl From<((u8, u8), (u8, u8))> for Grid {
1829    /// implements constructor for `Grid` from ((u8, u8), (u8, u8))
1830    ///
1831    /// # Examples
1832    ///
1833    /// ```
1834    /// use grid_math::{Cell, Grid};
1835    ///
1836    /// let vals = ((2, 2), (5, 5));
1837    /// let grid = Grid::from(vals);
1838    /// assert_eq!((Cell::from(vals.0), Cell::from(vals.1)), (grid.start(), grid.end()));
1839    /// ```
1840    fn from(value: ((u8, u8), (u8, u8))) -> Self {
1841        let (start, end): (Cell, Cell) = (value.0.into(), value.1.into());
1842        if start.global_width > end.global_width || start.global_depth > end.global_depth {
1843            panic!("start cell overflows end cell! start:{start}, end:{end}")
1844        }
1845        Self { start, end }
1846    }
1847}
1848
1849#[allow(clippy::from_over_into)]
1850impl Into<((u8, u8), (u8, u8))> for Grid {
1851    /// implements conversion from `Grid` into ((u8, u8), (u8, u8))
1852    ///
1853    /// # Examples
1854    ///
1855    /// ```
1856    /// use grid_math::{Cell, Grid};
1857    ///
1858    /// let grid = Grid::new(5, 5);
1859    /// let vals: ((u8, u8), (u8, u8)) = grid.into();
1860    /// assert_eq!((Cell::from(vals.0), Cell::from(vals.1)), (grid.start(), grid.end()));
1861    /// ```
1862    fn into(self) -> ((u8, u8), (u8, u8)) {
1863        (self.start.into(), self.end.into())
1864    }
1865}
1866
1867impl fmt::Display for Grid {
1868    /// implements display for `Grid`
1869    ///
1870    /// # Examples
1871    ///
1872    /// ```
1873    /// use grid_math::Grid;
1874    ///
1875    /// let grid = Grid::new(5, 6);
1876    /// assert_eq!(format!("{grid}"), "[(0, 0):(4, 5)]");
1877    /// ```
1878    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1879        write!(f, "[{start}:{end}]", start = self.start, end = self.end)
1880    }
1881}
1882
1883impl From<Grid> for Cells {
1884    /// Creates new iterator over every `Cell` on the `Grid`
1885    ///
1886    /// # Examples:
1887    ///
1888    /// ```
1889    /// use grid_math::{Grid, Cells};
1890    ///
1891    /// let grid = Grid::new(5, 5);
1892    /// let cells = Cells::from(grid);
1893    /// ```
1894    fn from(grid: Grid) -> Self {
1895        Self {
1896            grid,
1897            current: grid.start,
1898            consumed: false,
1899        }
1900    }
1901}
1902
1903impl From<Grid> for Columns {
1904    /// Creates new iterator over every column on the `Grid`
1905    ///
1906    /// # Examples:
1907    ///
1908    /// ```
1909    /// use grid_math::{Grid, Columns};
1910    ///
1911    /// let grid = Grid::new(5, 5);
1912    /// let columns = Columns::from(grid);
1913    /// ```
1914    fn from(grid: Grid) -> Self {
1915        Self {
1916            grid,
1917            current: Grid {
1918                start: grid.start,
1919                end: grid.start.project_down(grid),
1920            },
1921            consumed: false,
1922        }
1923    }
1924}
1925
1926impl From<Grid> for Rows {
1927    /// Creates new iterator over every row on the `Grid`
1928    ///
1929    /// # Examples:
1930    ///
1931    /// ```
1932    /// use grid_math::{Grid, Rows};
1933    ///
1934    /// let grid = Grid::new(5, 5);
1935    /// let rows = Rows::from(grid);
1936    /// ```
1937    fn from(grid: Grid) -> Self {
1938        Self {
1939            grid,
1940            current: Grid {
1941                start: grid.start,
1942                end: grid.start.project_right(grid),
1943            },
1944            consumed: false,
1945        }
1946    }
1947}
1948
1949impl Iterator for Cells {
1950    type Item = Cell;
1951    fn next(&mut self) -> Option<Self::Item> {
1952        if self.consumed {
1953            return None;
1954        }
1955        if self.current == self.grid.end {
1956            self.consumed = true;
1957            return Some(self.current);
1958        }
1959        let previous = self.current;
1960        match self.current.overflowing_right(self.grid, 1) {
1961            (next, true) => self.current = next.wrapping_down(self.grid, 1),
1962            (next, false) => self.current = next,
1963        }
1964        Some(previous)
1965    }
1966}
1967
1968impl Iterator for Columns {
1969    type Item = Grid;
1970    fn next(&mut self) -> Option<Self::Item> {
1971        if self.consumed {
1972            return None;
1973        }
1974        if self.current.end == self.grid.end {
1975            self.consumed = true;
1976            return Some(self.current);
1977        }
1978        let previous = self.current;
1979        self.current = Grid {
1980            start: self.current.start.saturating_right(self.grid, 1),
1981            end: self.current.end.saturating_right(self.grid, 1),
1982        };
1983        Some(previous)
1984    }
1985}
1986
1987impl Iterator for Rows {
1988    type Item = Grid;
1989    fn next(&mut self) -> Option<Self::Item> {
1990        if self.consumed {
1991            return None;
1992        }
1993        if self.current.end == self.grid.end {
1994            self.consumed = true;
1995            return Some(self.current);
1996        }
1997        let previous = self.current;
1998        self.current = Grid {
1999            start: self.current.start.saturating_down(self.grid, 1),
2000            end: self.current.end.saturating_down(self.grid, 1),
2001        };
2002        Some(previous)
2003    }
2004}
2005
2006impl<V> From<Grid> for GridMap<V> {
2007    /// Creates new `GridMap` from the given `Grid` with empty `HashMap<Cell, T>`
2008    ///
2009    /// # Examples:
2010    ///
2011    /// ```
2012    /// use grid_math::{Grid, GridMap};
2013    ///
2014    /// let grid = Grid::new(5, 5);
2015    /// let map: GridMap<char> = GridMap::from(grid);
2016    /// ```
2017    fn from(grid: Grid) -> Self {
2018        Self {
2019            grid,
2020            hashmap: HashMap::new(),
2021        }
2022    }
2023}
2024
2025impl<V> GridMap<V> {
2026    /// Shadows `insert` method from the `HashMap`, and reimplements it
2027    /// so it checks first if the key (`Cell`) is within the `Grid`, and then inserts it into the `HashMap`.
2028    /// This method currently has bad error handling, but this may change in the future
2029    ///
2030    /// # Panics
2031    /// Panics, if the key (`Cell`) is not within the inner `Grid`
2032    ///
2033    /// # Examples:
2034    ///
2035    /// ```
2036    /// use grid_math::{Grid, GridMap};
2037    ///
2038    /// let grid = Grid::new(5, 5);
2039    /// let mut map: GridMap<char> = GridMap::from(grid);
2040    /// map.insert(map.grid().start(), '#');
2041    /// map.insert(map.grid().end(), '@');
2042    /// assert_eq!(map.len(), 2);
2043    /// ```
2044    ///
2045    /// ```should_panic
2046    /// use grid_math::{Cell, Grid, GridMap};
2047    ///
2048    /// let grid = Grid::new(5, 5);
2049    /// let cell = Cell::new(6, 6);
2050    /// let mut map: GridMap<char> = GridMap::from(grid);
2051    /// map.insert(cell, '#'); // panic!
2052    /// ```
2053    pub fn insert(&mut self, cell: Cell, value: V) -> Option<V> {
2054        cell.within_panic(self.grid);
2055        self.hashmap.insert(cell, value)
2056    }
2057
2058    /// Returns the inner `Grid`
2059    ///
2060    /// # Examples:
2061    ///
2062    /// ```
2063    /// use grid_math::{Grid, GridMap};
2064    ///
2065    /// let grid = Grid::new(5, 5);
2066    /// let map: GridMap<char> = GridMap::from(grid);
2067    ///
2068    /// assert_eq!(grid, map.grid());
2069    /// ```
2070    pub fn grid(&self) -> Grid {
2071        self.grid
2072    }
2073}
2074
2075/// Implements `Deref` trait for GridMap, to return ref to the inner `HashMap`,
2076/// so we can call methods from `HashMap` directly on the `GridMap`
2077///
2078/// # Examples:
2079///
2080/// ```
2081/// use grid_math::{Grid, GridMap};
2082///
2083/// let grid = Grid::new(5, 5);
2084/// let mut map: GridMap<char> = GridMap::from(grid);
2085/// map.insert(map.grid().start(), '#');
2086///
2087/// assert_eq!(map.len(), 1);
2088/// ```
2089impl<V> Deref for GridMap<V> {
2090    type Target = HashMap<Cell, V>;
2091    fn deref(&self) -> &Self::Target {
2092        &self.hashmap
2093    }
2094}
2095
2096/// Implements `DerefMut` trait for GridMap, to return mut ref to the inner `HashMap`,
2097/// so we can call methods from `HashMap` directly on the `GridMap`
2098///
2099/// # Examples:
2100///
2101/// ```
2102/// use grid_math::{Grid, GridMap};
2103///
2104/// let grid = Grid::new(5, 5);
2105/// let mut map: GridMap<char> = GridMap::from(grid);
2106/// map.insert(map.grid().start(), '#');
2107///
2108/// assert_eq!(map.len(), 1);
2109/// ```
2110impl<V> DerefMut for GridMap<V> {
2111    fn deref_mut(&mut self) -> &mut Self::Target {
2112        &mut self.hashmap
2113    }
2114}
2115
2116// 🦀!⭐!!!