use std::fmt;
#[derive(Clone, Debug)]
pub struct Square {
pub col: usize,
pub row: usize,
}
impl fmt::Display for Square {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let col_name = match &self.col {
0 => "a",
1 => "b",
2 => "c",
3 => "d",
4 => "e",
5 => "f",
6 => "g",
7 => "h",
_ => panic!("Illegal coordinate"),
};
write!(f, "{}{}", col_name, self.row + 1)
}
}
impl PartialEq for Square {
fn eq(&self, other: &Self) -> bool {
self.col == other.col && self.row == other.row
}
}
impl Eq for Square {}
impl Square {
pub fn from(name: &str) -> Result<Square, &'static str> {
let name = name.to_lowercase();
let chars: Vec<char> = name.chars().collect();
if chars.len() == 2 {
let col = match chars[0] {
'a' => 0,
'b' => 1,
'c' => 2,
'd' => 3,
'e' => 4,
'f' => 5,
'g' => 6,
'h' => 7,
_ => {
return Err("Invalid square definition");
}
};
let row = match chars[1] {
'1' => 0,
'2' => 1,
'3' => 2,
'4' => 3,
'5' => 4,
'6' => 5,
'7' => 6,
'8' => 7,
_ => {
return Err("Invalid square definition");
}
};
return Ok(Square { col, row });
}
Err("Invalid square definition")
}
}
pub fn step_h(start: &Square, finish: &Square) -> usize {
if start.col > finish.col {
start.col - finish.col
} else {
finish.col - start.col
}
}
pub fn step_v(start: &Square, finish: &Square) -> usize {
if start.row > finish.row {
start.row - finish.row
} else {
finish.row - start.row
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_square() {
assert_eq!(Err("Invalid square definition"), Square::from("E"));
assert_eq!(Err("Invalid square definition"), Square::from("5E"));
assert_eq!(Err("Invalid square definition"), Square::from("E9"));
assert_eq!(Err("Invalid square definition"), Square::from("T3"));
assert_eq!(Ok(Square { col: 0, row: 7 }), Square::from("A8"));
assert_eq!(Ok(Square { col: 7, row: 0 }), Square::from("H1"));
assert_eq!(Ok(Square { col: 4, row: 4 }), Square::from("E5"));
}
}