use crate::handle::Handle;
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct PathId(pub u64);
crate::impl_space_usage_stack_newtype!(PathId);
impl crate::packed::PackedElement for PathId {
#[inline]
fn unpack(v: u64) -> Self {
PathId(v)
}
#[inline]
fn pack(self) -> u64 {
self.0
}
}
pub trait PathStep: Sized + Copy + Eq {
fn handle(&self) -> Handle;
}
pub trait PathBase: Sized {
type Step: PathStep;
type StepIx: Sized + Copy + Eq;
fn len(&self) -> usize;
#[inline]
fn is_empty(&self) -> bool {
self.len() == 0
}
fn circular(&self) -> bool;
fn step_at(&self, index: Self::StepIx) -> Option<Self::Step>;
fn first_step(&self) -> Self::StepIx;
fn last_step(&self) -> Self::StepIx;
fn next_step(&self, step: Self::StepIx) -> Option<Self::Step>;
fn prev_step(&self, step: Self::StepIx) -> Option<Self::Step>;
}
pub trait PathSteps: PathBase {
type Steps: DoubleEndedIterator<Item = Self::Step>;
fn steps(self) -> Self::Steps;
fn contains(self, handle: Handle) -> bool {
self.steps().any(|s| s.handle() == handle)
}
}
pub trait MutPath: PathBase {
fn append_step(&mut self, handle: Handle) -> StepUpdate<Self::StepIx>;
fn prepend_step(&mut self, handle: Handle) -> StepUpdate<Self::StepIx>;
fn insert_step_after(
&mut self,
index: Self::StepIx,
handle: Handle,
) -> Option<StepUpdate<Self::StepIx>>;
fn remove_step(
&mut self,
index: Self::StepIx,
) -> Option<StepUpdate<Self::StepIx>>;
fn rewrite_segment(
&mut self,
from: Self::StepIx,
to: Self::StepIx,
new_segment: &[Handle],
) -> Option<(Self::StepIx, Self::StepIx, Vec<StepUpdate<Self::StepIx>>)>;
fn set_circularity(&mut self, circular: bool);
fn flip_step(
&mut self,
index: Self::StepIx,
) -> Option<Vec<StepUpdate<Self::StepIx>>>;
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum StepUpdate<StepIx: Sized + Copy + Eq> {
Insert { handle: Handle, step: StepIx },
Remove { handle: Handle, step: StepIx },
}
impl<StepIx: Sized + Copy + Eq> StepUpdate<StepIx> {
pub fn handle(&self) -> Handle {
match self {
StepUpdate::Insert { handle, .. } => *handle,
StepUpdate::Remove { handle, .. } => *handle,
}
}
pub fn step(&self) -> StepIx {
match self {
StepUpdate::Insert { step, .. } => *step,
StepUpdate::Remove { step, .. } => *step,
}
}
}
impl<'a, T> PathBase for &'a T
where
T: PathBase,
{
type Step = T::Step;
type StepIx = T::StepIx;
#[inline]
fn len(&self) -> usize {
<T as PathBase>::len(self)
}
#[inline]
fn circular(&self) -> bool {
<T as PathBase>::circular(self)
}
#[inline]
fn step_at(&self, index: Self::StepIx) -> Option<Self::Step> {
<T as PathBase>::step_at(self, index)
}
#[inline]
fn first_step(&self) -> Self::StepIx {
<T as PathBase>::first_step(self)
}
#[inline]
fn last_step(&self) -> Self::StepIx {
<T as PathBase>::last_step(self)
}
#[inline]
fn next_step(&self, step: Self::StepIx) -> Option<Self::Step> {
<T as PathBase>::next_step(self, step)
}
#[inline]
fn prev_step(&self, step: Self::StepIx) -> Option<Self::Step> {
<T as PathBase>::next_step(self, step)
}
}
impl<'a, T> PathBase for &'a mut T
where
T: PathBase,
{
type Step = T::Step;
type StepIx = T::StepIx;
#[inline]
fn len(&self) -> usize {
<T as PathBase>::len(self)
}
#[inline]
fn circular(&self) -> bool {
<T as PathBase>::circular(self)
}
#[inline]
fn step_at(&self, index: Self::StepIx) -> Option<Self::Step> {
<T as PathBase>::step_at(self, index)
}
#[inline]
fn first_step(&self) -> Self::StepIx {
<T as PathBase>::first_step(self)
}
#[inline]
fn last_step(&self) -> Self::StepIx {
<T as PathBase>::last_step(self)
}
#[inline]
fn next_step(&self, step: Self::StepIx) -> Option<Self::Step> {
<T as PathBase>::next_step(self, step)
}
#[inline]
fn prev_step(&self, step: Self::StepIx) -> Option<Self::Step> {
<T as PathBase>::next_step(self, step)
}
}