parse: fix missing mode & leniency + improve error msg

This commit is contained in:
MaxOhn
2021-01-20 10:21:28 +01:00
parent 2336793cc6
commit b3f73b7b6c
3 changed files with 31 additions and 26 deletions
+2 -2
View File
@@ -278,7 +278,7 @@ mod tests {
#[test] #[test]
#[ignore] #[ignore]
fn no_leniency_single() { fn no_leniency_single() {
let file = match File::open("./maps/1851299.osu") { let file = match File::open("./maps/295.osu") {
Ok(file) => file, Ok(file) => file,
Err(why) => panic!("Could not open file: {}", why), Err(why) => panic!("Could not open file: {}", why),
}; };
@@ -288,7 +288,7 @@ mod tests {
Err(why) => panic!("Error while parsing map: {}", why), Err(why) => panic!("Error while parsing map: {}", why),
}; };
let result = OsuPP::new(&map).mods(256).calculate(stars); let result = OsuPP::new(&map).mods(0).calculate(stars);
println!("Stars: {}", result.stars()); println!("Stars: {}", result.stars());
println!("PP: {}", result.pp()); println!("PP: {}", result.pp());
+3 -3
View File
@@ -18,7 +18,7 @@ pub enum ParseError {
InvalidMode, InvalidMode,
InvalidPathType, InvalidPathType,
InvalidTimingSignature, InvalidTimingSignature,
MissingField, MissingField(&'static str),
UnknownHitObjectKind, UnknownHitObjectKind,
} }
@@ -36,7 +36,7 @@ impl fmt::Display for ParseError {
Self::InvalidMode => f.write_str("invalid mode"), Self::InvalidMode => f.write_str("invalid mode"),
Self::InvalidPathType => f.write_str("invalid path type"), Self::InvalidPathType => f.write_str("invalid path type"),
Self::InvalidTimingSignature => f.write_str("invalid timing signature"), Self::InvalidTimingSignature => f.write_str("invalid timing signature"),
Self::MissingField => f.write_str("missing field"), Self::MissingField(field) => write!(f, "missing field `{}`", field),
Self::UnknownHitObjectKind => f.write_str("unsupported hitobject kind"), Self::UnknownHitObjectKind => f.write_str("unsupported hitobject kind"),
} }
} }
@@ -54,7 +54,7 @@ impl StdError for ParseError {
Self::InvalidMode => None, Self::InvalidMode => None,
Self::InvalidPathType => None, Self::InvalidPathType => None,
Self::InvalidTimingSignature => None, Self::InvalidTimingSignature => None,
Self::MissingField => None, Self::MissingField(_) => None,
Self::UnknownHitObjectKind => None, Self::UnknownHitObjectKind => None,
} }
} }
+26 -21
View File
@@ -25,8 +25,8 @@ macro_rules! sort {
} }
macro_rules! next_field { macro_rules! next_field {
($opt:expr) => { ($opt:expr, $($val:tt)*) => {
$opt.ok_or(ParseError::MissingField)? $opt.ok_or_else(|| ParseError::MissingField(stringify!($($val)*)))?
}; };
} }
@@ -197,8 +197,8 @@ impl Beatmap {
buf.clear(); buf.clear();
} }
self.mode = next_field!(mode); self.mode = mode.unwrap_or(GameMode::STD);
self.stack_leniency = next_field!(stack_leniency); self.stack_leniency = stack_leniency.unwrap_or(0.7);
Ok(empty) Ok(empty)
} }
@@ -243,12 +243,12 @@ impl Beatmap {
buf.clear(); buf.clear();
} }
self.od = next_field!(od); self.od = next_field!(od, od);
self.cs = next_field!(cs); self.cs = next_field!(cs, cs);
self.hp = next_field!(hp); self.hp = next_field!(hp, hp);
self.ar = ar.unwrap_or(self.od); self.ar = ar.unwrap_or(self.od);
self.sv = next_field!(sv); self.sv = next_field!(sv, sv);
self.tick_rate = next_field!(tick_rate); self.tick_rate = next_field!(tick_rate, sv);
Ok(empty) Ok(empty)
} }
@@ -279,10 +279,12 @@ impl Beatmap {
let mut split = line.split(','); let mut split = line.split(',');
let time = next_field!(split.next()).trim().parse::<f32>()?; let time = next_field!(split.next(), timing point time)
.trim()
.parse::<f32>()?;
validate_float!(time); validate_float!(time);
let beat_len = next_field!(split.next()).trim().parse::<f32>()?; let beat_len = next_field!(split.next(), beat len).trim().parse::<f32>()?;
if beat_len < 0.0 { if beat_len < 0.0 {
let point = DifficultyPoint { let point = DifficultyPoint {
@@ -351,18 +353,20 @@ impl Beatmap {
let mut split = line.split(','); let mut split = line.split(',');
let pos = Pos2 { let pos = Pos2 {
x: next_field!(split.next()).parse()?, x: next_field!(split.next(), x position).parse()?,
y: next_field!(split.next()).parse()?, y: next_field!(split.next(), y position).parse()?,
}; };
let time = next_field!(split.next()).trim().parse::<f32>()?; let time = next_field!(split.next(), hitobject time)
.trim()
.parse::<f32>()?;
validate_float!(time); validate_float!(time);
if !self.hit_objects.is_empty() && time < prev_time { if !self.hit_objects.is_empty() && time < prev_time {
unsorted = true; unsorted = true;
} }
let kind: u8 = next_field!(split.next()).parse()?; let kind: u8 = next_field!(split.next(), hitobject kind).parse()?;
let sound = split.next().map(str::parse).transpose()?.unwrap_or(0); let sound = split.next().map(str::parse).transpose()?.unwrap_or(0);
let kind = if kind & Self::CIRCLE_FLAG > 0 { let kind = if kind & Self::CIRCLE_FLAG > 0 {
@@ -374,9 +378,10 @@ impl Beatmap {
let mut curve_points = Vec::with_capacity(16); let mut curve_points = Vec::with_capacity(16);
curve_points.push(pos); curve_points.push(pos);
let mut curve_point_iter = next_field!(split.next()).split('|'); let mut curve_point_iter = next_field!(split.next(), curve points).split('|');
let mut path_type: PathType = next_field!(curve_point_iter.next()).parse()?; let mut path_type: PathType =
next_field!(curve_point_iter.next(), path kind).parse()?;
for pos in curve_point_iter { for pos in curve_point_iter {
let mut v = pos.split(':').map(str::parse); let mut v = pos.split(':').map(str::parse);
@@ -401,8 +406,8 @@ impl Beatmap {
if curve_points.is_empty() { if curve_points.is_empty() {
HitObjectKind::Circle HitObjectKind::Circle
} else { } else {
let repeats = next_field!(split.next()).parse::<usize>()?; let repeats = next_field!(split.next(), repeats).parse::<usize>()?;
let len: f32 = next_field!(split.next()).parse()?; let len: f32 = next_field!(split.next(), pixel len).parse()?;
HitObjectKind::Slider { HitObjectKind::Slider {
repeats, repeats,
@@ -413,7 +418,7 @@ impl Beatmap {
} }
} else if kind & Self::SPINNER_FLAG > 0 { } else if kind & Self::SPINNER_FLAG > 0 {
self.n_spinners += 1; self.n_spinners += 1;
let end_time = next_field!(split.next()).parse()?; let end_time = next_field!(split.next(), spinner endtime).parse()?;
HitObjectKind::Spinner { end_time } HitObjectKind::Spinner { end_time }
} else if kind & Self::HOLD_FLAG > 0 { } else if kind & Self::HOLD_FLAG > 0 {
@@ -421,7 +426,7 @@ impl Beatmap {
let mut end = time; let mut end = time;
if let Some(next) = split.next() { if let Some(next) = split.next() {
end = end.max(next_field!(next.split(':').next()).parse()?); end = end.max(next_field!(next.split(':').next(), hold endtime).parse()?);
} }
HitObjectKind::Hold { end_time: end } HitObjectKind::Hold { end_time: end }