Remove ExactSizeIterator requirement on Transaction::change
Size hint is enough.
This commit is contained in:
parent
cd65a48635
commit
bf43fabf65
2 changed files with 31 additions and 31 deletions
|
@ -1,6 +1,4 @@
|
|||
use ropey::Rope;
|
||||
|
||||
use crate::{Change, Transaction};
|
||||
use crate::{Rope, Transaction};
|
||||
|
||||
/// Compares `old` and `new` to generate a [`Transaction`] describing
|
||||
/// the steps required to get from `old` to `new`.
|
||||
|
@ -25,34 +23,34 @@ pub fn compare_ropes(old: &Rope, new: &Rope) -> Transaction {
|
|||
// The current position of the change needs to be tracked to
|
||||
// construct the `Change`s.
|
||||
let mut pos = 0;
|
||||
let changes: Vec<Change> = diff
|
||||
.ops()
|
||||
.iter()
|
||||
.map(|op| op.as_tag_tuple())
|
||||
.filter_map(|(tag, old_range, new_range)| {
|
||||
// `old_pos..pos` is equivalent to `start..end` for where
|
||||
// the change should be applied.
|
||||
let old_pos = pos;
|
||||
pos += old_range.end - old_range.start;
|
||||
Transaction::change(
|
||||
old,
|
||||
diff.ops()
|
||||
.iter()
|
||||
.map(|op| op.as_tag_tuple())
|
||||
.filter_map(|(tag, old_range, new_range)| {
|
||||
// `old_pos..pos` is equivalent to `start..end` for where
|
||||
// the change should be applied.
|
||||
let old_pos = pos;
|
||||
pos += old_range.end - old_range.start;
|
||||
|
||||
match tag {
|
||||
// Semantically, inserts and replacements are the same thing.
|
||||
similar::DiffTag::Insert | similar::DiffTag::Replace => {
|
||||
// This is the text from the `new` rope that should be
|
||||
// inserted into `old`.
|
||||
let text: &str = {
|
||||
let start = new.char_to_byte(new_range.start);
|
||||
let end = new.char_to_byte(new_range.end);
|
||||
&new_converted[start..end]
|
||||
};
|
||||
Some((old_pos, pos, Some(text.into())))
|
||||
match tag {
|
||||
// Semantically, inserts and replacements are the same thing.
|
||||
similar::DiffTag::Insert | similar::DiffTag::Replace => {
|
||||
// This is the text from the `new` rope that should be
|
||||
// inserted into `old`.
|
||||
let text: &str = {
|
||||
let start = new.char_to_byte(new_range.start);
|
||||
let end = new.char_to_byte(new_range.end);
|
||||
&new_converted[start..end]
|
||||
};
|
||||
Some((old_pos, pos, Some(text.into())))
|
||||
}
|
||||
similar::DiffTag::Delete => Some((old_pos, pos, None)),
|
||||
similar::DiffTag::Equal => None,
|
||||
}
|
||||
similar::DiffTag::Delete => Some((old_pos, pos, None)),
|
||||
similar::DiffTag::Equal => None,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
Transaction::change(old, changes.into_iter())
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -473,11 +473,13 @@ impl Transaction {
|
|||
/// Generate a transaction from a set of changes.
|
||||
pub fn change<I>(doc: &Rope, changes: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = Change> + ExactSizeIterator,
|
||||
I: IntoIterator<Item = Change> + Iterator,
|
||||
{
|
||||
let len = doc.len_chars();
|
||||
|
||||
let mut changeset = ChangeSet::with_capacity(2 * changes.len() + 1); // rough estimate
|
||||
let (lower, upper) = changes.size_hint();
|
||||
let size = upper.unwrap_or(lower);
|
||||
let mut changeset = ChangeSet::with_capacity(2 * size + 1); // rough estimate
|
||||
|
||||
// TODO: verify ranges are ordered and not overlapping or change will panic.
|
||||
|
||||
|
|
Loading…
Reference in a new issue