4
4
//! so `TextEdit` is the ultimate representation of the work done by
5
5
//! rust-analyzer.
6
6
7
+ use itertools:: Itertools ;
8
+ use std:: cmp:: Ordering ;
7
9
pub use text_size:: { TextRange , TextSize } ;
8
10
9
11
/// `InsertDelete` -- a single "atomic" change to text
@@ -16,6 +18,22 @@ pub struct Indel {
16
18
pub delete : TextRange ,
17
19
}
18
20
21
+ impl PartialOrd for Indel {
22
+ fn partial_cmp ( & self , other : & Indel ) -> Option < Ordering > {
23
+ if self == other {
24
+ return Some ( Ordering :: Equal ) ;
25
+ }
26
+ let cmp_to_other = self . delete . end ( ) <= other. delete . start ( ) ;
27
+ let cmp_to_self = other. delete . end ( ) <= self . delete . start ( ) ;
28
+ match ( cmp_to_other, cmp_to_self) {
29
+ ( true , true ) => Some ( Ordering :: Equal ) ,
30
+ ( true , false ) => Some ( Ordering :: Less ) ,
31
+ ( false , true ) => Some ( Ordering :: Greater ) ,
32
+ ( false , false ) => None ,
33
+ }
34
+ }
35
+ }
36
+
19
37
#[ derive( Default , Debug , Clone ) ]
20
38
pub struct TextEdit {
21
39
/// Invariant: disjoint and sorted by `delete`.
@@ -109,9 +127,8 @@ impl TextEdit {
109
127
}
110
128
111
129
pub fn union ( & mut self , other : TextEdit ) -> Result < ( ) , TextEdit > {
112
- // FIXME: can be done without allocating intermediate vector
113
- let mut all = self . iter ( ) . chain ( other. iter ( ) ) . collect :: < Vec < _ > > ( ) ;
114
- if !check_disjoint_and_sort ( & mut all) {
130
+ let mut iter_merge = self . iter ( ) . merge ( other. iter ( ) ) ;
131
+ if !check_disjoint ( & mut iter_merge) {
115
132
return Err ( other) ;
116
133
}
117
134
@@ -185,17 +202,28 @@ impl TextEditBuilder {
185
202
}
186
203
}
187
204
188
- fn assert_disjoint_or_equal ( indels : & mut [ Indel ] ) {
205
+ fn assert_disjoint_or_equal ( indels : & mut Vec < Indel > ) {
189
206
assert ! ( check_disjoint_and_sort( indels) ) ;
190
207
}
191
- // FIXME: Remove the impl Bound here, it shouldn't be needed
192
- fn check_disjoint_and_sort ( indels : & mut [ impl std:: borrow:: Borrow < Indel > ] ) -> bool {
193
- indels. sort_by_key ( |indel| ( indel. borrow ( ) . delete . start ( ) , indel. borrow ( ) . delete . end ( ) ) ) ;
194
- indels. iter ( ) . zip ( indels. iter ( ) . skip ( 1 ) ) . all ( |( l, r) | {
195
- let l = l. borrow ( ) ;
196
- let r = r. borrow ( ) ;
197
- l. delete . end ( ) <= r. delete . start ( ) || l == r
198
- } )
208
+
209
+ fn check_disjoint_and_sort ( indels : & mut Vec < Indel > ) -> bool {
210
+ indels. sort_by_key ( |indel| ( indel. delete . start ( ) , indel. delete . end ( ) ) ) ;
211
+ return check_disjoint ( & mut indels. iter ( ) ) ;
212
+ }
213
+
214
+ fn check_disjoint < ' a , I > ( indels : & mut I ) -> bool
215
+ where
216
+ I : std:: iter:: Iterator < Item = & ' a Indel > ,
217
+ {
218
+ if let Some ( indel) = indels. next ( ) {
219
+ let mut indel = indel;
220
+ return indels. all ( |right_indel| {
221
+ let check = indel <= right_indel;
222
+ indel = right_indel;
223
+ return check;
224
+ } ) ;
225
+ }
226
+ true
199
227
}
200
228
201
229
#[ cfg( test) ]
0 commit comments