@@ -82,37 +82,6 @@ impl SubAssign<u32> for Offset {
82
82
}
83
83
}
84
84
85
- #[ derive( Clone , Copy , Debug ) ]
86
- struct LineRange {
87
- start : u32 ,
88
- end : u32 ,
89
- }
90
-
91
- impl LineRange {
92
- fn with_offset ( range : Range < u32 > , offset : Offset ) -> Self {
93
- match offset {
94
- Offset :: Added ( added) => {
95
- assert ! ( range. start >= added, "{range:?} {offset:?}" ) ;
96
-
97
- Self {
98
- start : range. start - added,
99
- end : range. end - added,
100
- }
101
- }
102
- Offset :: Deleted ( deleted) => Self {
103
- start : range. start + deleted,
104
- end : range. end + deleted,
105
- } ,
106
- }
107
- }
108
- }
109
-
110
- impl From < LineRange > for Range < u32 > {
111
- fn from ( line_range : LineRange ) -> Self {
112
- line_range. start ..line_range. end
113
- }
114
- }
115
-
116
85
#[ derive( Debug , PartialEq ) ]
117
86
pub struct BlameEntry {
118
87
pub range_in_blamed_file : Range < u32 > ,
@@ -173,6 +142,12 @@ pub struct UnblamedHunk {
173
142
pub range_in_destination : Range < u32 > ,
174
143
}
175
144
145
+ #[ derive( Debug ) ]
146
+ enum Either < T , U > {
147
+ Left ( T ) ,
148
+ Right ( U ) ,
149
+ }
150
+
176
151
impl UnblamedHunk {
177
152
pub fn new ( range_in_blamed_file : Range < u32 > , offset : Offset ) -> Self {
178
153
assert ! (
@@ -231,6 +206,22 @@ impl UnblamedHunk {
231
206
Self :: new ( self . range_in_blamed_file . clone ( ) , combined_offset)
232
207
}
233
208
209
+ fn split_at ( self , line_number_in_destination : u32 ) -> Either < Self , ( Self , Self ) > {
210
+ if line_number_in_destination > self . range_in_destination . start
211
+ && line_number_in_destination < self . range_in_destination . end
212
+ {
213
+ let first_range_in_destination = self . range_in_destination . start ..line_number_in_destination;
214
+ let second_range_in_destination = line_number_in_destination..self . range_in_destination . end ;
215
+
216
+ Either :: Right ( (
217
+ Self :: from_destination ( first_range_in_destination, self . offset ( ) ) ,
218
+ Self :: from_destination ( second_range_in_destination, self . offset ( ) ) ,
219
+ ) )
220
+ } else {
221
+ Either :: Left ( self )
222
+ }
223
+ }
224
+
234
225
fn offset ( & self ) -> Offset {
235
226
if self . range_in_blamed_file . start > self . range_in_destination . start {
236
227
Offset :: Added ( self . range_in_blamed_file . start - self . range_in_destination . start )
@@ -379,59 +370,48 @@ pub fn process_change(
379
370
// <---> (added)
380
371
// <---> (blamed)
381
372
// <--> <-> (new hunk)
382
- if added. start > hunk. range_in_destination . start {
383
- let line_range_in_next_destination = LineRange :: with_offset (
384
- hunk. range_in_destination . start ..added. start ,
385
- * offset_in_destination,
386
- ) ;
387
-
388
- new_hunks_to_blame. push ( UnblamedHunk :: from_destination (
389
- line_range_in_next_destination. into ( ) ,
390
- hunk. offset ( ) + * offset_in_destination,
391
- ) ) ;
392
- }
373
+
374
+ let new_hunk = match hunk. split_at ( added. start ) {
375
+ Either :: Left ( hunk) => hunk,
376
+ Either :: Right ( ( before, after) ) => {
377
+ new_hunks_to_blame. push ( before. shift_by ( * offset_in_destination) ) ;
378
+
379
+ after
380
+ }
381
+ } ;
393
382
394
383
* offset_in_destination += added. end - added. start ;
395
384
* offset_in_destination -= number_of_lines_deleted;
396
385
397
- out. push ( BlameEntry :: with_offset ( added. clone ( ) , suspect, hunk. offset ( ) ) ) ;
398
-
399
- let new_hunk = if hunk. range_in_destination . end > added. end {
400
- Some ( UnblamedHunk :: from_destination (
401
- added. end ..hunk. range_in_destination . end ,
402
- hunk. offset ( ) ,
403
- ) )
404
- } else {
405
- None
406
- } ;
386
+ out. push ( BlameEntry :: with_offset ( added. clone ( ) , suspect, new_hunk. offset ( ) ) ) ;
407
387
408
- ( new_hunk, None )
388
+ match new_hunk. split_at ( added. end ) {
389
+ Either :: Left ( _) => ( None , None ) ,
390
+ Either :: Right ( ( _, after) ) => ( Some ( after) , None ) ,
391
+ }
409
392
}
410
393
( true , false ) => {
411
394
// <--------> (hunk)
412
395
// <-------> (added)
413
396
// <----> (blamed)
414
397
// <--> (new hunk)
415
398
416
- if added. start > hunk. range_in_destination . start {
417
- let line_range_in_next_destination = LineRange :: with_offset (
418
- hunk. range_in_destination . start ..added. start ,
419
- * offset_in_destination,
420
- ) ;
399
+ let new_hunk = match hunk. split_at ( added. start ) {
400
+ Either :: Left ( hunk) => hunk,
401
+ Either :: Right ( ( before, after) ) => {
402
+ new_hunks_to_blame. push ( before. shift_by ( * offset_in_destination) ) ;
421
403
422
- new_hunks_to_blame. push ( UnblamedHunk :: from_destination (
423
- line_range_in_next_destination. into ( ) ,
424
- hunk. offset ( ) + * offset_in_destination,
425
- ) ) ;
426
- }
404
+ after
405
+ }
406
+ } ;
427
407
428
408
out. push ( BlameEntry :: with_offset (
429
- added. start ..hunk . range_in_destination . end ,
409
+ added. start ..new_hunk . range_in_destination . end ,
430
410
suspect,
431
- hunk . offset ( ) ,
411
+ new_hunk . offset ( ) ,
432
412
) ) ;
433
413
434
- if added. end > hunk . range_in_destination . end {
414
+ if added. end > new_hunk . range_in_destination . end {
435
415
( None , Some ( Change :: Added ( added, number_of_lines_deleted) ) )
436
416
} else {
437
417
todo ! ( ) ;
@@ -452,16 +432,10 @@ pub fn process_change(
452
432
* offset_in_destination += added. end - added. start ;
453
433
* offset_in_destination -= number_of_lines_deleted;
454
434
455
- let new_hunk = if hunk. range_in_destination . end > added. end {
456
- Some ( UnblamedHunk :: from_destination (
457
- added. end ..hunk. range_in_destination . end ,
458
- hunk. offset ( ) ,
459
- ) )
460
- } else {
461
- None
462
- } ;
463
-
464
- ( new_hunk, None )
435
+ match hunk. split_at ( added. end ) {
436
+ Either :: Left ( _) => ( None , None ) ,
437
+ Either :: Right ( ( _, after) ) => ( Some ( after) , None ) ,
438
+ }
465
439
}
466
440
( false , false ) => {
467
441
// Any of the following cases are handled by this branch:
@@ -517,26 +491,18 @@ pub fn process_change(
517
491
// <-----> (hunk)
518
492
// | (line_number_in_destination)
519
493
520
- if hunk. range_in_destination . start < line_number_in_destination {
521
- let line_range_in_next_destination = LineRange :: with_offset (
522
- hunk. range_in_destination . start ..line_number_in_destination,
523
- * offset_in_destination,
524
- ) ;
494
+ let new_hunk = match hunk. split_at ( line_number_in_destination) {
495
+ Either :: Left ( hunk) => hunk,
496
+ Either :: Right ( ( before, after) ) => {
497
+ new_hunks_to_blame. push ( before. shift_by ( * offset_in_destination) ) ;
525
498
526
- new_hunks_to_blame. push ( UnblamedHunk :: from_destination (
527
- line_range_in_next_destination. into ( ) ,
528
- hunk. offset ( ) + * offset_in_destination,
529
- ) ) ;
530
- }
499
+ after
500
+ }
501
+ } ;
531
502
532
503
* offset_in_destination -= number_of_lines_deleted;
533
504
534
- let new_hunk = Some ( UnblamedHunk :: from_destination (
535
- line_number_in_destination..hunk. range_in_destination . end ,
536
- hunk. offset ( ) ,
537
- ) ) ;
538
-
539
- ( new_hunk, None )
505
+ ( Some ( new_hunk) , None )
540
506
} else {
541
507
// <---> (hunk)
542
508
// | (line_number_in_destination)
0 commit comments