diff --git a/src/board/castle_rights.rs b/src/board/castle_rights.rs index 5b06544..5bd9d91 100644 --- a/src/board/castle_rights.rs +++ b/src/board/castle_rights.rs @@ -24,9 +24,18 @@ impl CastleRights { /// Panics if the index is out of bounds. #[inline(always)] pub fn from_index(index: usize) -> Self { - assert!(index < Self::NUM_VARIANTS); - // SAFETY: we know the value is in-bounds - unsafe { Self::from_index_unchecked(index) } + Self::try_from_index(index).expect("index out of bouds") + } + + /// Convert from a castle rights index into a [CastleRights] type. Returns [None] if the index + /// is out of bounds. + pub fn try_from_index(index: usize) -> Option { + if index < Self::NUM_VARIANTS { + // SAFETY: we know the value is in-bounds + Some(unsafe { Self::from_index_unchecked(index) }) + } else { + None + } } /// Convert from a castle rights index into a [CastleRights] type, no bounds checking. diff --git a/src/board/color.rs b/src/board/color.rs index 17ebcb5..e41d3c5 100644 --- a/src/board/color.rs +++ b/src/board/color.rs @@ -25,9 +25,18 @@ impl Color { /// Panics if the index is out of bounds. #[inline(always)] pub fn from_index(index: usize) -> Self { - assert!(index < Self::NUM_VARIANTS); - // SAFETY: we know the value is in-bounds - unsafe { Self::from_index_unchecked(index) } + Self::try_from_index(index).expect("index out of bouds") + } + + /// Convert from a color index into a [Color] type. Returns [None] if the index is out of + /// bounds. + pub fn try_from_index(index: usize) -> Option { + if index < Self::NUM_VARIANTS { + // SAFETY: we know the value is in-bounds + Some(unsafe { Self::from_index_unchecked(index) }) + } else { + None + } } /// Convert from a color index into a [Color] type, no bounds checking. diff --git a/src/board/file.rs b/src/board/file.rs index 5398660..1641498 100644 --- a/src/board/file.rs +++ b/src/board/file.rs @@ -41,9 +41,17 @@ impl File { /// Panics if the index is out of bounds. #[inline(always)] pub fn from_index(index: usize) -> Self { - assert!(index < Self::NUM_VARIANTS); - // SAFETY: we know the value is in-bounds - unsafe { Self::from_index_unchecked(index) } + Self::try_from_index(index).expect("index out of bouds") + } + + /// Convert from a file index into a [File] type. Returns [None] if the index is out of bounds. + pub fn try_from_index(index: usize) -> Option { + if index < Self::NUM_VARIANTS { + // SAFETY: we know the value is in-bounds + Some(unsafe { Self::from_index_unchecked(index) }) + } else { + None + } } /// Convert from a file index into a [File] type, no bounds checking. diff --git a/src/board/piece.rs b/src/board/piece.rs index 76d9df9..f6fdce4 100644 --- a/src/board/piece.rs +++ b/src/board/piece.rs @@ -34,9 +34,18 @@ impl Piece { /// Panics if the index is out of bounds. #[inline(always)] pub fn from_index(index: usize) -> Self { - assert!(index < Self::NUM_VARIANTS); - // SAFETY: we know the value is in-bounds - unsafe { Self::from_index_unchecked(index) } + Self::try_from_index(index).expect("index out of bouds") + } + + /// Convert from a piece index into a [Piece] type. Returns [None] if the index is out of + /// bounds. + pub fn try_from_index(index: usize) -> Option { + if index < Self::NUM_VARIANTS { + // SAFETY: we know the value is in-bounds + Some(unsafe { Self::from_index_unchecked(index) }) + } else { + None + } } /// Convert from a piece index into a [Piece] type, no bounds checking. diff --git a/src/board/rank.rs b/src/board/rank.rs index f716bde..1632229 100644 --- a/src/board/rank.rs +++ b/src/board/rank.rs @@ -41,9 +41,17 @@ impl Rank { /// Panics if the index is out of bounds. #[inline(always)] pub fn from_index(index: usize) -> Self { - assert!(index < Self::NUM_VARIANTS); - // SAFETY: we know the value is in-bounds - unsafe { Self::from_index_unchecked(index) } + Self::try_from_index(index).expect("index out of bouds") + } + + /// Convert from a rank index into a [Rank] type. Returns [None] if the index is out of bounds. + pub fn try_from_index(index: usize) -> Option { + if index < Self::NUM_VARIANTS { + // SAFETY: we know the value is in-bounds + Some(unsafe { Self::from_index_unchecked(index) }) + } else { + None + } } /// Convert from a rank index into a [Rank] type, no bounds checking. diff --git a/src/board/square.rs b/src/board/square.rs index afbd9bf..b5de25b 100644 --- a/src/board/square.rs +++ b/src/board/square.rs @@ -57,9 +57,18 @@ impl Square { /// Convert from a square index into a [Square] type. #[inline(always)] pub fn from_index(index: usize) -> Self { - assert!(index < Self::NUM_VARIANTS); - // SAFETY: we know the value is in-bounds - unsafe { Self::from_index_unchecked(index) } + Self::try_from_index(index).expect("index out of bouds") + } + + /// Convert from a square index into a [Square] type. Returns [None] if the index is out of + /// bounds. + pub fn try_from_index(index: usize) -> Option { + if index < Self::NUM_VARIANTS { + // SAFETY: we know the value is in-bounds + Some(unsafe { Self::from_index_unchecked(index) }) + } else { + None + } } /// Convert from a square index into a [Square] type, no bounds checking.