use std::{fmt::Debug, ops::Range}; use num::{cast, Integer, NumCast}; pub trait Mergable { fn is_mergable(&self, _other: &Self, _conf: &Cfg) -> bool where Self: Sized, { false } fn merge(&mut self, _other: &Self, _conf: &Cfg) where Self: Sized, { unreachable!() } } pub trait Sliceable { fn slice(&self, from: usize, to: usize) -> Self; } #[derive(Debug, Clone, Copy)] pub struct Slice<'a, T> { pub value: &'a T, pub start: usize, pub end: usize, } impl Slice<'_, T> { pub fn into_inner(&self) -> T { self.value.slice(self.start, self.end) } } #[allow(clippy::len_without_is_empty)] pub trait HasLength { /// if the content is deleted, len should be zero fn len(&self) -> usize; /// the actual length of the value, cannot be affected by delete state fn content_len(&self) -> usize { self.len() } } pub trait Rle: HasLength + Sliceable + Mergable + Debug + Clone {} impl + Debug + Clone, Cfg> Rle for T {} impl Sliceable for Range { fn slice(&self, start: usize, end: usize) -> Self { self.start + cast(start).unwrap()..self.start + cast(end).unwrap() } } impl + Copy> Mergable for Range { fn is_mergable(&self, other: &Self, _: &()) -> bool { other.start <= self.end && other.start >= self.start } fn merge(&mut self, other: &Self, _conf: &()) where Self: Sized, { self.end = other.end; } } impl HasLength for Range { fn len(&self) -> usize { cast(self.end - self.start).unwrap() } }