Use loop instead of iter

This commit is contained in:
Andras Schmelczer 2025-06-14 14:24:48 +01:00
commit 44697164a0
No known key found for this signature in database
GPG key ID: FC8F2C3D3D1A718C
2 changed files with 73 additions and 70 deletions

View file

@ -3,6 +3,7 @@ mod edited_text;
mod merge_context; mod merge_context;
mod operation; mod operation;
mod ordered_operation; mod ordered_operation;
mod utils;
pub use cursor::{CursorPosition, TextWithCursors}; pub use cursor::{CursorPosition, TextWithCursors};
pub use edited_text::EditedText; pub use edited_text::EditedText;

View file

@ -9,7 +9,7 @@ use crate::{
utils::{cook_operations::cook_operations, elongate_operations::elongate_operations}, utils::{cook_operations::cook_operations, elongate_operations::elongate_operations},
}, },
tokenizer::{Tokenizer, word_tokenizer::word_tokenizer}, tokenizer::{Tokenizer, word_tokenizer::word_tokenizer},
utils::{merge_iters::MergeSorted as _, side::Side, string_builder::StringBuilder}, utils::{side::Side, string_builder::StringBuilder},
}; };
/// A text document and a sequence of operations that can be applied to the text /// A text document and a sequence of operations that can be applied to the text
@ -117,34 +117,37 @@ where
let mut left_cursors = self.cursors.into_iter().peekable(); let mut left_cursors = self.cursors.into_iter().peekable();
let mut right_cursors = other.cursors.into_iter().peekable(); let mut right_cursors = other.cursors.into_iter().peekable();
let merged_operations: Vec<OrderedOperation<T>> = self let mut merged_operations: Vec<OrderedOperation<T>> =
.operations Vec::with_capacity(self.operations.len() + other.operations.len());
.into_iter()
// The current text is always the left; the other operation is the right side. let mut left_iter = self.operations.into_iter();
.map(|op| (op, Side::Left)) let mut right_iter = other.operations.into_iter();
.merge_sorted_by_key(
other.operations.into_iter().map(|op| (op, Side::Right)), let mut maybe_left_op = left_iter.next();
|(operation, _)| { let mut maybe_right_op = right_iter.next();
(
operation.order, loop {
operation.operation.start_index(), let (side, OrderedOperation { operation, order }) =
// Make sure that the ordering is deterministic regardless which text match (maybe_left_op.clone(), maybe_right_op.clone()) {
// is left or right. (Some(left_op), Some(right_op)) => {
match &operation.operation { if left_op < right_op {
Operation::Equal { index, .. } => index.to_string(), (Side::Left, left_op)
Operation::Insert { text, .. } => text } else {
.iter() (Side::Right, right_op)
.map(crate::tokenizer::token::Token::original) }
.collect::<String>(), }
Operation::Delete {
deleted_character_count, (Some(left_op), None) => (Side::Left, left_op),
.. (None, Some(right_op)) => (Side::Right, right_op),
} => deleted_character_count.to_string(), (None, None) => break,
}, };
)
}, if side == Side::Left {
) maybe_left_op = left_iter.next();
.flat_map(|(OrderedOperation { order, operation }, side)| { } else {
maybe_right_op = right_iter.next();
}
let original_start = operation.start_index() as i64; let original_start = operation.start_index() as i64;
let original_end = operation.end_index(); let original_end = operation.end_index();
let original_length = operation.len() as i64; let original_length = operation.len() as i64;
@ -160,10 +163,9 @@ where
), ),
}; };
if let Some(ref op @ (Operation::Insert { .. } | Operation::Equal { .. })) = result if let Some(ref op @ (Operation::Insert { .. } | Operation::Equal { .. })) = result {
{ let shift =
let shift = op.start_index() as i64 - original_start + op.len() as i64 op.start_index() as i64 - original_start + op.len() as i64 - original_length;
- original_length;
match side { match side {
Side::Left => { Side::Left => {
while let Some(cursor) = while let Some(cursor) =
@ -176,8 +178,8 @@ where
} }
} }
Side::Right => { Side::Right => {
while let Some(cursor) = right_cursors while let Some(cursor) =
.next_if(|cursor| cursor.char_index <= original_end + 1) right_cursors.next_if(|cursor| cursor.char_index <= original_end + 1)
{ {
merged_cursors.push(cursor.with_index( merged_cursors.push(cursor.with_index(
(op.start_index() as i64).max(cursor.char_index as i64 + shift) (op.start_index() as i64).max(cursor.char_index as i64 + shift)
@ -188,11 +190,11 @@ where
} }
} }
result merged_operations.extend(result.into_iter().map(|op| OrderedOperation {
.map(|operation| OrderedOperation { order, operation }) order,
.into_iter() operation: op,
}) }));
.collect(); }
let last_index = merged_operations let last_index = merged_operations
.iter() .iter()