Repository: sharkdp/bat (language: rust)

Issue:
`Controller::run_with_error_handler` does not allow the handler closure to modify variables outside
I'm using `bat::controller::Controller` and I'd like to handle error(s) while printing outputs in my application side. I tried to capture the last error with `FnMut` closure:

```rust
use bat::controller::Controller;

let mut controller = Controller::new(...);

// ...

let inputs = ...;

let mut last_error: Option<MyError> = None;
controller.run_with_error_handler(inputs, |err, _| {
   last_error = Some(err.into()); 
})?;
```

But the handler type is bounded by `Fn` so it could not modify the variable outside:

```
error[E0594]: cannot assign to `last_error`, as it is a captured variable in a `Fn` closure
   --> src/bat.rs:169:13
    |
110 |     pub fn print(&self, file: File) -> Result<()> {
    |            -----                       ---------- change this to return `FnMut` instead of `Fn`
...
168 |         if controller.run_with_error_handler(vec![input], None, |err, _| {
    |                                                                 -------- in this closure
169 |             last_error = Some(err);
    |             ^^^^^^^^^^^^^^^^^^^^^^ cannot assign
```

I'd like to request to modify the `Fn` bound to `FnMut` to make error handling more flexible.


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 39cac34d7e..492adaf94c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,6 +28,7 @@
 
 ## `bat` as a library
 
+- Make `Controller::run_with_error_handler`'s error handler `FnMut`, see #2831 (@rhysd)
 
 # v0.24.0
 
diff --git a/src/controller.rs b/src/controller.rs
index f378cbc662..ffc5dd5b57 100644
--- a/src/controller.rs
+++ b/src/controller.rs
@@ -47,7 +47,7 @@ impl<'b> Controller<'b> {
         &self,
         inputs: Vec<Input>,
         output_buffer: Option<&mut dyn std::fmt::Write>,
-        handle_error: impl Fn(&Error, &mut dyn Write),
+        mut handle_error: impl FnMut(&Error, &mut dyn Write),
     ) -> Result<bool> {
         let mut output_type;
 


Test patch: