diff --git a/core/src/coordinates.rs b/core/src/coordinates.rs index f165a9a..b0c67ee 100644 --- a/core/src/coordinates.rs +++ b/core/src/coordinates.rs @@ -67,7 +67,14 @@ macro_rules! range_bound_struct { } } + /// Create a new `Self` + /// + /// # Safety + /// + /// This function does not perform any bounds checking. It should only be called when + /// the input is already known to be within bounds, i.e. when `x >= Self::FIRST && x < Self::LAST`. $vis unsafe fn new_unchecked(x: $repr) -> Self { + debug_assert!((Self::FIRST.0..=Self::LAST.0).contains(&x)); Self(x) } @@ -76,9 +83,9 @@ macro_rules! range_bound_struct { } } - impl Into<$repr> for $type { - fn into(self) -> $repr { - self.0 + impl From<$type> for $repr { + fn from(x: $type) -> Self { + x.0 } } @@ -200,7 +207,11 @@ coordinate_enum!(Square, [ ]); impl Square { + /// # Safety + /// + /// This function does not do any bounds checking on the input. pub unsafe fn from_index(x: u8) -> Square { + debug_assert!((x as usize) < Self::NUM); Self::try_from(x).unwrap_unchecked() } @@ -233,50 +244,37 @@ impl Square { let index: u8 = self as u8; let dir: i8 = direction.to_offset(); match direction { - Direction::North => Square::try_from(index.wrapping_add_signed(dir)).ok(), + Direction::North | Direction::NorthEast => { + Square::try_from(index.wrapping_add_signed(dir)).ok() + } Direction::NorthWest => { - if self.rank() != Rank::EIGHT { - Square::try_from(index.wrapping_add_signed(dir)).ok() - } else { + if self.rank() == Rank::EIGHT { None + } else { + Square::try_from(index.wrapping_add_signed(dir)).ok() } } Direction::West => { - if self.file() != File::A { - Square::try_from(index.wrapping_add_signed(dir)).ok() - } else { + if self.file() == File::A { None + } else { + Square::try_from(index.wrapping_add_signed(dir)).ok() } } - Direction::SouthWest => { - if self.rank() != Rank::ONE { - Square::try_from(index.wrapping_add_signed(dir)).ok() - } else { + Direction::SouthEast | Direction::South | Direction::SouthWest => { + if self.rank() == Rank::ONE { None - } - } - Direction::South => { - if self.rank() != Rank::ONE { - Square::try_from(index.wrapping_add_signed(dir)).ok() } else { - None - } - } - Direction::SouthEast => { - if self.rank() != Rank::ONE { Square::try_from(index.wrapping_add_signed(dir)).ok() - } else { - None } } Direction::East => { - if self.file() != File::H { - Square::try_from(index.wrapping_add_signed(dir)).ok() - } else { + if self.file() == File::H { None + } else { + Square::try_from(index.wrapping_add_signed(dir)).ok() } } - Direction::NorthEast => Square::try_from(index.wrapping_add_signed(dir)).ok(), } } } @@ -300,7 +298,7 @@ impl FromStr for Square { .and_then(|c| c.try_into().ok()) .ok_or(ParseSquareError)?; - if !chars.next().is_none() { + if chars.next().is_some() { return Err(ParseSquareError); } @@ -328,17 +326,17 @@ impl fmt::Display for Square { } } -impl Into for File { - fn into(self) -> char { - let value: u8 = self.into(); - (value + 'a' as u8) as char +impl From for char { + fn from(value: File) -> Self { + let u8value: u8 = value.into(); + (u8value + b'a') as char } } impl Into for Rank { fn into(self) -> char { let value: u8 = self.into(); - (value + '1' as u8) as char + (value + b'1') as char } } @@ -346,7 +344,7 @@ impl TryFrom for File { type Error = (); fn try_from(value: char) -> Result { - File::try_from(value.to_ascii_lowercase() as u8 - 'a' as u8) + File::try_from(value.to_ascii_lowercase() as u8 - b'a') } } @@ -354,7 +352,7 @@ impl TryFrom for Rank { type Error = (); fn try_from(value: char) -> Result { - let result = (value as u8).checked_sub('1' as u8).ok_or(())?; + let result = (value as u8).checked_sub(b'1').ok_or(())?; Self::try_from(result) } }