75 lines
1.9 KiB
Rust
Executable File
75 lines
1.9 KiB
Rust
Executable File
use livesplit::model::Segment;
|
|
use livesplit::Run;
|
|
|
|
pub trait SplitsLogic {
|
|
fn subsplits(&self) -> Option<Vec<SplitCategory<'_>>>;
|
|
}
|
|
|
|
impl SplitsLogic for Run {
|
|
fn subsplits(&self) -> Option<Vec<SplitCategory<'_>>> {
|
|
let mut output = Vec::new();
|
|
let mut current_category = SplitCategory::default();
|
|
for segment in &self.segments.segments {
|
|
if !segment.is_subsplit() {
|
|
if current_category.splits.is_empty() {
|
|
return None;
|
|
} else {
|
|
if let Some(category) = segment.category_name() {
|
|
current_category.name = category;
|
|
}
|
|
|
|
current_category.splits.push(segment);
|
|
|
|
let mut insert = SplitCategory::default();
|
|
std::mem::swap(&mut insert, &mut current_category);
|
|
|
|
output.push(insert);
|
|
|
|
continue;
|
|
}
|
|
}
|
|
|
|
current_category.splits.push(segment);
|
|
}
|
|
|
|
Some(output)
|
|
}
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct SplitCategory<'a> {
|
|
pub name: &'a str,
|
|
pub splits: Vec<&'a Segment>,
|
|
}
|
|
|
|
pub trait SegmentLogic {
|
|
fn clean_name(&self) -> &str;
|
|
fn category_name(&self) -> Option<&str>;
|
|
fn is_subsplit(&self) -> bool;
|
|
}
|
|
|
|
impl SegmentLogic for Segment {
|
|
fn clean_name(&self) -> &str {
|
|
let mut output = &*self.name;
|
|
|
|
if output.chars().filter(|&c| c == '}' || c == '{').count() > 1 {
|
|
if let Some(idx) = output.find('}') {
|
|
output = output[idx + 1..].trim_start();
|
|
}
|
|
}
|
|
|
|
output.trim_start_matches(|c| c == '-')
|
|
}
|
|
|
|
fn category_name(&self) -> Option<&str> {
|
|
let open = self.name.find('{')?;
|
|
let close = self.name[open + 1..].find('}')? + open + 1;
|
|
|
|
Some(&self.name[open + 1..close])
|
|
}
|
|
|
|
fn is_subsplit(&self) -> bool {
|
|
self.name.starts_with('-')
|
|
}
|
|
}
|