sweeprs/
cell.rs

1/// Indicate what the mine contain
2#[derive(Clone)]
3pub enum CellKind {
4    Mine,
5    Free,
6    Uninitialized,
7}
8
9/// Hold the state of the cell
10#[derive(Clone)]
11pub enum CellState {
12    Closed,
13    Flagged,
14    Opened,
15}
16
17/// Default cell struct
18#[derive(Clone)]
19pub struct Cell {
20    pub kind: CellKind,
21    pub state: CellState,
22}
23
24/// Cell trait
25pub trait SweeperCell {
26    fn open(&mut self) -> &CellKind;
27
28    fn flag(&mut self) -> &CellState;
29}
30
31/// Default implementation of the cell trait
32impl SweeperCell for Cell {
33    fn open(&mut self) -> &CellKind {
34        if let CellState::Closed = self.state {
35            self.state = CellState::Opened
36        }
37        &self.kind
38    }
39
40    fn flag(&mut self) -> &CellState {
41        match self.state {
42            CellState::Closed => self.state = CellState::Flagged,
43            CellState::Flagged => self.state = CellState::Closed,
44            _ => (),
45        }
46        &self.state
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    macro_rules! test_board_cell_trait {
55        ($func_name:ident, $state:expr, $func:ident, $expected:pat) => {
56            #[test]
57            fn $func_name() {
58                let mut cell = Cell {
59                    kind: CellKind::Free,
60                    state: $state,
61                };
62                cell.$func();
63                assert!(matches!(cell.state, $expected));
64            }
65        };
66    }
67
68    test_board_cell_trait!(open_closed, CellState::Closed, open, CellState::Opened);
69    test_board_cell_trait!(open_flagged, CellState::Flagged, open, CellState::Flagged);
70    test_board_cell_trait!(open_opened, CellState::Opened, open, CellState::Opened);
71    test_board_cell_trait!(flag_closed, CellState::Closed, flag, CellState::Flagged);
72    test_board_cell_trait!(flag_flagged, CellState::Flagged, flag, CellState::Closed);
73    test_board_cell_trait!(flag_opened, CellState::Opened, flag, CellState::Opened);
74}