cursor.rs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #![allow(clippy::while_let_on_iterator)]
  2. use crate::core::delta::operation::{DeltaOperation, OperationAttributes};
  3. use crate::core::delta::DeltaOperations;
  4. use crate::core::interval::Interval;
  5. use crate::errors::{ErrorBuilder, OTError, OTErrorCode};
  6. use std::{cmp::min, iter::Enumerate, slice::Iter};
  7. /// A [OperationsCursor] is used to iterate the delta and return the corresponding delta.
  8. #[derive(Debug)]
  9. pub struct OperationsCursor<'a, T: OperationAttributes> {
  10. pub(crate) delta: &'a DeltaOperations<T>,
  11. pub(crate) origin_iv: Interval,
  12. pub(crate) consume_iv: Interval,
  13. pub(crate) consume_count: usize,
  14. pub(crate) op_offset: usize,
  15. iter: Enumerate<Iter<'a, DeltaOperation<T>>>,
  16. next_op: Option<DeltaOperation<T>>,
  17. }
  18. impl<'a, T> OperationsCursor<'a, T>
  19. where
  20. T: OperationAttributes,
  21. {
  22. /// # Arguments
  23. ///
  24. /// * `delta`: The delta you want to iterate over.
  25. /// * `interval`: The range for the cursor movement.
  26. ///
  27. /// # Examples
  28. ///
  29. /// ```
  30. /// use lib_ot::core::{OperationsCursor, OperationIterator, Interval, DeltaOperation};
  31. /// use lib_ot::text_delta::DeltaTextOperations;
  32. /// let mut delta = DeltaTextOperations::default();
  33. /// delta.add(DeltaOperation::insert("123"));
  34. /// delta.add(DeltaOperation::insert("4"));
  35. ///
  36. /// let mut cursor = OperationsCursor::new(&delta, Interval::new(0, 3));
  37. /// assert_eq!(cursor.next_iv(), Interval::new(0,3));
  38. /// assert_eq!(cursor.next_with_len(Some(2)).unwrap(), DeltaOperation::insert("12"));
  39. /// assert_eq!(cursor.get_next_op().unwrap(), DeltaOperation::insert("3"));
  40. /// assert_eq!(cursor.get_next_op(), None);
  41. /// ```
  42. pub fn new(delta: &'a DeltaOperations<T>, interval: Interval) -> OperationsCursor<'a, T> {
  43. // debug_assert!(interval.start <= delta.target_len);
  44. let mut cursor = Self {
  45. delta,
  46. origin_iv: interval,
  47. consume_iv: interval,
  48. consume_count: 0,
  49. op_offset: 0,
  50. iter: delta.ops.iter().enumerate(),
  51. next_op: None,
  52. };
  53. cursor.descend(0);
  54. cursor
  55. }
  56. /// Returns the next operation interval
  57. pub fn next_iv(&self) -> Interval {
  58. self
  59. .next_iv_with_len(None)
  60. .unwrap_or_else(|| Interval::new(0, 0))
  61. }
  62. /// Returns the next operation
  63. pub fn get_next_op(&mut self) -> Option<DeltaOperation<T>> {
  64. self.next_with_len(None)
  65. }
  66. /// Returns the reference of the next operation
  67. pub fn next_op(&self) -> Option<&DeltaOperation<T>> {
  68. let mut next_op = self.next_op.as_ref();
  69. if next_op.is_none() {
  70. let mut offset = 0;
  71. for op in &self.delta.ops {
  72. offset += op.len();
  73. if offset > self.consume_count {
  74. next_op = Some(op);
  75. break;
  76. }
  77. }
  78. }
  79. next_op
  80. }
  81. /// # Arguments
  82. ///
  83. /// * `expected_len`: Return the next operation with the specified length.
  84. ///
  85. ///
  86. pub fn next_with_len(&mut self, expected_len: Option<usize>) -> Option<DeltaOperation<T>> {
  87. let mut find_op = None;
  88. let holder = self.next_op.clone();
  89. let mut next_op = holder.as_ref();
  90. if next_op.is_none() {
  91. next_op = find_next(self);
  92. }
  93. let mut consume_len = 0;
  94. while find_op.is_none() && next_op.is_some() {
  95. let op = next_op.take().unwrap();
  96. let interval = self
  97. .next_iv_with_len(expected_len)
  98. .unwrap_or_else(|| Interval::new(0, 0));
  99. // cache the op if the interval is empty. e.g. last_op_before(Some(0))
  100. if interval.is_empty() {
  101. self.next_op = Some(op.clone());
  102. break;
  103. }
  104. find_op = op.shrink(interval);
  105. let suffix = Interval::new(0, op.len()).suffix(interval);
  106. if suffix.is_empty() {
  107. self.next_op = None;
  108. } else {
  109. self.next_op = op.shrink(suffix);
  110. }
  111. consume_len += interval.end;
  112. self.consume_count += interval.end;
  113. self.consume_iv.start = self.consume_count;
  114. // continue to find the op in next iteration
  115. if find_op.is_none() {
  116. next_op = find_next(self);
  117. }
  118. }
  119. if find_op.is_some() {
  120. if let Some(end) = expected_len {
  121. // try to find the next op before the index if consume_len less than index
  122. if end > consume_len && self.has_next() {
  123. return self.next_with_len(Some(end - consume_len));
  124. }
  125. }
  126. }
  127. find_op
  128. }
  129. pub fn has_next(&self) -> bool {
  130. self.next_op().is_some()
  131. }
  132. /// Finds the op within the current offset.
  133. /// This function sets the start of the consume_iv to the offset, updates the consume_count
  134. /// and the next_op reference.
  135. ///
  136. /// # Arguments
  137. ///
  138. /// * `offset`: Represents the offset of the delta string, in Utf16CodeUnit unit.
  139. fn descend(&mut self, offset: usize) {
  140. self.consume_iv.start += offset;
  141. if self.consume_count >= self.consume_iv.start {
  142. return;
  143. }
  144. while let Some((o_index, op)) = self.iter.next() {
  145. self.op_offset = o_index;
  146. let start = self.consume_count;
  147. let end = start + op.len();
  148. let intersect = Interval::new(start, end).intersect(self.consume_iv);
  149. if intersect.is_empty() {
  150. self.consume_count += op.len();
  151. } else {
  152. self.next_op = Some(op.clone());
  153. break;
  154. }
  155. }
  156. }
  157. fn next_iv_with_len(&self, expected_len: Option<usize>) -> Option<Interval> {
  158. let op = self.next_op()?;
  159. let start = self.consume_count;
  160. let end = match expected_len {
  161. None => self.consume_count + op.len(),
  162. Some(expected_len) => self.consume_count + min(expected_len, op.len()),
  163. };
  164. let intersect = Interval::new(start, end).intersect(self.consume_iv);
  165. let interval = intersect.translate_neg(start);
  166. Some(interval)
  167. }
  168. }
  169. fn find_next<'a, T>(cursor: &mut OperationsCursor<'a, T>) -> Option<&'a DeltaOperation<T>>
  170. where
  171. T: OperationAttributes,
  172. {
  173. match cursor.iter.next() {
  174. None => None,
  175. Some((o_index, op)) => {
  176. cursor.op_offset = o_index;
  177. Some(op)
  178. },
  179. }
  180. }
  181. type SeekResult = Result<(), OTError>;
  182. pub trait Metric {
  183. fn seek<T: OperationAttributes>(cursor: &mut OperationsCursor<T>, offset: usize) -> SeekResult;
  184. }
  185. /// [OpMetric] is used by [DeltaIterator] for seeking operations
  186. /// The unit of the movement is Operation
  187. pub struct OpMetric();
  188. impl Metric for OpMetric {
  189. fn seek<T: OperationAttributes>(
  190. cursor: &mut OperationsCursor<T>,
  191. op_offset: usize,
  192. ) -> SeekResult {
  193. check_bound(cursor.op_offset, op_offset)?;
  194. let mut seek_cursor = OperationsCursor::new(cursor.delta, cursor.origin_iv);
  195. while let Some((_, op)) = seek_cursor.iter.next() {
  196. cursor.descend(op.len());
  197. if cursor.op_offset >= op_offset {
  198. break;
  199. }
  200. }
  201. Ok(())
  202. }
  203. }
  204. /// [Utf16CodeUnitMetric] is used by [OperationIterator] for seeking operations.
  205. /// The unit of the movement is Utf16CodeUnit
  206. pub struct Utf16CodeUnitMetric();
  207. impl Metric for Utf16CodeUnitMetric {
  208. fn seek<T: OperationAttributes>(cursor: &mut OperationsCursor<T>, offset: usize) -> SeekResult {
  209. if offset > 0 {
  210. check_bound(cursor.consume_count, offset)?;
  211. let _ = cursor.next_with_len(Some(offset));
  212. }
  213. Ok(())
  214. }
  215. }
  216. fn check_bound(current: usize, target: usize) -> Result<(), OTError> {
  217. debug_assert!(current <= target);
  218. if current > target {
  219. let msg = format!("{} should be greater than current: {}", target, current);
  220. return Err(
  221. ErrorBuilder::new(OTErrorCode::IncompatibleLength)
  222. .msg(&msg)
  223. .build(),
  224. );
  225. }
  226. Ok(())
  227. }