use crate::encode::EncodedPin;
use crate::error::ParseError;
use crate::letter::Letter;
use crate::side::Side;
use crate::state::State;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Identifier {
letter: Letter,
side: Side,
state: State,
terminal: bool,
}
impl Identifier {
#[must_use]
pub const fn new(letter: Letter, side: Side, state: State, terminal: bool) -> Self {
Self {
letter,
side,
state,
terminal,
}
}
pub const fn parse(input: &str) -> Result<Self, ParseError> {
crate::parse::parse(input)
}
#[must_use]
pub const fn is_valid(input: &str) -> bool {
Self::parse(input).is_ok()
}
#[must_use]
pub fn encode(self) -> EncodedPin {
EncodedPin::from_identifier(self)
}
#[must_use]
pub const fn letter(self) -> Letter {
self.letter
}
#[must_use]
pub const fn side(self) -> Side {
self.side
}
#[must_use]
pub const fn state(self) -> State {
self.state
}
#[must_use]
pub const fn is_terminal(self) -> bool {
self.terminal
}
#[must_use]
pub const fn is_normal(self) -> bool {
matches!(self.state, State::Normal)
}
#[must_use]
pub const fn is_enhanced(self) -> bool {
matches!(self.state, State::Enhanced)
}
#[must_use]
pub const fn is_diminished(self) -> bool {
matches!(self.state, State::Diminished)
}
#[must_use]
pub const fn is_first(self) -> bool {
matches!(self.side, Side::First)
}
#[must_use]
pub const fn is_second(self) -> bool {
matches!(self.side, Side::Second)
}
#[must_use]
pub const fn with_letter(self, letter: Letter) -> Self {
Self::new(letter, self.side, self.state, self.terminal)
}
#[must_use]
pub const fn with_side(self, side: Side) -> Self {
Self::new(self.letter, side, self.state, self.terminal)
}
#[must_use]
pub const fn with_state(self, state: State) -> Self {
Self::new(self.letter, self.side, state, self.terminal)
}
#[must_use]
pub const fn with_terminal(self, terminal: bool) -> Self {
Self::new(self.letter, self.side, self.state, terminal)
}
#[must_use]
pub const fn enhanced(self) -> Self {
self.with_state(State::Enhanced)
}
#[must_use]
pub const fn diminished(self) -> Self {
self.with_state(State::Diminished)
}
#[must_use]
pub const fn normalized(self) -> Self {
self.with_state(State::Normal)
}
#[must_use]
pub const fn flipped(self) -> Self {
self.with_side(self.side.flip())
}
}
impl core::fmt::Display for Identifier {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.encode().as_str())
}
}
impl core::str::FromStr for Identifier {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::parse(s)
}
}
impl TryFrom<&str> for Identifier {
type Error = ParseError;
fn try_from(s: &str) -> Result<Self, Self::Error> {
Self::parse(s)
}
}
impl TryFrom<&[u8]> for Identifier {
type Error = ParseError;
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
crate::parse::parse_bytes(bytes)
}
}