Emit slices instead of indices
This commit is contained in:
parent
b48816e143
commit
ed5db344fb
1 changed files with 43 additions and 30 deletions
73
src/merge.rs
73
src/merge.rs
|
@ -1,32 +1,38 @@
|
||||||
use std::ops::Range;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use diff;
|
use diff;
|
||||||
use diff::Result::*;
|
use diff::Result::*;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq)]
|
||||||
struct Chunk(Range<usize>, Range<usize>);
|
struct Chunk<'a, Item: 'a + Debug + PartialEq + Eq>(&'a [diff::Result<Item>], &'a [diff::Result<Item>]);
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum ChunkKind {
|
enum ChunkKind {
|
||||||
Stable,
|
Stable,
|
||||||
Unstable,
|
Unstable,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq)]
|
||||||
struct ChunkItem {
|
struct ChunkItem<'a, Item>
|
||||||
|
where
|
||||||
|
Item: 'a + Debug + PartialEq + Eq
|
||||||
|
{
|
||||||
kind: ChunkKind,
|
kind: ChunkKind,
|
||||||
chunk: Chunk,
|
chunk: Chunk<'a, Item>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChunkItem {
|
impl<'a, Item> ChunkItem<'a, Item>
|
||||||
fn stable(chunk: Chunk) -> ChunkItem {
|
where
|
||||||
|
Item: 'a + Debug + PartialEq + Eq
|
||||||
|
{
|
||||||
|
fn stable(chunk: Chunk<'a, Item>) -> ChunkItem<'a, Item> {
|
||||||
ChunkItem {
|
ChunkItem {
|
||||||
kind: ChunkKind::Stable,
|
kind: ChunkKind::Stable,
|
||||||
chunk: chunk,
|
chunk: chunk,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unstable(chunk: Chunk) -> ChunkItem {
|
fn unstable(chunk: Chunk<'a, Item>) -> ChunkItem<'a, Item> {
|
||||||
ChunkItem {
|
ChunkItem {
|
||||||
kind: ChunkKind::Unstable,
|
kind: ChunkKind::Unstable,
|
||||||
chunk: chunk,
|
chunk: chunk,
|
||||||
|
@ -36,7 +42,7 @@ impl ChunkItem {
|
||||||
|
|
||||||
struct MergeIterator<'a, Item>
|
struct MergeIterator<'a, Item>
|
||||||
where
|
where
|
||||||
Item: 'a
|
Item: 'a + Debug + PartialEq + Eq
|
||||||
{
|
{
|
||||||
left: &'a [diff::Result<Item>],
|
left: &'a [diff::Result<Item>],
|
||||||
right: &'a [diff::Result<Item>],
|
right: &'a [diff::Result<Item>],
|
||||||
|
@ -45,7 +51,10 @@ where
|
||||||
ri: usize,
|
ri: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Item> MergeIterator<'a, Item> {
|
impl<'a, Item> MergeIterator<'a, Item>
|
||||||
|
where
|
||||||
|
Item: 'a + Debug + PartialEq + Eq
|
||||||
|
{
|
||||||
fn new(left: &'a [diff::Result<Item>], right: &'a [diff::Result<Item>]) -> MergeIterator<'a, Item> {
|
fn new(left: &'a [diff::Result<Item>], right: &'a [diff::Result<Item>]) -> MergeIterator<'a, Item> {
|
||||||
MergeIterator {
|
MergeIterator {
|
||||||
left,
|
left,
|
||||||
|
@ -56,8 +65,11 @@ impl<'a, Item> MergeIterator<'a, Item> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Item> Iterator for MergeIterator<'a, Item> {
|
impl<'a, Item> Iterator for MergeIterator<'a, Item>
|
||||||
type Item = ChunkItem;
|
where
|
||||||
|
Item: 'a + Debug + PartialEq + Eq
|
||||||
|
{
|
||||||
|
type Item = ChunkItem<'a, Item>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
@ -65,7 +77,7 @@ impl<'a, Item> Iterator for MergeIterator<'a, Item> {
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
let chunk = ChunkItem::stable(Chunk(self.li..self.li+i, self.ri..self.ri+i));
|
let chunk = ChunkItem::stable(Chunk(&self.left[self.li..self.li+i], &self.right[self.ri..self.ri+i]));
|
||||||
self.li += i;
|
self.li += i;
|
||||||
self.ri += i;
|
self.ri += i;
|
||||||
return Some(chunk);
|
return Some(chunk);
|
||||||
|
@ -90,14 +102,14 @@ impl<'a, Item> Iterator for MergeIterator<'a, Item> {
|
||||||
ri += 1;
|
ri += 1;
|
||||||
},
|
},
|
||||||
(Some(&Both(..)), Some(&Both(..))) => {
|
(Some(&Both(..)), Some(&Both(..))) => {
|
||||||
let chunk = ChunkItem::unstable(Chunk(self.li..li, self.ri..ri));
|
let chunk = ChunkItem::unstable(Chunk(&self.left[self.li..li], &self.right[self.ri..ri]));
|
||||||
self.li = li;
|
self.li = li;
|
||||||
self.ri = ri;
|
self.ri = ri;
|
||||||
return Some(chunk);
|
return Some(chunk);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if self.li < self.left.len() || self.ri < self.right.len() {
|
if self.li < self.left.len() || self.ri < self.right.len() {
|
||||||
let chunk = ChunkItem::unstable(Chunk(self.li..self.left.len(), self.ri..self.right.len()));
|
let chunk = ChunkItem::unstable(Chunk(&self.left[self.li..self.left.len()], &self.right[self.ri..self.right.len()]));
|
||||||
self.li = self.left.len();
|
self.li = self.left.len();
|
||||||
self.ri = self.right.len();
|
self.ri = self.right.len();
|
||||||
return Some(chunk);
|
return Some(chunk);
|
||||||
|
@ -124,12 +136,13 @@ mod test {
|
||||||
let ob = diff::chars(o, b);
|
let ob = diff::chars(o, b);
|
||||||
|
|
||||||
let merge = MergeIterator::new(&oa, &ob).collect::<Vec<_>>();
|
let merge = MergeIterator::new(&oa, &ob).collect::<Vec<_>>();
|
||||||
|
|
||||||
assert_eq!(vec![
|
assert_eq!(vec![
|
||||||
ChunkItem::stable(Chunk(0..3, 0..3)),
|
ChunkItem::stable (Chunk(&oa[0.. 3], &ob[0.. 3])),
|
||||||
ChunkItem::unstable(Chunk(3..6, 3..3)),
|
ChunkItem::unstable(Chunk(&oa[3.. 6], &ob[3.. 3])),
|
||||||
ChunkItem::stable(Chunk(6..9, 3..6)),
|
ChunkItem::stable (Chunk(&oa[6.. 9], &ob[3.. 6])),
|
||||||
ChunkItem::unstable(Chunk(9..9, 6..9)),
|
ChunkItem::unstable(Chunk(&oa[9.. 9], &ob[6.. 9])),
|
||||||
ChunkItem::stable(Chunk(9..12, 9..12)),
|
ChunkItem::stable (Chunk(&oa[9..12], &ob[9..12])),
|
||||||
], merge);
|
], merge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,9 +157,9 @@ mod test {
|
||||||
|
|
||||||
let merge = MergeIterator::new(&oa, &ob).collect::<Vec<_>>();
|
let merge = MergeIterator::new(&oa, &ob).collect::<Vec<_>>();
|
||||||
assert_eq!(vec![
|
assert_eq!(vec![
|
||||||
ChunkItem::stable(Chunk(0..3, 0..3)),
|
ChunkItem::stable (Chunk(&oa[0.. 3], &ob[0.. 3])),
|
||||||
ChunkItem::unstable(Chunk(3..9, 3..9)),
|
ChunkItem::unstable(Chunk(&oa[3.. 9], &ob[3.. 9])),
|
||||||
ChunkItem::stable(Chunk(9..12, 9..12)),
|
ChunkItem::stable (Chunk(&oa[9..12], &ob[9..12])),
|
||||||
], merge);
|
], merge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,8 +174,8 @@ mod test {
|
||||||
|
|
||||||
let merge = MergeIterator::new(&oa, &ob).collect::<Vec<_>>();
|
let merge = MergeIterator::new(&oa, &ob).collect::<Vec<_>>();
|
||||||
assert_eq!(vec![
|
assert_eq!(vec![
|
||||||
ChunkItem::stable(Chunk(0..9, 0..9)),
|
ChunkItem::stable (Chunk(&oa[0..9], &ob[0.. 9])),
|
||||||
ChunkItem::unstable(Chunk(9..9, 9..12)),
|
ChunkItem::unstable(Chunk(&oa[9..9], &ob[9..12])),
|
||||||
], merge);
|
], merge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,8 +190,8 @@ mod test {
|
||||||
|
|
||||||
let merge = MergeIterator::new(&oa, &ob).collect::<Vec<_>>();
|
let merge = MergeIterator::new(&oa, &ob).collect::<Vec<_>>();
|
||||||
assert_eq!(vec![
|
assert_eq!(vec![
|
||||||
ChunkItem::stable(Chunk(0..6, 0..6)),
|
ChunkItem::stable (Chunk(&oa[0..6], &ob[0.. 6])),
|
||||||
ChunkItem::unstable(Chunk(6..9, 6..12)),
|
ChunkItem::unstable(Chunk(&oa[6..9], &ob[6..12])),
|
||||||
], merge);
|
], merge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +206,7 @@ mod test {
|
||||||
|
|
||||||
let merge = MergeIterator::new(&oa, &ob).collect::<Vec<_>>();
|
let merge = MergeIterator::new(&oa, &ob).collect::<Vec<_>>();
|
||||||
assert_eq!(vec![
|
assert_eq!(vec![
|
||||||
ChunkItem::unstable(Chunk(0..6, 0..6)),
|
ChunkItem::unstable(Chunk(&oa[0..6], &ob[0..6])),
|
||||||
], merge);
|
], merge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue