More generic lifetimes for iter_changes and added iter_all_changes
This commit is contained in:
parent
b98be24027
commit
12e7d5e4b0
5 changed files with 67 additions and 11 deletions
|
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
All notable changes to similar are documented here.
|
All notable changes to similar are documented here.
|
||||||
|
|
||||||
|
## 1.1.0
|
||||||
|
|
||||||
|
* More generic lifetimes for `iter_changes` and `iter_inline_changes`.
|
||||||
|
* Added `iter_all_changes` shortcut as this is commonly useful.
|
||||||
|
|
||||||
## 1.0.0
|
## 1.0.0
|
||||||
|
|
||||||
* Add `get_diff_ratio`.
|
* Add `get_diff_ratio`.
|
||||||
|
|
|
||||||
|
|
@ -174,12 +174,15 @@ impl<'s, T: DiffableStr + ?Sized> fmt::Display for InlineChange<'s, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn iter_inline_changes<'diff, T>(
|
pub(crate) fn iter_inline_changes<'x, 'diff, 'old, 'new, 'bufs, T>(
|
||||||
diff: &'diff TextDiff<'_, '_, '_, T>,
|
diff: &'diff TextDiff<'old, 'new, 'bufs, T>,
|
||||||
op: &DiffOp,
|
op: &DiffOp,
|
||||||
) -> impl Iterator<Item = InlineChange<'diff, T>>
|
) -> impl Iterator<Item = InlineChange<'x, T>> + 'diff
|
||||||
where
|
where
|
||||||
T: DiffableStr + ?Sized,
|
T: DiffableStr + ?Sized,
|
||||||
|
'x: 'diff,
|
||||||
|
'old: 'x,
|
||||||
|
'new: 'x,
|
||||||
{
|
{
|
||||||
let (tag, old_range, new_range) = op.as_tag_tuple();
|
let (tag, old_range, new_range) = op.as_tag_tuple();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -294,7 +294,15 @@ impl<'old, 'new, 'bufs, T: DiffableStr + ?Sized + 'old + 'new> TextDiff<'old, 'n
|
||||||
/// ways in which a change could be encoded (insert/delete vs replace), look
|
/// ways in which a change could be encoded (insert/delete vs replace), look
|
||||||
/// up the value from the appropriate slice and also handle correct index
|
/// up the value from the appropriate slice and also handle correct index
|
||||||
/// handling.
|
/// handling.
|
||||||
pub fn iter_changes(&self, op: &DiffOp) -> impl Iterator<Item = Change<'_, T>> {
|
pub fn iter_changes<'x, 'slf>(
|
||||||
|
&'slf self,
|
||||||
|
op: &DiffOp,
|
||||||
|
) -> impl Iterator<Item = Change<'x, T>> + 'slf
|
||||||
|
where
|
||||||
|
'x: 'slf,
|
||||||
|
'old: 'x,
|
||||||
|
'new: 'x,
|
||||||
|
{
|
||||||
op.iter_changes(self.old_slices(), self.new_slices())
|
op.iter_changes(self.old_slices(), self.new_slices())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -310,6 +318,22 @@ impl<'old, 'new, 'bufs, T: DiffableStr + ?Sized + 'old + 'new> TextDiff<'old, 'n
|
||||||
group_diff_ops(self.ops().to_vec(), n)
|
group_diff_ops(self.ops().to_vec(), n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Flattens out the diff into all changes.
|
||||||
|
///
|
||||||
|
/// This is a shortcut for combining [`TextDiff::ops`] with
|
||||||
|
/// [`TextDiff::iter_changes`].
|
||||||
|
pub fn iter_all_changes<'x, 'slf>(&'slf self) -> impl Iterator<Item = Change<'x, T>> + 'slf
|
||||||
|
where
|
||||||
|
'x: 'slf,
|
||||||
|
'old: 'x,
|
||||||
|
'new: 'x,
|
||||||
|
{
|
||||||
|
// unclear why this needs Box::new here. It seems to infer some really
|
||||||
|
// odd lifetimes I can't figure out how to work with.
|
||||||
|
Box::new(self.ops().iter().flat_map(move |op| self.iter_changes(&op)))
|
||||||
|
as Box<dyn Iterator<Item = _>>
|
||||||
|
}
|
||||||
|
|
||||||
/// Utility to return a unified diff formatter.
|
/// Utility to return a unified diff formatter.
|
||||||
pub fn unified_diff<'diff>(&'diff self) -> UnifiedDiff<'diff, 'old, 'new, 'bufs, T> {
|
pub fn unified_diff<'diff>(&'diff self) -> UnifiedDiff<'diff, 'old, 'new, 'bufs, T> {
|
||||||
UnifiedDiff::from_text_diff(self)
|
UnifiedDiff::from_text_diff(self)
|
||||||
|
|
@ -322,7 +346,15 @@ impl<'old, 'new, 'bufs, T: DiffableStr + ?Sized + 'old + 'new> TextDiff<'old, 'n
|
||||||
/// this function with regards to how it detects those inline changes
|
/// this function with regards to how it detects those inline changes
|
||||||
/// is currently not defined and will likely change over time.
|
/// is currently not defined and will likely change over time.
|
||||||
#[cfg(feature = "inline")]
|
#[cfg(feature = "inline")]
|
||||||
pub fn iter_inline_changes(&self, op: &DiffOp) -> impl Iterator<Item = InlineChange<'_, T>> {
|
pub fn iter_inline_changes<'x, 'slf>(
|
||||||
|
&'slf self,
|
||||||
|
op: &DiffOp,
|
||||||
|
) -> impl Iterator<Item = InlineChange<'x, T>> + 'slf
|
||||||
|
where
|
||||||
|
'x: 'slf,
|
||||||
|
'old: 'x,
|
||||||
|
'new: 'x,
|
||||||
|
{
|
||||||
inline::iter_inline_changes(self, op)
|
inline::iter_inline_changes(self, op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -492,3 +524,18 @@ fn test_get_close_matches() {
|
||||||
);
|
);
|
||||||
assert_eq!(matches, vec!["aulo", "hulu", "uulo", "zulo"]);
|
assert_eq!(matches, vec!["aulo", "hulu", "uulo", "zulo"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_lifetimes_on_iter() {
|
||||||
|
fn diff_lines<'x, T>(old: &'x T, new: &'x T) -> Vec<Change<'x, T::Output>>
|
||||||
|
where
|
||||||
|
T: DiffableStrRef + ?Sized,
|
||||||
|
{
|
||||||
|
TextDiff::from_lines(old, new).iter_all_changes().collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
let a = "1\n2\n3\n".to_string();
|
||||||
|
let b = "1\n99\n3\n".to_string();
|
||||||
|
let changes = diff_lines(&a, &b);
|
||||||
|
insta::assert_debug_snapshot!(&changes);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -247,15 +247,16 @@ impl DiffOp {
|
||||||
///
|
///
|
||||||
/// `old` and `new` are two indexable objects like the types you pass to
|
/// `old` and `new` are two indexable objects like the types you pass to
|
||||||
/// the diffing algorithm functions.
|
/// the diffing algorithm functions.
|
||||||
pub fn iter_changes<'x, Old, New, T>(
|
pub fn iter_changes<'x, 'lookup, Old, New, T>(
|
||||||
&self,
|
&self,
|
||||||
old: &'x Old,
|
old: &'lookup Old,
|
||||||
new: &'x New,
|
new: &'lookup New,
|
||||||
) -> impl Iterator<Item = Change<'x, T>>
|
) -> impl Iterator<Item = Change<'x, T>> + 'lookup
|
||||||
where
|
where
|
||||||
Old: Index<usize, Output = &'x T> + ?Sized,
|
Old: Index<usize, Output = &'x T> + ?Sized,
|
||||||
New: Index<usize, Output = &'x T> + ?Sized,
|
New: Index<usize, Output = &'x T> + ?Sized,
|
||||||
T: 'x + ?Sized,
|
T: 'x + ?Sized,
|
||||||
|
'x: 'lookup,
|
||||||
{
|
{
|
||||||
let (tag, old_range, new_range) = self.as_tag_tuple();
|
let (tag, old_range, new_range) = self.as_tag_tuple();
|
||||||
let mut old_index = old_range.start;
|
let mut old_index = old_range.start;
|
||||||
|
|
|
||||||
|
|
@ -240,11 +240,11 @@ impl<'diff, 'old, 'new, 'bufs, T: DiffableStr + ?Sized>
|
||||||
pub fn iter_changes(&self) -> impl Iterator<Item = Change<'_, T>> + '_ {
|
pub fn iter_changes(&self) -> impl Iterator<Item = Change<'_, T>> + '_ {
|
||||||
// unclear why this needs Box::new here. It seems to infer some really
|
// unclear why this needs Box::new here. It seems to infer some really
|
||||||
// odd lifetimes I can't figure out how to work with.
|
// odd lifetimes I can't figure out how to work with.
|
||||||
(Box::new(
|
Box::new(
|
||||||
self.ops()
|
self.ops()
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(move |op| self.diff.iter_changes(op)),
|
.flat_map(move |op| self.diff.iter_changes(op)),
|
||||||
)) as Box<dyn Iterator<Item = _>>
|
) as Box<dyn Iterator<Item = _>>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the hunk as bytes to the output stream.
|
/// Write the hunk as bytes to the output stream.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue