use crate::api::*;
use std::marker::{PhantomData};
pub struct RopeConcatenator<Cell, Attribute> {
cell: PhantomData<Cell>,
attribute: PhantomData<Attribute>,
left_len: usize
}
impl<Cell, Attribute> RopeConcatenator<Cell, Attribute> {
pub fn new() -> RopeConcatenator<Cell, Attribute>{
RopeConcatenator {
cell: PhantomData,
attribute: PhantomData,
left_len: 0
}
}
pub fn send_left<'a, ActionIter: 'a+IntoIterator<Item=RopeAction<Cell, Attribute>>>(&'a mut self, items: ActionIter) -> impl 'a+Iterator<Item=RopeAction<Cell, Attribute>> {
items.into_iter()
.map(|item| {
use RopeAction::*;
let (range, new_len) = match &item {
Replace(range, cells) => (range, cells.len()),
ReplaceAttributes(range, cells, _attributes) => (range, cells.len()),
SetAttributes(range, _attributes) => (range, range.len()),
};
debug_assert!(range.start <= self.left_len);
debug_assert!(range.end <= self.left_len);
if new_len > range.len() {
self.left_len += new_len - range.len();
} else if new_len < range.len() {
debug_assert!(range.len() - new_len <= self.left_len);
self.left_len -= range.len() - new_len;
}
item
})
}
pub fn send_right<'a, ActionIter: 'a+IntoIterator<Item=RopeAction<Cell, Attribute>>>(&'a mut self, items: ActionIter) -> impl 'a+Iterator<Item=RopeAction<Cell, Attribute>> {
let left_len = self.left_len;
items.into_iter()
.map(move |item| {
use RopeAction::*;
match item {
Replace(range, cells) => Replace((range.start+left_len)..(range.end+left_len), cells),
ReplaceAttributes(range, cells, attributes) => ReplaceAttributes((range.start+left_len)..(range.end+left_len), cells, attributes),
SetAttributes(range, attributes) => SetAttributes((range.start+left_len)..(range.end+left_len), attributes),
}
})
}
}