1
// This file is part of hnefatafl-copenhagen.
2
//
3
// hnefatafl-copenhagen is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU Affero General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// hnefatafl-copenhagen is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU Affero General Public License for more details.
12
//
13
// You should have received a copy of the GNU Affero General Public License
14
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
15

            
16
use std::fmt;
17

            
18
use serde::{Deserialize, Serialize};
19

            
20
use crate::role::Role;
21

            
22
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
23
pub enum Space {
24
    Empty,
25
    Attacker,
26
    King,
27
    Defender,
28
}
29

            
30
impl Space {
31
    #[must_use]
32
    pub fn display_ascii(&self) -> &str {
33
        match self {
34
            Self::Attacker => "A",
35
            Self::Empty => ".",
36
            Self::King => "K",
37
            Self::Defender => "D",
38
        }
39
    }
40
}
41

            
42
impl TryFrom<char> for Space {
43
    type Error = anyhow::Error;
44

            
45
14994606
    fn try_from(value: char) -> anyhow::Result<Self> {
46
14994606
        match value {
47
2962404
            'X' => Ok(Self::Attacker),
48
1481328
            'O' => Ok(Self::Defender),
49
10427124
            '.' => Ok(Self::Empty),
50
123750
            'K' => Ok(Self::King),
51
            ch => Err(anyhow::Error::msg(format!(
52
                "Error trying to convert '{ch}' to a Space!"
53
            ))),
54
        }
55
14994606
    }
56
}
57

            
58
impl fmt::Display for Space {
59
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60
        match self {
61
            Self::Attacker => write!(f, "♟"),
62
            Self::Empty => write!(f, "."),
63
            Self::King => write!(f, "♔"),
64
            Self::Defender => write!(f, "♙"),
65
        }
66
    }
67
}
68

            
69
impl From<Space> for Role {
70
361426336
    fn from(space: Space) -> Self {
71
361426336
        match space {
72
110987198
            Space::Attacker => Role::Attacker,
73
30024340
            Space::Defender | Space::King => Role::Defender,
74
220414798
            Space::Empty => Role::Roleless,
75
        }
76
361426336
    }
77
}
78

            
79
impl TryFrom<Space> for usize {
80
    type Error = anyhow::Error;
81

            
82
    fn try_from(space: Space) -> Result<usize, anyhow::Error> {
83
        match space {
84
            Space::Attacker => Ok(0),
85
            Space::Defender => Ok(1),
86
            Space::King => Ok(2),
87
            Space::Empty => Err(anyhow::Error::msg(
88
                "we should not try to get a usize for an empty space",
89
            )),
90
        }
91
    }
92
}