mitsuhiko / similar

A high level diffing library for rust based on diffs
https://insta.rs/similar
Apache License 2.0
974 stars 32 forks source link

How to return an owned diff with TextDiff::configure().diff_lines #65

Open lbirkert opened 3 months ago

lbirkert commented 3 months ago

TextDiff::configure().diff_lines does not want to accept owned Strings as arguments, only String references. Therefore I cannot return it, as the String I parse is owned by the current function. How can I transfer ownership to return this diff?

lbirkert commented 3 months ago

Am I forced to write a custom similar::Change type which allows owned Strings and then map every change to that custom struct or is there somehow a builtin method to do that?

max-sixty commented 3 months ago

Could you post a code example?

lbirkert commented 3 months ago

sure.

pub fn my_func() -> ... {
    // in reality these buffers are non trivial to fetch
    let old = fs::read(path_old).unwrap();
    let old = std::str::from_utf8(old).unwrap();
    let new = fs::read(path_old).unwrap();
    let new = std::str::from_utf8(new).unwrap();

    // I'd like to return this diff to process it further
    // but old and new are only refs to Strings which belong to the
    // current function, so they will be dropped once
    // we exit the function
    TextDiff::configure().diff_lines(old, new)

    // This is what I would like to do, to_string would turn
    // them owned and therefore ownership would get transfered 
    // to the TextDiff, allowing me to return it, as there is
    // no dependence on values owned by the current function
    //
    // This does not work though, diff_lines requires refs
    TextDiff::configure().diff_lines(old.to_string(), new.to_string())
}

I hope this makes it clear.

mitsuhiko commented 3 months ago

Yes, this is not possible today. However this is not a lost cause as you can work around this with self_cell: https://docs.rs/self_cell/latest/self_cell/

This is related to #33.

lbirkert commented 3 months ago

Alright. Thanks for the tip

lbirkert commented 3 months ago

I cannot get this to work. Self cell throws lifetime errors. Can you please post an example on how to do this?