I have Arc<Mutex<_>> data in an enum. Now I would like to call a function on the enum and pass a closure/callback so that the enum will unlock the inner data and pass it through the closure before closing the lock.
use std::ops::Deref;
use std::sync::{Arc, Mutex};
#[derive(Default)]
struct Note {
nothing: (),
// ...
}
/// a data struct that contains references to every field of the base struct
struct NoteData<'a> {
nothing: &'a (),
// ...
}
/// a function to instantiate a data struct
fn note_to_data(note: &Note) -> NoteData {
NoteData {
nothing: ¬e.nothing,
}
}
/// a model that encapsulates multiple possible entities
enum Model {
Note(Arc<Mutex<Note>>),
// ...
}
impl Model {
/// a function that allows performing a calculation on the data struct without
/// needing to export a mutable reference outside of the enum, which would cause locking issues
pub fn with_data<'a>(&'a self, func: impl Fn(NoteData<'a>)) {
match self {
Model::Note(note) => {
let lock : MutexGuard<Note> = note.lock().unwrap();
let borrowed : &Note = lock.deref();
let data : NoteData = note_to_data(borrowed);
func(data); // the data struct with the references that depend on the lock are moved and dropped. Why is the lock complaining it still doesn't live long enough?
// ... "`lock` dropped here while still borrowed"
}
}
}
}
#[test]
fn test_closure() {
let model = Model::Note(Arc::new(Mutex::new(Note::default())));
model.with_data(|data| {
println!("{:?}", data.nothing);
});
}
It doesn't work however and I'm puzzled why that is the case, since the NoteData struct is dropped by moving it to the 'func' closure call and should not outlive the lock. (other answer where exactly this works)
The error is the following:
error[E0597]: `lock` does not live long enough
--> lib/experiment/src/lib.rs:28:32
|
24 | pub fn with_data<'a>(&'a self, func: impl Fn(NoteData<'a>)) {
| -- lifetime `'a` defined here
...
28 | let borrowed = lock.deref();
| ^^^^^^^^^^^^
| |
| borrowed value does not live long enough
| argument requires that `lock` is borrowed for `'a`
...
31 | }
| - `lock` dropped here while still borrowed