Use Option instead of Result where applicable

master
Simon Bruder 2020-06-25 13:25:47 +02:00
parent 5d3138ed2d
commit 8c8f954bbe
No known key found for this signature in database
GPG Key ID: 6F03E0000CC5B62F
2 changed files with 113 additions and 86 deletions

View File

@ -3,7 +3,7 @@ use std::str::FromStr;
use anyhow::{anyhow, Result};
use clap::Clap;
use log::{debug, info, trace};
use log::{debug, info, trace, warn};
use crate::ddr::ssq;
use crate::osu::beatmap;
@ -142,25 +142,25 @@ impl ShockStepGenerator {
}
}
fn get_time_from_beats(beats: f32, tempo_changes: &[ssq::TempoChange]) -> Result<i32> {
fn get_time_from_beats(beats: f32, tempo_changes: &[ssq::TempoChange]) -> Option<i32> {
for tempo_change in tempo_changes {
// For TempoChanges that are infinitely short but exactly cover that beat, use the start
// time of that TempoChange
if (beats - tempo_change.start_beats).abs() < 0.001
&& (beats - tempo_change.end_beats).abs() < 0.001
{
return Ok(tempo_change.start_ms);
return Some(tempo_change.start_ms);
}
if beats < tempo_change.end_beats {
return Ok(tempo_change.start_ms
+ ((beats - tempo_change.start_beats) * tempo_change.beat_length) as i32);
return Some(
tempo_change.start_ms
+ ((beats - tempo_change.start_beats) * tempo_change.beat_length) as i32,
);
}
}
Err(anyhow!(
"Conversion of Step to HitObject failed: Beat lies outside of TimingPoints range"
))
None
}
impl From<ssq::TempoChange> for beatmap::TimingPoint {
@ -191,69 +191,93 @@ impl ssq::Step {
num_columns: u8,
tempo_changes: &ssq::TempoChanges,
shock_step_generator: &mut ShockStepGenerator,
) -> Result<Vec<beatmap::HitObject>> {
) -> Option<Vec<beatmap::HitObject>> {
let mut hit_objects = Vec::new();
match self {
ssq::Step::Step { beats, row } => {
let time = get_time_from_beats(*beats, &tempo_changes.0)?;
let time = get_time_from_beats(*beats, &tempo_changes.0);
let columns: Vec<bool> = row.clone().into();
match time {
Some(time) => {
let columns: Vec<bool> = row.clone().into();
for (column, active) in columns.iter().enumerate() {
if *active {
hit_objects.push(beatmap::HitObject::HitCircle {
x: beatmap::column_to_x(column as u8, num_columns),
y: 192,
time,
hit_sound: beatmap::HitSound {
normal: true,
whistle: false,
finish: false,
clap: false,
},
new_combo: false,
skip_combo_colours: 0,
hit_sample: beatmap::HitSample {
normal_set: 0,
addition_set: 0,
index: 0,
volume: 0,
filename: "".to_string(),
},
})
for (column, active) in columns.iter().enumerate() {
if *active {
hit_objects.push(beatmap::HitObject::HitCircle {
x: beatmap::column_to_x(column as u8, num_columns),
y: 192,
time,
hit_sound: beatmap::HitSound {
normal: true,
whistle: false,
finish: false,
clap: false,
},
new_combo: false,
skip_combo_colours: 0,
hit_sample: beatmap::HitSample {
normal_set: 0,
addition_set: 0,
index: 0,
volume: 0,
filename: "".to_string(),
},
})
}
}
}
None => {
warn!("Could not get start time of step, skipping");
return None;
}
}
}
ssq::Step::Freeze { start, end, row } => {
let time = get_time_from_beats(*start, &tempo_changes.0)?;
let end_time = get_time_from_beats(*end, &tempo_changes.0)?;
let time = get_time_from_beats(*start, &tempo_changes.0);
let end_time = get_time_from_beats(*end, &tempo_changes.0);
let columns: Vec<bool> = row.clone().into();
match (time, end_time) {
(Some(time), Some(end_time)) => {
let columns: Vec<bool> = row.clone().into();
for (column, active) in columns.iter().enumerate() {
if *active {
hit_objects.push(beatmap::HitObject::Hold {
column: column as u8,
columns: num_columns,
time,
end_time,
hit_sound: beatmap::HitSound {
normal: true,
whistle: false,
finish: true,
clap: false,
},
new_combo: false,
skip_combo_colours: 0,
hit_sample: beatmap::HitSample {
normal_set: 0,
addition_set: 0,
index: 0,
volume: 0,
filename: "".to_string(),
},
})
for (column, active) in columns.iter().enumerate() {
if *active {
hit_objects.push(beatmap::HitObject::Hold {
column: column as u8,
columns: num_columns,
time,
end_time,
hit_sound: beatmap::HitSound {
normal: true,
whistle: false,
finish: true,
clap: false,
},
new_combo: false,
skip_combo_colours: 0,
hit_sample: beatmap::HitSample {
normal_set: 0,
addition_set: 0,
index: 0,
volume: 0,
filename: "".to_string(),
},
})
}
}
}
(None, Some(_)) => {
warn!("Could not get start time of freeze, skipping");
return None;
}
(Some(_), None) => {
warn!("Could not get end time of freeze, skipping");
return None;
}
(None, None) => {
warn!("Could not get start and end time of freeze, skipping");
return None;
}
}
}
@ -288,7 +312,7 @@ impl ssq::Step {
}
}
Ok(hit_objects)
Some(hit_objects)
}
}
@ -363,12 +387,13 @@ impl ssq::SSQ {
ShockStepGenerator::new(chart.difficulty.players * 4, config.shock_action.clone());
for step in &chart.steps.0 {
trace!("Converting {:?} to hit object", step);
let mut step_hit_objects = step.to_hit_objects(
if let Some(mut step_hit_objects) = step.to_hit_objects(
chart.difficulty.players * 4,
&self.tempo_changes,
&mut shock_step_generator,
)?;
hit_objects.0.append(&mut step_hit_objects);
) {
hit_objects.0.append(&mut step_hit_objects);
}
}
let converted_chart = ConvertedChart {

View File

@ -1,7 +1,7 @@
use std::convert::From;
use std::fmt;
use anyhow::{anyhow, Result};
use anyhow::Result;
use log::{debug, info, trace, warn};
use nom::bytes::complete::take;
use nom::multi::many0;
@ -126,27 +126,29 @@ impl Steps {
continue;
}
let last_step = match Self::find_last(Self(parsed_steps.clone()), &row) {
Ok(last_step) => last_step,
Err(err) => {
warn!("Could not add freeze arrow: {}; adding normal step", err);
parsed_steps.push(Step::Step { beats, row });
continue;
}
};
if FREEZE {
parsed_steps.push(Step::Freeze {
start: if let Step::Step { beats, .. } = parsed_steps[last_step] {
beats
} else {
unreachable!()
},
end: beats,
row,
});
match Self::find_last(Self(parsed_steps.clone()), &row) {
Some(last_step) => {
parsed_steps.push(Step::Freeze {
start: if let Step::Step { beats, .. } = parsed_steps[last_step]
{
beats
} else {
unreachable!()
},
end: beats,
row,
});
parsed_steps.remove(last_step);
parsed_steps.remove(last_step);
}
None => {
warn!(
"Could not find previous step for freeze, adding normal step"
);
parsed_steps.push(Step::Step { beats, row });
}
}
} else {
trace!("Freeze disabled, adding normal step");
parsed_steps.push(Step::Step { beats, row });
@ -173,16 +175,16 @@ impl Steps {
Ok((input, Self(parsed_steps)))
}
fn find_last(steps: Self, row: &Row) -> Result<usize> {
fn find_last(steps: Self, row: &Row) -> Option<usize> {
for i in (0..steps.0.len()).rev() {
if let Step::Step { row: step_row, .. } = &steps.0[i] {
if step_row.clone().intersects(row.clone()) {
return Ok(i);
return Some(i);
}
}
}
Err(anyhow!("No previous step found on that column"))
None
}
}