@@ -207,7 +207,7 @@ fn diffCompute(
207207 return dmp .diffBisect (allocator , before , after , deadline );
208208}
209209
210- const HalfMatchResult = ? struct {
210+ const HalfMatchResult = struct {
211211 prefix_before : []const u8 ,
212212 suffix_before : []const u8 ,
213213 prefix_after : []const u8 ,
@@ -220,7 +220,7 @@ fn diffHalfMatch(
220220 allocator : std.mem.Allocator ,
221221 before : []const u8 ,
222222 after : []const u8 ,
223- ) DiffError ! HalfMatchResult {
223+ ) DiffError ! ? HalfMatchResult {
224224 if (dmp .diff_timeout <= 0 ) {
225225 // Don't risk returning a non-optimal diff if we have unlimited time.
226226 return null ;
@@ -237,7 +237,7 @@ fn diffHalfMatch(
237237 // Check again based on the third quarter.
238238 var half_match_2 = try dmp .diffHalfMatchInternal (allocator , long_text , short_text , (long_text .len + 1 ) / 2 );
239239
240- var half_match : HalfMatchResult = undefined ;
240+ var half_match : ? HalfMatchResult = null ;
241241 if (half_match_1 == null and half_match_2 == null ) {
242242 return null ;
243243 } else if (half_match_2 == null ) {
@@ -270,7 +270,7 @@ fn diffHalfMatchInternal(
270270 long_text : []const u8 ,
271271 short_text : []const u8 ,
272272 i : usize ,
273- ) DiffError ! HalfMatchResult {
273+ ) DiffError ! ? HalfMatchResult {
274274 // Start with a 1/4 length Substring at position i as a seed.
275275 const seed = long_text [i .. i + long_text .len / 4 ];
276276 var j : isize = -1 ;
@@ -1198,21 +1198,129 @@ fn diffCommonOverlap(text1_in: []const u8, text2_in: []const u8) usize {
11981198// std.log.err("{any}", .{bruh});
11991199// }
12001200
1201- test {
1201+ // test {
1202+ // var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
1203+ // defer arena.deinit();
1204+
1205+ // var bruh = try default.diff(arena.allocator(), "Hello World.", "Goodbye World.", true);
1206+ // try diffCleanupSemantic(arena.allocator(), &bruh);
1207+ // for (bruh.items) |b| {
1208+ // std.log.err("{any}", .{b});
1209+ // }
1210+
1211+ // // for (bruh.items) |b| {
1212+ // // std.log.err("{s} {s}", .{ switch (b.operation) {
1213+ // // .equal => "",
1214+ // // .insert => "+",
1215+ // // .delete => "-",
1216+ // // }, b.text });
1217+ // // }
1218+ // }
1219+
1220+ test diffCommonPrefix {
1221+ // Detect any common suffix.
1222+ try std .testing .expectEqual (@as (usize , 0 ), diffCommonPrefix ("abc" , "xyz" )); // Null case
1223+ try std .testing .expectEqual (@as (usize , 4 ), diffCommonPrefix ("1234abcdef" , "1234xyz" )); // Non-null case
1224+ try std .testing .expectEqual (@as (usize , 4 ), diffCommonPrefix ("1234" , "1234xyz" )); // Whole case
1225+ }
1226+
1227+ test diffCommonSuffix {
1228+ // Detect any common suffix.
1229+ try std .testing .expectEqual (@as (usize , 0 ), diffCommonSuffix ("abc" , "xyz" )); // Null case
1230+ try std .testing .expectEqual (@as (usize , 4 ), diffCommonSuffix ("abcdef1234" , "xyz1234" )); // Non-null case
1231+ try std .testing .expectEqual (@as (usize , 4 ), diffCommonSuffix ("1234" , "xyz1234" )); // Whole case
1232+ }
1233+
1234+ test diffCommonOverlap {
1235+ // Detect any suffix/prefix overlap.
1236+ try std .testing .expectEqual (@as (usize , 0 ), diffCommonOverlap ("" , "abcd" )); // Null case
1237+ try std .testing .expectEqual (@as (usize , 3 ), diffCommonOverlap ("abc" , "abcd" )); // Whole case
1238+ try std .testing .expectEqual (@as (usize , 0 ), diffCommonOverlap ("123456" , "abcd" )); // No overlap
1239+ try std .testing .expectEqual (@as (usize , 3 ), diffCommonOverlap ("123456xxx" , "xxxabcd" )); // Overlap
1240+
1241+ // Some overly clever languages (C#) may treat ligatures as equal to their
1242+ // component letters. E.g. U+FB01 == 'fi'
1243+ try std .testing .expectEqual (@as (usize , 0 ), diffCommonOverlap ("fi" , "\u{fb01} " )); // Unicode
1244+ }
1245+
1246+ test diffHalfMatch {
12021247 var arena = std .heap .ArenaAllocator .init (std .testing .allocator );
12031248 defer arena .deinit ();
12041249
1205- var bruh = try default .diff (arena .allocator (), "Hello World." , "Goodbye World." , true );
1206- try diffCleanupSemantic (arena .allocator (), & bruh );
1207- for (bruh .items ) | b | {
1208- std .log .err ("{any}" , .{b });
1209- }
1210-
1211- // for (bruh.items) |b| {
1212- // std.log.err("{s} {s}", .{ switch (b.operation) {
1213- // .equal => "",
1214- // .insert => "+",
1215- // .delete => "-",
1216- // }, b.text });
1217- // }
1250+ var one_timeout = DiffMatchPatch {};
1251+ one_timeout .diff_timeout = 1 ;
1252+
1253+ try std .testing .expectEqual (@as (? HalfMatchResult , null ), try one_timeout .diffHalfMatch (arena .allocator (), "1234567890" , "abcdef" )); // No match #1
1254+ try std .testing .expectEqual (@as (? HalfMatchResult , null ), try one_timeout .diffHalfMatch (arena .allocator (), "12345" , "23" )); // No match #2
1255+
1256+ // Single matches
1257+ try std .testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1258+ .prefix_before = "12" ,
1259+ .suffix_before = "90" ,
1260+ .prefix_after = "a" ,
1261+ .suffix_after = "z" ,
1262+ .common_middle = "345678" ,
1263+ }), try one_timeout .diffHalfMatch (arena .allocator (), "1234567890" , "a345678z" )); // Single Match #1
1264+
1265+ try std .testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1266+ .prefix_before = "a" ,
1267+ .suffix_before = "z" ,
1268+ .prefix_after = "12" ,
1269+ .suffix_after = "90" ,
1270+ .common_middle = "345678" ,
1271+ }), try one_timeout .diffHalfMatch (arena .allocator (), "a345678z" , "1234567890" )); // Single Match #2
1272+
1273+ try std .testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1274+ .prefix_before = "abc" ,
1275+ .suffix_before = "z" ,
1276+ .prefix_after = "1234" ,
1277+ .suffix_after = "0" ,
1278+ .common_middle = "56789" ,
1279+ }), try one_timeout .diffHalfMatch (arena .allocator (), "abc56789z" , "1234567890" )); // Single Match #3
1280+
1281+ try std .testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1282+ .prefix_before = "a" ,
1283+ .suffix_before = "xyz" ,
1284+ .prefix_after = "1" ,
1285+ .suffix_after = "7890" ,
1286+ .common_middle = "23456" ,
1287+ }), try one_timeout .diffHalfMatch (arena .allocator (), "a23456xyz" , "1234567890" )); // Single Match #4
1288+
1289+ // Multiple matches
1290+ try std .testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1291+ .prefix_before = "12123" ,
1292+ .suffix_before = "123121" ,
1293+ .prefix_after = "a" ,
1294+ .suffix_after = "z" ,
1295+ .common_middle = "1234123451234" ,
1296+ }), try one_timeout .diffHalfMatch (arena .allocator (), "121231234123451234123121" , "a1234123451234z" )); // Multiple Matches #1
1297+
1298+ try std .testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1299+ .prefix_before = "" ,
1300+ .suffix_before = "-=-=-=-=-=" ,
1301+ .prefix_after = "x" ,
1302+ .suffix_after = "" ,
1303+ .common_middle = "x-=-=-=-=-=-=-=" ,
1304+ }), try one_timeout .diffHalfMatch (arena .allocator (), "x-=-=-=-=-=-=-=-=-=-=-=-=" , "xx-=-=-=-=-=-=-=" )); // Multiple Matches #2
1305+
1306+ try std .testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1307+ .prefix_before = "-=-=-=-=-=" ,
1308+ .suffix_before = "" ,
1309+ .prefix_after = "" ,
1310+ .suffix_after = "y" ,
1311+ .common_middle = "-=-=-=-=-=-=-=y" ,
1312+ }), try one_timeout .diffHalfMatch (arena .allocator (), "-=-=-=-=-=-=-=-=-=-=-=-=y" , "-=-=-=-=-=-=-=yy" )); // Multiple Matches #3
1313+
1314+ // Other cases
1315+ // Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy
1316+ try std .testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1317+ .prefix_before = "qHillo" ,
1318+ .suffix_before = "w" ,
1319+ .prefix_after = "x" ,
1320+ .suffix_after = "Hulloy" ,
1321+ .common_middle = "HelloHe" ,
1322+ }), try one_timeout .diffHalfMatch (arena .allocator (), "qHilloHelloHew" , "xHelloHeHulloy" )); // Non-optimal halfmatch
1323+
1324+ one_timeout .diff_timeout = 0 ;
1325+ try std .testing .expectEqualDeep (@as (? HalfMatchResult , null ), try one_timeout .diffHalfMatch (arena .allocator (), "qHilloHelloHew" , "xHelloHeHulloy" )); // Non-optimal halfmatch
12181326}
0 commit comments