private function getUnifiedDiffHunk()

in src/StringDiff.php [93:149]


  private function getUnifiedDiffHunk(vec<DiffOp<string>> $hunk): ?string {
    if (C\is_empty($hunk)) {
      return null;
    }
    $old_start = null;
    $new_start = null;
    $old_lines = 0;
    $new_lines = 0;

    $lines = vec[];

    foreach ($hunk as $op) {
      if ($op->isKeepOp()) {
        $op = $op->asKeepOp();
        $lines[] = ' '.$op->getContent();
        $old_start ??= $op->getOldPos();
        $new_start ??= $op->getNewPos();
        ++$old_lines;
        ++$new_lines;
        continue;
      }

      if ($op->isDeleteOp()) {
        $op = $op->asDeleteOp();
        $lines[] = '-'.$op->getContent();
        $old_start ??= $op->getOldPos();
        $new_start ??= $op->getOldPos();
        ++$old_lines;
        continue;
      }

      if ($op->isInsertOp()) {
        $op = $op->asInsertOp();
        $lines[] = '+'.$op->getContent();
        $old_start ??= $op->getNewPos();
        $new_start ??= $op->getNewPos();
        ++$new_lines;
        continue;
      }

      invariant_violation('Unsupported diff op: %s', \get_class($op));
    }
    invariant($old_start !== null, 'failed to find an old pos');
    invariant($new_start !== null, 'failed to find a new pos');

    $format = (int $start, int $lines) ==> ($start === 1 && $lines === 1)
      ? '1'
      : Str\format('%d,%d', $start, $lines);

    return Str\format(
      "@@ -%s +%s @@\n",
      $format($old_start + 1, $old_lines),
      $format($new_start + 1, $new_lines),
    ).
      Str\join($lines, "\n").
      "\n";
  }