cardinal_sdk/
event.rs

1use crate::{EventFlag, FSEventStreamEventId, ScanType};
2use std::{
3    ffi::{CStr, OsStr},
4    os::unix::ffi::OsStrExt,
5    path::{Path, PathBuf},
6};
7
8#[derive(Debug)]
9pub struct FsEvent {
10    /// The path of this event.
11    pub path: PathBuf,
12    /// The event type.
13    pub flag: EventFlag,
14    /// The event id.
15    pub id: FSEventStreamEventId,
16}
17
18impl FsEvent {
19    pub(crate) unsafe fn from_raw(path: *const i8, flag: u32, id: u64) -> Self {
20        let path = unsafe { CStr::from_ptr(path) };
21        let path = OsStr::from_bytes(path.to_bytes());
22        let path = PathBuf::from(path);
23        let flag = EventFlag::from_bits_truncate(flag);
24        FsEvent { path, flag, id }
25    }
26
27    pub fn should_rescan(&self, root: &Path) -> bool {
28        match self.flag.scan_type() {
29            ScanType::ReScan => true,
30            ScanType::SingleNode | ScanType::Folder if self.path == root => true,
31            ScanType::SingleNode | ScanType::Folder | ScanType::Nop => false,
32        }
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use std::path::PathBuf;
40
41    #[test]
42    fn test_should_rescan() {
43        let root = std::path::Path::new("/root");
44
45        // ReScan always true
46        let event = FsEvent {
47            path: PathBuf::from("/root/file"),
48            flag: EventFlag::RootChanged,
49            id: 1,
50        };
51        assert!(event.should_rescan(root));
52
53        // SingleNode at root true
54        let event = FsEvent {
55            path: PathBuf::from("/root"),
56            flag: EventFlag::ItemModified | EventFlag::ItemIsFile,
57            id: 1,
58        };
59        assert!(event.should_rescan(root));
60
61        // SingleNode not at root false
62        let event = FsEvent {
63            path: PathBuf::from("/root/sub/file"),
64            flag: EventFlag::ItemModified | EventFlag::ItemIsFile,
65            id: 1,
66        };
67        assert!(!event.should_rescan(root));
68
69        // Nop false
70        let event = FsEvent {
71            path: PathBuf::from("/root/file"),
72            flag: EventFlag::HistoryDone,
73            id: 1,
74        };
75        assert!(!event.should_rescan(root));
76    }
77}