refactor: better insert content trait

This commit is contained in:
Zixuan Chen 2022-07-15 20:32:35 +08:00
parent 81ccf8fc4a
commit ad7a1c54ce
2 changed files with 33 additions and 9 deletions

View file

@ -4,32 +4,56 @@ use crate::id::ID;
use rle::{HasLength, Mergable, Sliceable};
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum ContentTypeID {
Container,
Text,
Custom(u16),
}
pub trait MergeableInsertContent {
pub trait MergeableContent {
fn is_mergable_content(&self, other: &dyn InsertContent) -> bool;
fn merge_content(&mut self, other: &dyn InsertContent);
}
pub trait InsertContent: HasLength + std::fmt::Debug + Any + MergeableInsertContent {
fn id(&self) -> ContentTypeID;
fn slice(&self, from: usize, to: usize) -> Box<dyn InsertContent>;
pub trait SliceableContent {
fn slice_content(&self, from: usize, to: usize) -> Box<dyn InsertContent>;
}
pub trait CloneContent {
fn clone_content(&self) -> Box<dyn InsertContent>;
}
impl<T: Mergable + Any> MergeableInsertContent for T {
pub trait InsertContent:
HasLength + std::fmt::Debug + Any + MergeableContent + SliceableContent + CloneContent
{
fn id(&self) -> ContentTypeID;
}
impl<T: Sliceable + InsertContent> SliceableContent for T {
fn slice_content(&self, from: usize, to: usize) -> Box<dyn InsertContent> {
Box::new(self.slice(from, to))
}
}
impl<T: Clone + InsertContent> CloneContent for T {
fn clone_content(&self) -> Box<dyn InsertContent> {
Box::new(self.clone())
}
}
impl<T: Mergable + Any> MergeableContent for T {
fn is_mergable_content(&self, other: &dyn InsertContent) -> bool {
if self.type_id() == other.type_id() {
self.is_mergable(unsafe { &*(other as *const dyn Any as *const T) }, &())
self.is_mergable(
unsafe { &*(other as *const dyn InsertContent as *const T) },
&(),
)
} else {
false
}
}
fn merge_content(&mut self, other: &dyn InsertContent) {
let other = unsafe { &*(other as *const dyn Any as *const T) };
let other = unsafe { &*(other as *const dyn InsertContent as *const T) };
self.merge(other, &());
}
}
@ -40,7 +64,7 @@ pub mod content {
let t = TypeId::of::<T>();
let concrete = content.type_id();
if t == concrete {
Some(unsafe { &*(content as *const dyn Any as *const T) })
Some(unsafe { &*(content as *const dyn InsertContent as *const T) })
} else {
None
}

View file

@ -133,7 +133,7 @@ impl<T: Mergable<Cfg> + HasLength, Cfg> RleVec<T, Cfg> {
}
pub fn slice_merged(&self, range: Range<usize>) -> &[T] {
todo!()
&self.vec[range]
}
}