Skip to content

Commit 5246b71

Browse files
shumpohliCodeSometime
authored andcommitted
Increase clarity and remove undefined behavior when converting from usize to rank or file
1 parent ec50789 commit 5246b71

2 files changed

Lines changed: 42 additions & 20 deletions

File tree

src/file.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
use crate::error::Error;
2-
use std::mem::transmute;
32
use std::str::FromStr;
43

54
/// Describe a file (column) on a chess board
5+
#[repr(u8)]
66
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Debug, Hash)]
77
pub enum File {
8-
A,
9-
B,
10-
C,
11-
D,
12-
E,
13-
F,
14-
G,
15-
H,
8+
A = 0,
9+
B = 1,
10+
C = 2,
11+
D = 3,
12+
E = 4,
13+
F = 5,
14+
G = 6,
15+
H = 7,
1616
}
1717

1818
/// How many files are there?
@@ -34,7 +34,18 @@ impl File {
3434
/// Convert a `usize` into a `File` (the inverse of to_index). If i > 7, wrap around.
3535
#[inline]
3636
pub fn from_index(i: usize) -> File {
37-
unsafe { transmute((i as u8) & 7) }
37+
// match is optimized to no-op with opt-level=1 with rustc 1.53.0
38+
match i & 7 {
39+
0 => File::A,
40+
1 => File::B,
41+
2 => File::C,
42+
3 => File::D,
43+
4 => File::E,
44+
5 => File::F,
45+
6 => File::G,
46+
7 => File::H,
47+
_ => unreachable!(),
48+
}
3849
}
3950

4051
/// Go one file to the left. If impossible, wrap around.

src/rank.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
use crate::error::Error;
2-
use std::mem::transmute;
32
use std::str::FromStr;
43

54
/// Describe a rank (row) on a chess board
5+
#[repr(u8)]
66
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Debug, Hash)]
77
pub enum Rank {
8-
First,
9-
Second,
10-
Third,
11-
Fourth,
12-
Fifth,
13-
Sixth,
14-
Seventh,
15-
Eighth,
8+
First = 0,
9+
Second = 1,
10+
Third = 2,
11+
Fourth = 3,
12+
Fifth = 4,
13+
Sixth = 5,
14+
Seventh = 6,
15+
Eighth = 7,
1616
}
1717

1818
/// How many ranks are there?
@@ -35,7 +35,18 @@ impl Rank {
3535
/// around.
3636
#[inline]
3737
pub fn from_index(i: usize) -> Rank {
38-
unsafe { transmute((i as u8) & 7) }
38+
// match is optimized to no-op with opt-level=1 with rustc 1.53.0
39+
match i & 7 {
40+
0 => Rank::First,
41+
1 => Rank::Second,
42+
2 => Rank::Third,
43+
3 => Rank::Fourth,
44+
4 => Rank::Fifth,
45+
5 => Rank::Sixth,
46+
6 => Rank::Seventh,
47+
7 => Rank::Eighth,
48+
_ => unreachable!(),
49+
}
3950
}
4051

4152
/// Go one rank down. If impossible, wrap around.

0 commit comments

Comments
 (0)