chessrs 0.1.0

A command line implementation for the game of chess
Documentation
use std::fmt::Display;

use crate::PieceType;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Coords {
    pub piece: PieceType,
    pub is_capture: bool,
    pub x: usize,
    pub y: usize,
}

impl Display for Coords {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let x = (self.x as u8 + 'a' as u8) as char;
        let y = (self.y as u8 + '1' as u8) as char;

        write!(f, "{}{}", x, y)
    }
}

impl Into<(usize, usize)> for Coords {
    fn into(self) -> (usize, usize) {
        (self.x, self.y)
    }
}

impl From<(usize, usize)> for Coords {
    fn from(tuple: (usize, usize)) -> Self {
        Coords {
            piece: PieceType::None,
            is_capture: false,
            x: tuple.0,
            y: 7 - tuple.1,
        }
    }
}

impl Coords {
    pub fn new(x: usize, y: usize) -> Self {
        Coords {
            piece: PieceType::None,
            is_capture: false,
            x,
            y: 7 - y,
        }
    }
    pub fn from_raw(x: usize, y: usize) -> Self {
        Coords {
            piece: PieceType::None,
            is_capture: false,
            x,
            y,
        }
    }

    pub fn build(s: &str) -> Result<Coords, String> {
        if s.len() > 4 || s.len() < 2 {
            return Err("Invalid input".to_string());
        }

        let mut chars = s.chars();
        let piece = if s.len() == 2 {
            PieceType::Pawn
        } else {
            match chars.next().unwrap() {
                'p' => PieceType::Pawn,
                'r' => PieceType::Rook,
                'n' => PieceType::Knight,
                'b' => PieceType::Bishop,
                'q' => PieceType::Queen,
                'k' => PieceType::King,
                _ => return Err("Invalid piece".to_string()),
            }
        };
        let is_capture = if s.len() > 3 {
            match chars.next().unwrap() {
                'x' => true,
                _ => false,
            }
        } else {
            false
        };
        let x = match chars.next().unwrap() {
            x @ 'a'..='h' => x as usize - 'a' as usize,
            _ => return Err("Invalid x coordinate".to_string()),
        };
        let y = match chars.next().unwrap() {
            y @ '1'..='8' => y as usize - '1' as usize,
            _ => return Err("Invalid y coordinate".to_string()),
        };

        Ok(Coords {
            piece,
            is_capture,
            x,
            y,
        })
    }

    pub fn default() -> Self {
        Coords {
            piece: PieceType::None,
            is_capture: false,
            x: 9,
            y: 9,
        }
    }
}