parse: fix missing mode & leniency + improve error msg
This commit is contained in:
@@ -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
@@ -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
@@ -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 }
|
||||||
|
|||||||
Reference in New Issue
Block a user