ddr::ssq::Row: Return error on invalid player count

This commit is contained in:
Simon Bruder 2020-07-23 12:37:29 +02:00
parent 38180cfd0a
commit 7700e511f9
No known key found for this signature in database
GPG key ID: 6F03E0000CC5B62F

View file

@ -20,6 +20,8 @@ const MEASURE_LENGTH: f32 = 4096.0;
pub enum Error { pub enum Error {
#[error("Not enough freeze data was found")] #[error("Not enough freeze data was found")]
NotEnoughFreezeData, NotEnoughFreezeData,
#[error("Invalid player count {0} (valid options: 1, 2)")]
InvalidPlayerCount(u8),
#[error(transparent)] #[error(transparent)]
IOError(#[from] io::Error), IOError(#[from] io::Error),
#[error(transparent)] #[error(transparent)]
@ -104,11 +106,14 @@ impl fmt::Display for Row {
} }
impl Row { impl Row {
fn new(byte: u8, players: u8) -> Self { fn new(byte: u8, players: u8) -> Result<Self, Error> {
match players { match players {
1 => Self::Single(PlayerRow::from(byte)), 1 => Ok(Self::Single(PlayerRow::from(byte))),
2 => Self::Double(PlayerRow::from(byte), PlayerRow::from(byte >> 4)), 2 => Ok(Self::Double(
_ => unreachable!(), PlayerRow::from(byte),
PlayerRow::from(byte >> 4),
)),
_ => Err(Error::InvalidPlayerCount(players)),
} }
} }
@ -256,7 +261,7 @@ impl Chart {
// freeze end (start is the last normal step in that column) // freeze end (start is the last normal step in that column)
trace!("Freeze arrow at {}", beats); trace!("Freeze arrow at {}", beats);
let row = Row::new(columns, difficulty.players); let row = Row::new(columns, difficulty.players)?;
if row.count_active() != 1 { if row.count_active() != 1 {
warn!("Found freeze with not exactly one column, which is not implemented, skipping"); warn!("Found freeze with not exactly one column, which is not implemented, skipping");
continue; continue;
@ -293,7 +298,7 @@ impl Chart {
parsed_steps.push(Step::Step { parsed_steps.push(Step::Step {
beats, beats,
row: Row::new(steps[step], difficulty.players), row: Row::new(steps[step], difficulty.players)?,
}); });
} }
} }
@ -453,12 +458,11 @@ mod tests {
#[quickcheck] #[quickcheck]
fn test_row_new(columns: u8, players: u8) -> TestResult { fn test_row_new(columns: u8, players: u8) -> TestResult {
match players { match (Row::new(columns, players), players) {
1 | 2 => match (Row::new(columns, players), players) { (Ok(Row::Single(..)), 1) => TestResult::passed(),
(Row::Single(..), 1) | (Row::Double(..), 2) => TestResult::passed(), (Ok(Row::Double(..)), 2) => TestResult::passed(),
_ => TestResult::failed(), (Ok(Row::Single(..)), 2) | (Ok(Row::Double(..)), 1) => TestResult::failed(),
}, (row, _) => TestResult::from_bool(row.is_err()),
_ => TestResult::must_fail(move || Row::new(columns, players)),
} }
} }
@ -471,7 +475,7 @@ mod tests {
} else { } else {
columns columns
}; };
let row = Row::new(columns, players); let row = Row::new(columns, players).unwrap();
let intersects = row.clone().intersects(row); let intersects = row.clone().intersects(row);
// Rows dont intersect when all columns are unset // Rows dont intersect when all columns are unset
if columns == 0 { if columns == 0 {
@ -492,8 +496,8 @@ mod tests {
(0b00100000, 0b00100000, 2), (0b00100000, 0b00100000, 2),
]; ];
for (a, b, players) in values.iter() { for (a, b, players) in values.iter() {
let row_a = Row::new(*a, *players); let row_a = Row::new(*a, *players).unwrap();
let row_b = Row::new(*b, *players); let row_b = Row::new(*b, *players).unwrap();
assert!(row_a.intersects(row_b)); assert!(row_a.intersects(row_b));
} }
} }
@ -511,7 +515,7 @@ mod tests {
(0b11111111, 8, 2), (0b11111111, 8, 2),
]; ];
for (data, active, players) in values.iter() { for (data, active, players) in values.iter() {
assert_eq!(Row::new(*data, *players).count_active(), *active); assert_eq!(Row::new(*data, *players).unwrap().count_active(), *active);
} }
} }
@ -528,7 +532,10 @@ mod tests {
(0b11111111, "←↓↑→ ←↓↑→", 2), (0b11111111, "←↓↑→ ←↓↑→", 2),
]; ];
for (data, displayed, players) in values.iter() { for (data, displayed, players) in values.iter() {
assert_eq!(format!("{}", Row::new(*data, *players)), *displayed); assert_eq!(
format!("{}", Row::new(*data, *players).unwrap()),
*displayed
);
} }
} }