diff --git a/mino/src/srs.rs b/mino/src/srs.rs index 4484b3b..9a853a7 100644 --- a/mino/src/srs.rs +++ b/mino/src/srs.rs @@ -45,6 +45,76 @@ impl Spawn for PieceType { } } +impl PieceType { + /// Returns the name of the piece as a string. + pub fn name(self) -> &'static str { + match self { + PieceType::I => "I", + PieceType::J => "J", + PieceType::L => "L", + PieceType::O => "O", + PieceType::S => "S", + PieceType::T => "T", + PieceType::Z => "Z", + } + } + + /// Returns the name of the piece as a [`char`]. + pub fn as_char(self) -> char { + match self { + PieceType::I => 'I', + PieceType::J => 'J', + PieceType::L => 'L', + PieceType::O => 'O', + PieceType::S => 'S', + PieceType::T => 'T', + PieceType::Z => 'Z', + } + } +} + +impl core::fmt::Display for PieceType { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(self.name()) + } +} + +/// Error returned when trying to convert an invalid string to a [`PieceType`]. +#[derive(Debug)] +pub struct InvalidPieceName; + +impl TryFrom for PieceType { + type Error = InvalidPieceName; + fn try_from(ch: char) -> Result { + match ch { + 'I' => Ok(PieceType::I), + 'J' => Ok(PieceType::J), + 'L' => Ok(PieceType::L), + 'O' => Ok(PieceType::O), + 'S' => Ok(PieceType::S), + 'T' => Ok(PieceType::T), + 'Z' => Ok(PieceType::Z), + _ => Err(InvalidPieceName), + } + } +} + +impl core::str::FromStr for PieceType { + type Err = InvalidPieceName; + fn from_str(s: &str) -> Result { + if s.len() != 1 { + return Err(InvalidPieceName); + } + s.chars().next().unwrap().try_into() + } +} + +impl core::fmt::Display for InvalidPieceName { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "invalid piece name") + } +} + pub type Piece = crate::piece::Piece; #[cfg(test)] @@ -66,6 +136,14 @@ mod test { } } + #[test] + fn test_piece_name_parse() { + for ty in [L, O, J, I, S, T, Z] { + assert_eq!(PieceType::try_from(ty.as_char()).unwrap(), ty); + assert_eq!(ty.name().parse::().unwrap(), ty); + } + } + fn get_cells(ty: PieceType, r: Rot) -> (Range, Range, Vec<(i16, i16)>) { let loc = Loc { x: 0, y: 0, r }; let piece = Piece { ty, loc };