parse cleanup
This commit is contained in:
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
## Upcoming
|
## Upcoming
|
||||||
|
|
||||||
- No changes so far
|
- parse:
|
||||||
|
- Cleanup
|
||||||
|
|
||||||
# v0.2.0
|
# v0.2.0
|
||||||
|
|
||||||
|
|||||||
+33
-36
@@ -37,8 +37,8 @@ macro_rules! sort {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! next_field {
|
macro_rules! next_field {
|
||||||
($opt:expr, $($val:tt)*) => {
|
($opt:expr, $err:literal) => {
|
||||||
$opt.ok_or_else(|| ParseError::MissingField(stringify!($($val)*)))?
|
$opt.ok_or_else(|| ParseError::MissingField($err))?
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,24 +172,24 @@ macro_rules! parse_general_body {
|
|||||||
|
|
||||||
macro_rules! parse_general {
|
macro_rules! parse_general {
|
||||||
($reader:ident<$inner:ident>) => {
|
($reader:ident<$inner:ident>) => {
|
||||||
fn parse_difficulty<R: $inner>(
|
fn parse_general<R: $inner>(
|
||||||
&mut self,
|
&mut self,
|
||||||
reader: &mut $reader<R>,
|
reader: &mut $reader<R>,
|
||||||
buf: &mut String,
|
buf: &mut String,
|
||||||
section: &mut Section,
|
section: &mut Section,
|
||||||
) -> ParseResult<bool> {
|
) -> ParseResult<bool> {
|
||||||
parse_difficulty_body!(self, reader, buf, section)
|
parse_general_body!(self, reader, buf, section)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(async $reader:ident<$inner:ident>) => {
|
(async $reader:ident<$inner:ident>) => {
|
||||||
async fn parse_difficulty<R: $inner + Unpin>(
|
async fn parse_general<R: $inner + Unpin>(
|
||||||
&mut self,
|
&mut self,
|
||||||
reader: &mut $reader<R>,
|
reader: &mut $reader<R>,
|
||||||
buf: &mut String,
|
buf: &mut String,
|
||||||
section: &mut Section,
|
section: &mut Section,
|
||||||
) -> ParseResult<bool> {
|
) -> ParseResult<bool> {
|
||||||
parse_difficulty_body!(self, reader, buf, section)
|
parse_general_body!(self, reader, buf, section)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -230,12 +230,12 @@ macro_rules! parse_difficulty_body {
|
|||||||
$buf.clear();
|
$buf.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
$self.od = next_field!(od, od);
|
$self.od = next_field!(od, "od");
|
||||||
$self.cs = next_field!(cs, cs);
|
$self.cs = next_field!(cs, "cs");
|
||||||
$self.hp = next_field!(hp, 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, sv);
|
$self.sv = next_field!(sv, "sv");
|
||||||
$self.tick_rate = next_field!(tick_rate, sv);
|
$self.tick_rate = next_field!(tick_rate, "sv");
|
||||||
|
|
||||||
Ok(empty)
|
Ok(empty)
|
||||||
}};
|
}};
|
||||||
@@ -243,24 +243,24 @@ macro_rules! parse_difficulty_body {
|
|||||||
|
|
||||||
macro_rules! parse_difficulty {
|
macro_rules! parse_difficulty {
|
||||||
($reader:ident<$inner:ident>) => {
|
($reader:ident<$inner:ident>) => {
|
||||||
fn parse_general<R: $inner>(
|
fn parse_difficulty<R: $inner>(
|
||||||
&mut self,
|
&mut self,
|
||||||
reader: &mut $reader<R>,
|
reader: &mut $reader<R>,
|
||||||
buf: &mut String,
|
buf: &mut String,
|
||||||
section: &mut Section,
|
section: &mut Section,
|
||||||
) -> ParseResult<bool> {
|
) -> ParseResult<bool> {
|
||||||
parse_general_body!(self, reader, buf, section)
|
parse_difficulty_body!(self, reader, buf, section)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(async $reader:ident<$inner:ident>) => {
|
(async $reader:ident<$inner:ident>) => {
|
||||||
async fn parse_general<R: $inner + Unpin>(
|
async fn parse_difficulty<R: $inner + Unpin>(
|
||||||
&mut self,
|
&mut self,
|
||||||
reader: &mut $reader<R>,
|
reader: &mut $reader<R>,
|
||||||
buf: &mut String,
|
buf: &mut String,
|
||||||
section: &mut Section,
|
section: &mut Section,
|
||||||
) -> ParseResult<bool> {
|
) -> ParseResult<bool> {
|
||||||
parse_general_body!(self, reader, buf, section)
|
parse_difficulty_body!(self, reader, buf, section)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -306,12 +306,14 @@ macro_rules! parse_timingpoints_body {
|
|||||||
|
|
||||||
let mut split = line.split(',');
|
let mut split = line.split(',');
|
||||||
|
|
||||||
let time = next_field!(split.next(), timing point time)
|
let time = next_field!(split.next(), "timing point time")
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<f32>()?;
|
.parse::<f32>()?;
|
||||||
validate_float!(time);
|
validate_float!(time);
|
||||||
|
|
||||||
let beat_len = next_field!(split.next(), beat len).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 {
|
||||||
@@ -383,7 +385,6 @@ macro_rules! parse_timingpoints {
|
|||||||
|
|
||||||
#[cfg(any(feature = "osu", feature = "fruits"))]
|
#[cfg(any(feature = "osu", feature = "fruits"))]
|
||||||
parse_timingpoints_body!(self, reader, buf, section)
|
parse_timingpoints_body!(self, reader, buf, section)
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -408,11 +409,11 @@ macro_rules! parse_hitobjects_body {
|
|||||||
let mut split = line.split(',');
|
let mut split = line.split(',');
|
||||||
|
|
||||||
let pos = Pos2 {
|
let pos = Pos2 {
|
||||||
x: next_field!(split.next(), x position).parse()?,
|
x: next_field!(split.next(), "x position").parse()?,
|
||||||
y: next_field!(split.next(), y position).parse()?,
|
y: next_field!(split.next(), "y position").parse()?,
|
||||||
};
|
};
|
||||||
|
|
||||||
let time = next_field!(split.next(), hitobject time)
|
let time = next_field!(split.next(), "hitobject time")
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<f32>()?;
|
.parse::<f32>()?;
|
||||||
|
|
||||||
@@ -422,7 +423,7 @@ macro_rules! parse_hitobjects_body {
|
|||||||
unsorted = true;
|
unsorted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let kind: u8 = next_field!(split.next(), hitobject kind).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 {
|
||||||
@@ -437,13 +438,13 @@ macro_rules! parse_hitobjects_body {
|
|||||||
all(feature = "osu", not(feature = "no_sliders_no_leniency"))
|
all(feature = "osu", not(feature = "no_sliders_no_leniency"))
|
||||||
))]
|
))]
|
||||||
{
|
{
|
||||||
let mut curve_points = Vec::with_capacity(8);
|
let mut curve_points = Vec::with_capacity(4);
|
||||||
curve_points.push(pos);
|
curve_points.push(pos);
|
||||||
|
|
||||||
let mut curve_point_iter = next_field!(split.next(), curve points).split('|');
|
let mut curve_point_iter = next_field!(split.next(), "curve points").split('|');
|
||||||
|
|
||||||
let mut path_type: PathType =
|
let mut path_type: PathType =
|
||||||
next_field!(curve_point_iter.next(), path kind).parse()?;
|
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);
|
||||||
@@ -457,9 +458,7 @@ macro_rules! parse_hitobjects_body {
|
|||||||
if $self.version <= 6 && curve_points.len() >= 2 {
|
if $self.version <= 6 && curve_points.len() >= 2 {
|
||||||
if path_type == PathType::Linear {
|
if path_type == PathType::Linear {
|
||||||
path_type = PathType::Bezier;
|
path_type = PathType::Bezier;
|
||||||
}
|
} else if curve_points.len() == 2
|
||||||
|
|
||||||
if curve_points.len() == 2
|
|
||||||
&& (pos == curve_points[0] || pos == curve_points[1])
|
&& (pos == curve_points[0] || pos == curve_points[1])
|
||||||
{
|
{
|
||||||
path_type = PathType::Linear;
|
path_type = PathType::Linear;
|
||||||
@@ -467,9 +466,8 @@ macro_rules! parse_hitobjects_body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reduce amount of curvepoints but keep the elements evenly spaced.
|
// Reduce amount of curvepoints but keep the elements evenly spaced.
|
||||||
// Necessary to handle maps like XNOR (2573164) that have
|
// Necessary to handle maps like XNOR (2573164) which have
|
||||||
// tens of thousands of curvepoints more efficiently.
|
// tens of thousands of curvepoints more efficiently.
|
||||||
if curve_points.len() > CURVE_POINT_THRESHOLD {
|
|
||||||
while curve_points.len() > CURVE_POINT_THRESHOLD {
|
while curve_points.len() > CURVE_POINT_THRESHOLD {
|
||||||
let last = curve_points[curve_points.len() - 1];
|
let last = curve_points[curve_points.len() - 1];
|
||||||
let last_idx = (curve_points.len() - 1) / 2;
|
let last_idx = (curve_points.len() - 1) / 2;
|
||||||
@@ -481,23 +479,22 @@ macro_rules! parse_hitobjects_body {
|
|||||||
curve_points[last_idx] = last;
|
curve_points[last_idx] = last;
|
||||||
curve_points.truncate(last_idx + 1);
|
curve_points.truncate(last_idx + 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if curve_points.is_empty() {
|
if curve_points.is_empty() {
|
||||||
HitObjectKind::Circle
|
HitObjectKind::Circle
|
||||||
} else {
|
} else {
|
||||||
let repeats = next_field!(split.next(), repeats)
|
let repeats = next_field!(split.next(), "repeats")
|
||||||
.parse::<usize>()?
|
.parse::<usize>()?
|
||||||
.min(9000);
|
.min(9000);
|
||||||
|
|
||||||
let len = next_field!(split.next(), pixel len)
|
let pixel_len = next_field!(split.next(), "pixel len")
|
||||||
.parse::<f32>()?
|
.parse::<f32>()?
|
||||||
.max(0.0)
|
.max(0.0)
|
||||||
.min(MAX_COORDINATE_VALUE);
|
.min(MAX_COORDINATE_VALUE);
|
||||||
|
|
||||||
HitObjectKind::Slider {
|
HitObjectKind::Slider {
|
||||||
repeats,
|
repeats,
|
||||||
pixel_len: len,
|
pixel_len,
|
||||||
curve_points,
|
curve_points,
|
||||||
path_type,
|
path_type,
|
||||||
}
|
}
|
||||||
@@ -519,7 +516,7 @@ macro_rules! parse_hitobjects_body {
|
|||||||
}
|
}
|
||||||
} 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(), spinner endtime).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 {
|
||||||
@@ -527,7 +524,7 @@ macro_rules! parse_hitobjects_body {
|
|||||||
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(), hold endtime).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