use crate::command::Position;
#[derive(Debug, Clone)]
pub struct Path(pub Vec<Position>);
type SplitPositionedPath<'a> = (
&'a mut Position,
&'a mut Option<Position>,
&'a mut [Option<Position>],
);
type SplitPositionedPathWithPrevOption<'a> = (
&'a mut Option<Position>,
&'a mut Option<Position>,
&'a mut [Option<Position>],
);
impl Path {
pub fn take(self) -> crate::Path {
crate::Path(self.0.into_iter().map(|p| p.command).collect())
}
pub fn split_mut(
path: &mut [Option<Position>],
index: usize,
) -> Option<SplitPositionedPath<'_>> {
let (prev, item, next_paths) = Self::split_mut_with_prev_option(path, index)?;
let Some(prev) = prev else {
return None;
};
Some((prev, item, next_paths))
}
pub fn split_mut_with_prev_option(
path: &mut [Option<Position>],
index: usize,
) -> Option<SplitPositionedPathWithPrevOption<'_>> {
let (prev, next_inclusive) = path.split_at_mut(index);
let Some((item, next_paths)) = next_inclusive.split_first_mut() else {
return None;
};
if item.is_none() {
return None;
}
let Some(prev) = prev.iter_mut().rev().find(|p| p.is_some()) else {
return None;
};
Some((prev, item, next_paths))
}
}
impl From<Path> for crate::Path {
fn from(value: Path) -> Self {
value.take()
}
}