run-highlighter/src/splits_logic.rs

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('-')
}
}