Repository: hannobraun/inotify-rs (language: rust)

Issue:
Consider redesign of the field `name` in `Event`
The name, as returned by inotify, is only set, if the watch refers to a directory, and the event is for a file within that directory. This means, if you're watching a file directly, the name will be empty.

As this has lead to confusion among users in the past, I propose the following two measures:
- Clearly explain this in the documentation of the field.
- Consider changing the type of the field to `Option<&'a OsStr>`, to make it clear that the name is not always set.


Discussion / hints:

Fix patch:
diff --git a/inotify/src/lib.rs b/inotify/src/lib.rs
index 2303904..4e0a675 100644
--- a/inotify/src/lib.rs
+++ b/inotify/src/lib.rs
@@ -721,7 +721,11 @@ pub struct Event<'a> {
     pub cookie: u32,
 
     /// The name of the file the event originates from
-    pub name  : &'a OsStr,
+    ///
+    /// This field is set only, if the subject of the event is a file in a
+    /// wacthed directory. If the event concerns a file or directory that is
+    /// watched directly, `name` will be `None`.
+    pub name  : Option<&'a OsStr>,
 }
 
 impl<'a> Event<'a> {
@@ -734,6 +738,13 @@ impl<'a> Event<'a> {
             fd: fd,
         };
 
+        let name = if name == "" {
+            None
+        }
+        else {
+            Some(name)
+        };
+
         Event {
             wd    : wd,
             mask  : mask,


Test patch:
diff --git a/inotify/tests/main.rs b/inotify/tests/main.rs
index 9ce8f87..cdd8932 100644
--- a/inotify/tests/main.rs
+++ b/inotify/tests/main.rs
@@ -50,14 +50,30 @@ fn it_should_return_immediately_if_no_events_are_available() {
 }
 
 #[test]
-fn it_should_handle_file_names_correctly() {
+fn it_should_convert_the_name_into_an_os_str() {
     let mut testdir = TestDir::new();
-    let (mut path, mut file) = testdir.new_file();
-    let file_name = path
-        .file_name().unwrap()
-        .to_str().unwrap()
-        .to_string();
-    path.pop(); // Get path to the directory the file is in
+    let (path, mut file) = testdir.new_file();
+
+    let mut inotify = Inotify::init().unwrap();
+    inotify.add_watch(&path.parent().unwrap(), watch_mask::MODIFY).unwrap();
+
+    write_to(&mut file);
+
+    let mut buffer = [0; 1024];
+    let mut events = inotify.read_events_blocking(&mut buffer).unwrap();
+
+    if let Some(event) = events.next() {
+        assert_eq!(path.file_name(), event.name);
+    }
+    else {
+        panic!("Expected inotify event");
+    }
+}
+
+#[test]
+fn it_should_set_name_to_none_if_it_is_empty() {
+    let mut testdir = TestDir::new();
+    let (path, mut file) = testdir.new_file();
 
     let mut inotify = Inotify::init().unwrap();
     inotify.add_watch(&path, watch_mask::MODIFY).unwrap();
@@ -65,14 +81,14 @@ fn it_should_handle_file_names_correctly() {
     write_to(&mut file);
 
     let mut buffer = [0; 1024];
-    let events = inotify.read_events_blocking(&mut buffer).unwrap();
+    let mut events = inotify.read_events_blocking(&mut buffer).unwrap();
 
-    let mut num_events = 0;
-    for event in events {
-        assert_eq!(file_name, event.name.to_str().unwrap());
-        num_events += 1;
+    if let Some(event) = events.next() {
+        assert_eq!(event.name, None);
+    }
+    else {
+        panic!("Expected inotify event");
     }
-    assert!(num_events > 0);
 }
 
 #[test]