use super::cursor::*; use crate::core::delta::{Delta, NEW_LINE}; use crate::core::interval::Interval; use crate::core::operation::{Attributes, Operation}; use crate::rich_text::RichTextAttributes; use std::ops::{Deref, DerefMut}; pub(crate) const MAX_IV_LEN: usize = i32::MAX as usize; pub struct DeltaIterator<'a, T: Attributes> { cursor: DeltaCursor<'a, T>, } impl<'a, T> DeltaIterator<'a, T> where T: Attributes, { pub fn new(delta: &'a Delta) -> Self { let interval = Interval::new(0, MAX_IV_LEN); Self::from_interval(delta, interval) } pub fn from_offset(delta: &'a Delta, offset: usize) -> Self { let interval = Interval::new(0, MAX_IV_LEN); let mut iter = Self::from_interval(delta, interval); iter.seek::(offset); iter } pub fn from_interval(delta: &'a Delta, interval: Interval) -> Self { let cursor = DeltaCursor::new(delta, interval); Self { cursor } } pub fn ops(&mut self) -> Vec> { self.collect::>() } pub fn next_op_len(&self) -> Option { let interval = self.cursor.next_iv(); if interval.is_empty() { None } else { Some(interval.size()) } } pub fn next_op(&mut self) -> Option> { self.cursor.get_next_op() } pub fn next_op_with_len(&mut self, len: usize) -> Option> { self.cursor.next_with_len(Some(len)) } // find next op contains NEW_LINE pub fn next_op_with_newline(&mut self) -> Option<(Operation, usize)> { let mut offset = 0; while self.has_next() { if let Some(op) = self.next_op() { if OpNewline::parse(&op).is_contain() { return Some((op, offset)); } offset += op.len(); } } None } pub fn seek(&mut self, index: usize) { match M::seek(&mut self.cursor, index) { Ok(_) => {} Err(e) => log::error!("Seek fail: {:?}", e), } } pub fn has_next(&self) -> bool { self.cursor.has_next() } pub fn is_next_insert(&self) -> bool { match self.cursor.next_op() { None => false, Some(op) => op.is_insert(), } } pub fn is_next_retain(&self) -> bool { match self.cursor.next_op() { None => false, Some(op) => op.is_retain(), } } pub fn is_next_delete(&self) -> bool { match self.cursor.next_op() { None => false, Some(op) => op.is_delete(), } } } impl<'a, T> Iterator for DeltaIterator<'a, T> where T: Attributes, { type Item = Operation; fn next(&mut self) -> Option { self.next_op() } } pub fn is_empty_line_at_index(delta: &Delta, index: usize) -> bool { let mut iter = DeltaIterator::new(delta); let (prev, next) = (iter.next_op_with_len(index), iter.next_op()); if prev.is_none() { return true; } if next.is_none() { return false; } let prev = prev.unwrap(); let next = next.unwrap(); OpNewline::parse(&prev).is_end() && OpNewline::parse(&next).is_start() } pub struct AttributesIter<'a, T: Attributes> { delta_iter: DeltaIterator<'a, T>, } impl<'a, T> AttributesIter<'a, T> where T: Attributes, { pub fn new(delta: &'a Delta) -> Self { let interval = Interval::new(0, usize::MAX); Self::from_interval(delta, interval) } pub fn from_interval(delta: &'a Delta, interval: Interval) -> Self { let delta_iter = DeltaIterator::from_interval(delta, interval); Self { delta_iter } } pub fn next_or_empty(&mut self) -> T { match self.next() { None => T::default(), Some((_, attributes)) => attributes, } } } impl<'a, T> Deref for AttributesIter<'a, T> where T: Attributes, { type Target = DeltaIterator<'a, T>; fn deref(&self) -> &Self::Target { &self.delta_iter } } impl<'a, T> DerefMut for AttributesIter<'a, T> where T: Attributes, { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.delta_iter } } impl<'a, T> Iterator for AttributesIter<'a, T> where T: Attributes, { type Item = (usize, T); fn next(&mut self) -> Option { let next_op = self.delta_iter.next_op(); next_op.as_ref()?; let mut length: usize = 0; let mut attributes = T::default(); match next_op.unwrap() { Operation::::Delete(_n) => {} Operation::::Retain(retain) => { tracing::trace!("extend retain attributes with {} ", &retain.attributes); attributes.extend_other(retain.attributes.clone()); length = retain.n; } Operation::::Insert(insert) => { tracing::trace!("extend insert attributes with {} ", &insert.attributes); attributes.extend_other(insert.attributes.clone()); length = insert.utf16_size(); } } Some((length, attributes)) } } #[derive(PartialEq, Eq)] pub enum OpNewline { Start, End, Contain, Equal, NotFound, } impl OpNewline { pub fn parse(op: &Operation) -> OpNewline { let s = op.get_data(); if s == NEW_LINE { return OpNewline::Equal; } if s.starts_with(NEW_LINE) { return OpNewline::Start; } if s.ends_with(NEW_LINE) { return OpNewline::End; } if s.contains(NEW_LINE) { return OpNewline::Contain; } OpNewline::NotFound } pub fn is_start(&self) -> bool { self == &OpNewline::Start || self.is_equal() } pub fn is_end(&self) -> bool { self == &OpNewline::End || self.is_equal() } pub fn is_not_found(&self) -> bool { self == &OpNewline::NotFound } pub fn is_contain(&self) -> bool { self.is_start() || self.is_end() || self.is_equal() || self == &OpNewline::Contain } pub fn is_equal(&self) -> bool { self == &OpNewline::Equal } }