use crate::rope_binding::bound_rope::*;
use crate::rope_binding::rope_binding::*;
use futures::prelude::*;
use futures::stream;
use futures::task::{Poll};
use flo_rope::*;
use std::iter;
use std::collections::{VecDeque};
pub trait BoundRopeExt<Cell, Attribute>
where
Cell: 'static+Send+Unpin+Clone+PartialEq,
Attribute: 'static+Send+Sync+Clone+Unpin+PartialEq+Default {
fn chain<OtherRope: BoundRope<Cell, Attribute>>(&self, other: &OtherRope) -> RopeBinding<Cell, Attribute>;
fn map<NewCell, MapFn: 'static+Send+Fn(Cell) -> NewCell>(&self, map_fn: MapFn) -> RopeBinding<NewCell, Attribute>
where NewCell: 'static+Send+Unpin+Clone+PartialEq;
}
impl<Cell, Attribute, TRope> BoundRopeExt<Cell, Attribute> for TRope
where
Cell: 'static+Send+Unpin+Clone+PartialEq,
Attribute: 'static+Send+Sync+Clone+Unpin+PartialEq+Default,
TRope: BoundRope<Cell, Attribute> {
fn chain<OtherRope: BoundRope<Cell, Attribute>>(&self, other: &OtherRope) -> RopeBinding<Cell, Attribute> {
let mut follow_left = Some(self.follow_changes_retained());
let mut follow_right = Some(other.follow_changes_retained());
let mut pending = VecDeque::new();
let mut concatenator = RopeConcatenator::new();
let concat_stream = stream::poll_fn(move |ctxt| {
if let Some(next) = pending.pop_front() {
return Poll::Ready(Some(next));
}
let poll_left = follow_left.as_mut().map(|left| left.poll_next_unpin(ctxt));
match poll_left {
None => { }
Some(Poll::Pending) => { }
Some(Poll::Ready(None)) => { follow_left = None; }
Some(Poll::Ready(Some(action))) => {
for action in concatenator.send_left(iter::once(action)) {
pending.push_back(action);
}
if let Some(next) = pending.pop_front() { return Poll::Ready(Some(next)); }
}
}
let poll_right = follow_right.as_mut().map(|right| right.poll_next_unpin(ctxt));
match poll_right {
None => { }
Some(Poll::Pending) => { }
Some(Poll::Ready(None)) => { follow_right = None; }
Some(Poll::Ready(Some(action))) => {
for action in concatenator.send_right(iter::once(action)) {
pending.push_back(action);
}
if let Some(next) = pending.pop_front() { return Poll::Ready(Some(next)); }
}
}
Poll::Pending
});
RopeBinding::from_stream(concat_stream)
}
fn map<NewCell, MapFn: 'static+Send+Fn(Cell) -> NewCell>(&self, map_fn: MapFn) -> RopeBinding<NewCell, Attribute>
where NewCell: 'static+Send+Unpin+Clone+PartialEq {
let mut changes = self.follow_changes();
let mapped_stream = stream::poll_fn(move |ctxt| {
use RopeAction::*;
match changes.poll_next_unpin(ctxt) {
Poll::Ready(None) => Poll::Ready(None),
Poll::Pending => Poll::Pending,
Poll::Ready(Some(Replace(range, cells))) => Poll::Ready(Some(Replace(range, cells.into_iter().map(&map_fn).collect()))),
Poll::Ready(Some(SetAttributes(range, attributes))) => Poll::Ready(Some(SetAttributes(range, attributes))),
Poll::Ready(Some(ReplaceAttributes(range, cells, attributes))) => Poll::Ready(Some(ReplaceAttributes(range, cells.into_iter().map(&map_fn).collect(), attributes)))
}
});
RopeBinding::from_stream(mapped_stream)
}
}