Reputation: 14071
I try to get the following code to compile.
Due to the buffer
it wanted more explicit lifetimes inserted. So I tried that but still
cannot figure out yet how to make it also work in for_each
.
use std::{sync::mpsc::Sender, ffi::OsStr};
use inotify::{Event, EventMask, Inotify, WatchMask};
pub struct Watcher<'a> {
buffer: [u8; 1024],
sender: Sender<Event<&'a OsStr>>,
}
impl <'a> Watcher<'a> {
pub fn new(sender: Sender<Event<&OsStr>>) -> Watcher{
Watcher{
buffer: [0; 1024],
sender: sender,
}
}
pub fn watch_for_led_directories(&mut self, dir: String) {
let sender = self.sender.clone();
let mut inotify = Inotify::init().expect("Error while initializing inotify instance");
// Watch for modify and close events.
inotify
.add_watch(dir, WatchMask::CREATE | WatchMask::DELETE)
.expect("Failed to add file watch");
// Read events that were added with `add_watch` above.
let events = inotify
.read_events_blocking(&mut self.buffer)
.expect("Error while reading events");
events.filter(|e| -> bool { !e.mask.intersects(EventMask::ISDIR) }).for_each(|e| sender.send(e).unwrap());
}
}
EDIT:
I ended up giving up on no-copy of strings:
use std::{ffi::OsStr, sync::mpsc::Sender};
use inotify::{Event, EventMask, Inotify, WatchMask};
pub struct Watcher {
buffer: [u8; 1024],
sender: Sender<Event<String>>,
}
impl Watcher {
pub fn new(sender: Sender<Event<String>>) -> Watcher {
Watcher {
buffer: [0; 1024],
sender: sender,
}
}
pub fn watch_for_led_directories(&mut self, dir: String) {
let sender = self.sender.clone();
let mut inotify = Inotify::init().expect("Error while initializing inotify instance");
// Watch for modify and close events.
inotify
.add_watch(dir, WatchMask::CREATE | WatchMask::DELETE)
.expect("Failed to add file watch");
// Read events that were added with `add_watch` above.
let events = inotify
.read_events_blocking(&mut self.buffer)
.expect("Error while reading events");
let filter = |e: &Event<&OsStr>| -> bool {
!e.mask.intersects(EventMask::ISDIR) || e.name.is_none()
};
events.filter(filter).for_each(|e| {
sender
.send(Event {
cookie: e.cookie,
mask: e.mask,
name: Some(e.name.unwrap().to_str().expect("Expected valid unicode string").into()),
wd: e.wd,
})
.unwrap()
});
}
}
Upvotes: 0
Views: 107
Reputation: 149
The issue is that while self
has the lifetime of 'a
, &mut self
in watch_for_led_directories()
has a different lifetime.
inotify.read_events_blocking()
returns events
that has the same lifetime as &mut self.buffer
, which, as a mutable borrow, has the lifetime of &mut self
. But sender
is bound to life time 'a
. Therefore compiler cannot reconcile these two lifetimes.
One way to solve it is to provide an external buffer, instead of having it owned by Watcher
, e.g.:
pub fn watch_for_led_directories(&self, buffer: &'a mut [u8], dir: String) {
...
let events: Events = inotify
.read_events_blocking(buffer)
.expect("Error while reading events");
...
Compiler derives the lifetime of events
from buffer
and therefore it will be 'a
.
To use this method the externally allocated buffer must live at least as long as the Watcher
object, which should not be too difficult to arrange.
Upvotes: 1