Emit slices instead of indices

This commit is contained in:
Magnus Hoff 2017-11-16 16:21:49 +01:00
parent b48816e143
commit ed5db344fb

View file

@ -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);
} }
} }