Skip to content

Convenient variable-granularity chunk iterator #40

Description

@KnorpelSenf

I think this crate is amazing for its focus on performance. However, it isn't particularly convenient to use yet. One reason is that only line diffs are supported out of the box. Technically, one could implement a custom tokenizer and perform more granular diffs, or even run imara repeatedly on varying chunk sizes, but that's not exactly obvious and still requires a fair bit of complexity for library consumers.

I suggest the addition of a new convenience wrapper. It should be a very simple function (maybe called diff) for the main use case of this crate: provide a diff of two human-readable text strings. It should return the diff in a format that is trivial to understand even for people who have never thought about string diffing before (i.e. it shouldn't even require a knowledge of tokens).

It could take two strings and return an iterator of the following enum:

enum Chunk<'p, 'n> {
    Insert(&'n str),
    Delete(&'p str),
    Replace(&'p str, &'n str),
    Equal(&'n str),
}

We can add a method .index() to the iterator to drag along the two byte offsets in the old and the new string.

The implementation should implement a new heuristic to balance performance and character accuracy. It could:

  • perform a line diff and iterate over its hunks
  • if the current hunk is a pure insertion, yield Insert
  • if the current hunk is a pure deletion, yield Delete
  • if the current hunk is small in size (less than, say, 100 tokens), perform a word diff (feat: word diffs #33) and iterate over its hunks
    • if the current hunk is a pure insertion, yield Insert
    • if the current hunk is a pure deletion, yield Delete
    • if the current hunk is small in size (less than, say, 100 tokens), perform a character diff (feat: character diffs #38) and yield its hunks via Insert, Delete, and Replace
    • else, yield Replace
  • else, yield Replace

After every item, Equal should be interspersed.

We might want to add a more sophisticated heuristic than a simple size check, such as guessing the complexity of the diff by looking at the number of added/removed tokens and/or factoring in token size.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions