1use super::Diff;
2
3pub struct Replace<D: Diff> {
6 d: D,
7 del: Option<(usize, usize, usize)>,
8 ins: Option<(usize, usize, usize)>,
9 eq: Option<(usize, usize, usize)>,
10}
11
12impl<D: Diff> Replace<D> {
13 pub fn new(d: D) -> Self {
14 Replace {
15 d,
16 del: None,
17 ins: None,
18 eq: None,
19 }
20 }
21 pub fn into_inner(self) -> D {
22 self.d
23 }
24}
25
26impl<D: Diff> AsRef<D> for Replace<D> {
27 fn as_ref(&self) -> &D {
28 &self.d
29 }
30}
31
32impl<D: Diff> AsMut<D> for Replace<D> {
33 fn as_mut(&mut self) -> &mut D {
34 &mut self.d
35 }
36}
37
38impl<D: Diff> Diff for Replace<D> {
39 type Error = D::Error;
40 fn equal(&mut self, old: usize, new: usize, len: usize) -> Result<(), D::Error> {
41 if let Some((old0, len0, new0)) = self.del.take() {
42 if let Some((_, new1, new_len1)) = self.ins.take() {
43 self.d.replace(old0, len0, new1, new_len1)?
44 } else {
45 self.d.delete(old0, len0, new0)?
46 }
47 } else if let Some((old0, new0, new_len0)) = self.ins.take() {
48 self.d.insert(old0, new0, new_len0)?
49 }
50
51 if let Some((a, b, c)) = self.eq.take() {
52 self.eq = Some((a, b, c + len))
53 } else {
54 self.eq = Some((old, new, len))
55 }
56 Ok(())
57 }
58 fn delete(&mut self, old: usize, len: usize, new: usize) -> Result<(), D::Error> {
59 if let Some((a, b, c)) = self.eq.take() {
60 self.d.equal(a, b, c)?
61 }
62 if let Some((old0, len0, new0)) = self.del.take() {
63 assert_eq!(old, old0 + len0);
64 self.del = Some((old0, len0 + len, new0))
65 } else {
66 self.del = Some((old, len, new))
67 }
68 Ok(())
69 }
70
71 fn insert(&mut self, old: usize, new: usize, new_len: usize) -> Result<(), D::Error> {
72 if let Some((a, b, c)) = self.eq.take() {
73 self.d.equal(a, b, c)?
74 }
75 if let Some((old1, new1, new_len1)) = self.ins.take() {
76 assert_eq!(new1 + new_len1, new);
77 self.ins = Some((old1, new1, new_len + new_len1))
78 } else {
79 self.ins = Some((old, new, new_len))
80 }
81 Ok(())
82 }
83
84 fn replace(
85 &mut self,
86 old: usize,
87 old_len: usize,
88 new: usize,
89 new_len: usize,
90 ) -> Result<(), D::Error> {
91 if let Some((a, b, c)) = self.eq.take() {
92 self.d.equal(a, b, c)?
93 }
94 self.d.replace(old, old_len, new, new_len)
95 }
96
97 fn finish(&mut self) -> Result<(), D::Error> {
98 if let Some((a, b, c)) = self.eq.take() {
99 self.d.equal(a, b, c)?
100 }
101 if let Some((old0, len0, new0)) = self.del.take() {
102 if let Some((_, new1, new_len1)) = self.ins.take() {
103 self.d.replace(old0, len0, new1, new_len1)?
104 } else {
105 self.d.delete(old0, len0, new0)?
106 }
107 } else if let Some((old0, new0, new_len0)) = self.ins.take() {
108 self.d.insert(old0, new0, new_len0)?
109 }
110 self.d.finish()
111 }
112}
113
114#[test]
115fn myers() {
116 use myers;
117 let a: &[&str] = &[
118 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n",
119 "a\n",
120 "b\n",
121 "c\n",
122 "================================\n",
123 "d\n",
124 "e\n",
125 "f\n",
126 "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
127 ];
128 let b: &[&str] = &[
129 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n",
130 "x\n",
131 "b\n",
132 "c\n",
133 "================================\n",
134 "y\n",
135 "e\n",
136 "f\n",
137 "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
138 ];
139
140 struct D {}
141 impl Diff for D {
142 type Error = ();
143 fn equal(&mut self, o: usize, n: usize, len: usize) -> Result<(), ()> {
144 println!("equal {:?} {:?} {:?}", o, n, len);
145 Ok(())
146 }
147 fn delete(&mut self, o: usize, len: usize, new: usize) -> Result<(), ()> {
148 println!("delete {:?} {:?} {:?}", o, len, new);
149 Ok(())
150 }
151 fn insert(&mut self, o: usize, n: usize, len: usize) -> Result<(), ()> {
152 println!("insert {:?} {:?} {:?}", o, n, len);
153 Ok(())
154 }
155 fn replace(&mut self, o: usize, l: usize, n: usize, nl: usize) -> Result<(), ()> {
156 println!("replace {:?} {:?} {:?} {:?}", o, l, n, nl);
157 Ok(())
158 }
159 }
160 let mut d = Replace::new(D {});
161 myers::diff(&mut d, a, 0, a.len(), b, 0, b.len()).unwrap();
162}