use crate::error::ParseError;
use crate::side::Side;
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Letter(u8);
impl Letter {
pub const ALL: [Self; 26] = [
Self(b'A'),
Self(b'B'),
Self(b'C'),
Self(b'D'),
Self(b'E'),
Self(b'F'),
Self(b'G'),
Self(b'H'),
Self(b'I'),
Self(b'J'),
Self(b'K'),
Self(b'L'),
Self(b'M'),
Self(b'N'),
Self(b'O'),
Self(b'P'),
Self(b'Q'),
Self(b'R'),
Self(b'S'),
Self(b'T'),
Self(b'U'),
Self(b'V'),
Self(b'W'),
Self(b'X'),
Self(b'Y'),
Self(b'Z'),
];
#[must_use]
pub const fn from_ascii(byte: u8) -> Option<(Self, Side)> {
match byte {
b'A'..=b'Z' => Some((Self(byte), Side::First)),
b'a'..=b'z' => Some((Self(byte - 32), Side::Second)),
_ => None,
}
}
#[allow(clippy::cast_possible_truncation)] pub const fn try_from_char(c: char) -> Result<Self, ParseError> {
match c {
'A'..='Z' => Ok(Self(c as u8)),
'a'..='z' => Ok(Self(c as u8 - 32)),
_ => Err(ParseError::InvalidLetter),
}
}
#[must_use]
pub const fn as_char(self) -> char {
self.0 as char
}
#[must_use]
pub const fn as_ascii(self) -> u8 {
self.0
}
#[must_use]
pub(crate) const fn to_ascii(self, side: Side) -> u8 {
match side {
Side::First => self.0,
Side::Second => self.0 + 32,
}
}
}
impl TryFrom<char> for Letter {
type Error = ParseError;
fn try_from(c: char) -> Result<Self, Self::Error> {
Self::try_from_char(c)
}
}
impl core::fmt::Debug for Letter {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "Letter({:?})", self.as_char())
}
}