dyz1990 / sevenz-rust

A 7z decompressor/compressor lib written in pure rust
Apache License 2.0
146 stars 24 forks source link

Make function generics less restrictive #17

Closed marcospb19 closed 1 year ago

marcospb19 commented 1 year ago

From the documentation of FnMut:

Since FnOnce is a supertrait of FnMut, any instance of FnMut can be used where a FnOnce is expected, and since Fn is a subtrait of FnMut, any instance of Fn can be used where FnMut is expected.

And from the docs of Fn:

Use Fn as a bound when you want to accept a parameter of function-like type and need to call it repeatedly and without mutating state (e.g., when calling it concurrently). If you do not need such strict requirements, use FnMut or FnOnce as bounds.

Basically Fn is more restrictive, and if you don't need the restrictions, you should go with FnMut or FnOnce.

Here's a real example where Fn instead of FnMut generated an slightly more complicated code:

use std::cell::RefCell;

let a = RefCell::new(Vec::new());

sevenz_rust::decompress_file_with_extract_fn(archive_path, ".", |entry, _, _| {
    let name = entry.name().to_string();
    a.borrow_mut().push(name);
    Ok(true)
})

By replacing Fn by FnMut:

let a = Vec::new(); // simplified here

sevenz_rust::decompress_file_with_extract_fn(archive_path, ".", |entry, _, _| {
    let name = entry.name().to_string();
    a.push(name); // simplified here
    Ok(true)
})