@@ -3,13 +3,12 @@ use crate::blob::builtin_driver::text::utils::{
33    hunks_differ_in_diff3,  take_intersecting,  tokens,  write_ancestor,  write_conflict_marker,  write_hunks, 
44    zealously_contract_hunks,  CollectHunks ,  Hunk ,  Side , 
55} ; 
6- use  crate :: blob:: builtin_driver:: text:: { ConflictStyle ,  Options ,   ResolveWith } ; 
6+ use  crate :: blob:: builtin_driver:: text:: { Conflict ,   ConflictStyle ,  Labels ,   Options } ; 
77use  crate :: blob:: Resolution ; 
8- use  bstr:: BStr ; 
98
109/// Merge `current` and `other` with `ancestor` as base according to `opts`. 
1110/// 
12- /// Use `current_label`, `other_label` and `ancestor_label ` to annotate conflict sections. 
11+ /// Use `labels ` to annotate conflict sections. 
1312/// 
1413/// `input` is for reusing memory for lists of tokens, but note that it grows indefinitely 
1514/// while tokens for `current`, `ancestor` and `other` are added. 
@@ -23,12 +22,14 @@ use bstr::BStr;
2322pub  fn  merge < ' a > ( 
2423    out :  & mut  Vec < u8 > , 
2524    input :  & mut  imara_diff:: intern:: InternedInput < & ' a  [ u8 ] > , 
25+     Labels  { 
26+         ancestor :  ancestor_label, 
27+         current :  current_label, 
28+         other :  other_label, 
29+     } :  Labels < ' _ > , 
2630    current :  & ' a  [ u8 ] , 
27-     current_label :  Option < & BStr > , 
2831    ancestor :  & ' a  [ u8 ] , 
29-     ancestor_label :  Option < & BStr > , 
3032    other :  & ' a  [ u8 ] , 
31-     other_label :  Option < & BStr > , 
3233    opts :  Options , 
3334)  -> Resolution  { 
3435    out. clear ( ) ; 
@@ -77,9 +78,9 @@ pub fn merge<'a>(
7778                    . expect ( "at least one entry" ) , 
7879                & mut  filled_hunks, 
7980            ) ; 
80-             match  opts. on_conflict  { 
81-                 None  => { 
82-                     let  ( hunks_front_and_back,  num_hunks_front)  = match  opts . conflict_style  { 
81+             match  opts. conflict  { 
82+                 Conflict :: Keep   {  style ,  marker_size  }  => { 
83+                     let  ( hunks_front_and_back,  num_hunks_front)  = match  style  { 
8384                        ConflictStyle :: Merge  | ConflictStyle :: ZealousDiff3  => { 
8485                            zealously_contract_hunks ( & mut  filled_hunks,  & mut  intersecting,  input,  & current_tokens) 
8586                        } 
@@ -130,28 +131,22 @@ pub fn merge<'a>(
130131                        ) 
131132                        . or_else ( || detect_line_ending ( our_hunks,  input,  & current_tokens) ) 
132133                        . unwrap_or ( b"\n " . into ( ) ) ; 
133-                         match  opts . conflict_style  { 
134+                         match  style  { 
134135                            ConflictStyle :: Merge  => { 
135136                                if  contains_lines ( our_hunks)  || contains_lines ( their_hunks)  { 
136137                                    resolution = Resolution :: Conflict ; 
137-                                     write_conflict_marker ( out,  b'<' ,  current_label,  opts . marker_size ,  nl) ; 
138+                                     write_conflict_marker ( out,  b'<' ,  current_label,  marker_size,  nl) ; 
138139                                    write_hunks ( our_hunks,  input,  & current_tokens,  out) ; 
139-                                     write_conflict_marker ( out,  b'=' ,  None ,  opts . marker_size ,  nl) ; 
140+                                     write_conflict_marker ( out,  b'=' ,  None ,  marker_size,  nl) ; 
140141                                    write_hunks ( their_hunks,  input,  & current_tokens,  out) ; 
141-                                     write_conflict_marker ( out,  b'>' ,  other_label,  opts . marker_size ,  nl) ; 
142+                                     write_conflict_marker ( out,  b'>' ,  other_label,  marker_size,  nl) ; 
142143                                } 
143144                            } 
144145                            ConflictStyle :: Diff3  | ConflictStyle :: ZealousDiff3  => { 
145146                                if  contains_lines ( our_hunks)  || contains_lines ( their_hunks)  { 
146-                                     if  hunks_differ_in_diff3 ( 
147-                                         opts. conflict_style , 
148-                                         our_hunks, 
149-                                         their_hunks, 
150-                                         input, 
151-                                         & current_tokens, 
152-                                     )  { 
147+                                     if  hunks_differ_in_diff3 ( style,  our_hunks,  their_hunks,  input,  & current_tokens)  { 
153148                                        resolution = Resolution :: Conflict ; 
154-                                         write_conflict_marker ( out,  b'<' ,  current_label,  opts . marker_size ,  nl) ; 
149+                                         write_conflict_marker ( out,  b'<' ,  current_label,  marker_size,  nl) ; 
155150                                        write_hunks ( our_hunks,  input,  & current_tokens,  out) ; 
156151                                        let  ancestor_hunk = Hunk  { 
157152                                            before :  first_hunk. before . start ..last_hunk. before . end , 
@@ -161,11 +156,11 @@ pub fn merge<'a>(
161156                                        let  ancestor_hunk = std:: slice:: from_ref ( & ancestor_hunk) ; 
162157                                        let  ancestor_nl =
163158                                            detect_line_ending_or_nl ( ancestor_hunk,  input,  & current_tokens) ; 
164-                                         write_conflict_marker ( out,  b'|' ,  ancestor_label,  opts . marker_size ,  ancestor_nl) ; 
159+                                         write_conflict_marker ( out,  b'|' ,  ancestor_label,  marker_size,  ancestor_nl) ; 
165160                                        write_hunks ( ancestor_hunk,  input,  & current_tokens,  out) ; 
166-                                         write_conflict_marker ( out,  b'=' ,  None ,  opts . marker_size ,  nl) ; 
161+                                         write_conflict_marker ( out,  b'=' ,  None ,  marker_size,  nl) ; 
167162                                        write_hunks ( their_hunks,  input,  & current_tokens,  out) ; 
168-                                         write_conflict_marker ( out,  b'>' ,  other_label,  opts . marker_size ,  nl) ; 
163+                                         write_conflict_marker ( out,  b'>' ,  other_label,  marker_size,  nl) ; 
169164                                    }  else  { 
170165                                        write_hunks ( our_hunks,  input,  & current_tokens,  out) ; 
171166                                    } 
@@ -176,64 +171,60 @@ pub fn merge<'a>(
176171                    write_hunks ( back_hunks,  input,  & current_tokens,  out) ; 
177172                    ancestor_integrated_until = last_hunk. before . end ; 
178173                } 
179-                 Some ( resolve)  => { 
180-                     match  resolve { 
181-                         ResolveWith :: Ours  | ResolveWith :: Theirs  => { 
182-                             let  ( our_hunks,  their_hunks)  = match  filled_hunks_side { 
183-                                 Side :: Current  => ( & filled_hunks,  & intersecting) , 
184-                                 Side :: Other  => ( & intersecting,  & filled_hunks) , 
185-                                 Side :: Ancestor  => { 
186-                                     unreachable ! ( "initial hunks are never ancestors" ) 
187-                                 } 
188-                             } ; 
189-                             let  hunks_to_write = if  resolve == ResolveWith :: Ours  { 
190-                                 our_hunks
191-                             }  else  { 
192-                                 their_hunks
193-                             } ; 
194-                             if  let  Some ( first_hunk)  = hunks_to_write. first ( )  { 
195-                                 write_ancestor ( input,  ancestor_integrated_until,  first_hunk. before . start  as  usize ,  out) ; 
196-                             } 
197-                             write_hunks ( hunks_to_write,  input,  & current_tokens,  out) ; 
198-                             if  let  Some ( last_hunk)  = hunks_to_write. last ( )  { 
199-                                 ancestor_integrated_until = last_hunk. before . end ; 
200-                             } 
174+                 Conflict :: ResolveWithOurs  | Conflict :: ResolveWithTheirs  => { 
175+                     let  ( our_hunks,  their_hunks)  = match  filled_hunks_side { 
176+                         Side :: Current  => ( & filled_hunks,  & intersecting) , 
177+                         Side :: Other  => ( & intersecting,  & filled_hunks) , 
178+                         Side :: Ancestor  => { 
179+                             unreachable ! ( "initial hunks are never ancestors" ) 
201180                        } 
202-                         ResolveWith :: Union  => { 
203-                             let  ( hunks_front_and_back,  num_hunks_front)  =
204-                                 zealously_contract_hunks ( & mut  filled_hunks,  & mut  intersecting,  input,  & current_tokens) ; 
181+                     } ; 
182+                     let  hunks_to_write = if  opts. conflict  == Conflict :: ResolveWithOurs  { 
183+                         our_hunks
184+                     }  else  { 
185+                         their_hunks
186+                     } ; 
187+                     if  let  Some ( first_hunk)  = hunks_to_write. first ( )  { 
188+                         write_ancestor ( input,  ancestor_integrated_until,  first_hunk. before . start  as  usize ,  out) ; 
189+                     } 
190+                     write_hunks ( hunks_to_write,  input,  & current_tokens,  out) ; 
191+                     if  let  Some ( last_hunk)  = hunks_to_write. last ( )  { 
192+                         ancestor_integrated_until = last_hunk. before . end ; 
193+                     } 
194+                 } 
195+                 Conflict :: ResolveWithUnion  => { 
196+                     let  ( hunks_front_and_back,  num_hunks_front)  =
197+                         zealously_contract_hunks ( & mut  filled_hunks,  & mut  intersecting,  input,  & current_tokens) ; 
205198
206-                             let  ( our_hunks,  their_hunks)  = match  filled_hunks_side { 
207-                                 Side :: Current  => ( & filled_hunks,  & intersecting) , 
208-                                 Side :: Other  => ( & intersecting,  & filled_hunks) , 
209-                                 Side :: Ancestor  => { 
210-                                     unreachable ! ( "initial hunks are never ancestors" ) 
211-                                 } 
212-                             } ; 
213-                             let  ( front_hunks,  back_hunks)  = hunks_front_and_back. split_at ( num_hunks_front) ; 
214-                             let  first_hunk = front_hunks
215-                                 . first ( ) 
216-                                 . or ( our_hunks. first ( ) ) 
217-                                 . expect ( "at least one hunk to write" ) ; 
218-                             write_ancestor ( input,  ancestor_integrated_until,  first_hunk. before . start  as  usize ,  out) ; 
219-                             write_hunks ( front_hunks,  input,  & current_tokens,  out) ; 
220-                             assure_ends_with_nl ( out,  detect_line_ending_or_nl ( front_hunks,  input,  & current_tokens) ) ; 
221-                             write_hunks ( our_hunks,  input,  & current_tokens,  out) ; 
222-                             assure_ends_with_nl ( out,  detect_line_ending_or_nl ( our_hunks,  input,  & current_tokens) ) ; 
223-                             write_hunks ( their_hunks,  input,  & current_tokens,  out) ; 
224-                             if  !back_hunks. is_empty ( )  { 
225-                                 assure_ends_with_nl ( out,  detect_line_ending_or_nl ( their_hunks,  input,  & current_tokens) ) ; 
226-                             } 
227-                             write_hunks ( back_hunks,  input,  & current_tokens,  out) ; 
228-                             let  last_hunk = back_hunks
229-                                 . last ( ) 
230-                                 . or ( their_hunks. last ( ) ) 
231-                                 . or ( our_hunks. last ( ) ) 
232-                                 . or ( front_hunks. last ( ) ) 
233-                                 . expect ( "at least one hunk" ) ; 
234-                             ancestor_integrated_until = last_hunk. before . end ; 
199+                     let  ( our_hunks,  their_hunks)  = match  filled_hunks_side { 
200+                         Side :: Current  => ( & filled_hunks,  & intersecting) , 
201+                         Side :: Other  => ( & intersecting,  & filled_hunks) , 
202+                         Side :: Ancestor  => { 
203+                             unreachable ! ( "initial hunks are never ancestors" ) 
235204                        } 
236205                    } ; 
206+                     let  ( front_hunks,  back_hunks)  = hunks_front_and_back. split_at ( num_hunks_front) ; 
207+                     let  first_hunk = front_hunks
208+                         . first ( ) 
209+                         . or ( our_hunks. first ( ) ) 
210+                         . expect ( "at least one hunk to write" ) ; 
211+                     write_ancestor ( input,  ancestor_integrated_until,  first_hunk. before . start  as  usize ,  out) ; 
212+                     write_hunks ( front_hunks,  input,  & current_tokens,  out) ; 
213+                     assure_ends_with_nl ( out,  detect_line_ending_or_nl ( front_hunks,  input,  & current_tokens) ) ; 
214+                     write_hunks ( our_hunks,  input,  & current_tokens,  out) ; 
215+                     assure_ends_with_nl ( out,  detect_line_ending_or_nl ( our_hunks,  input,  & current_tokens) ) ; 
216+                     write_hunks ( their_hunks,  input,  & current_tokens,  out) ; 
217+                     if  !back_hunks. is_empty ( )  { 
218+                         assure_ends_with_nl ( out,  detect_line_ending_or_nl ( their_hunks,  input,  & current_tokens) ) ; 
219+                     } 
220+                     write_hunks ( back_hunks,  input,  & current_tokens,  out) ; 
221+                     let  last_hunk = back_hunks
222+                         . last ( ) 
223+                         . or ( their_hunks. last ( ) ) 
224+                         . or ( our_hunks. last ( ) ) 
225+                         . or ( front_hunks. last ( ) ) 
226+                         . expect ( "at least one hunk" ) ; 
227+                     ancestor_integrated_until = last_hunk. before . end ; 
237228                } 
238229            } 
239230        }  else  { 
0 commit comments