uqa_storage/native_file/
path_watch.rs1use std::{io, path::Path};
10
11#[cfg(target_os = "linux")]
12#[path = "path_watch/linux.rs"]
13mod platform;
14#[cfg(target_os = "macos")]
15#[path = "path_watch/macos.rs"]
16mod platform;
17
18pub struct PathChangeWatch {
23 #[cfg(any(target_os = "linux", target_os = "macos"))]
24 watch: platform::Watch,
25 process: u32,
26 changed: bool,
27}
28
29impl PathChangeWatch {
30 pub fn new(path: &Path) -> io::Result<Self> {
31 #[cfg(any(target_os = "linux", target_os = "macos"))]
32 {
33 if path.components().any(|component| {
34 matches!(
35 component,
36 std::path::Component::CurDir | std::path::Component::ParentDir
37 )
38 }) {
39 return Err(unsupported());
40 }
41 let parent = path
42 .parent()
43 .filter(|_| path.is_absolute())
44 .ok_or_else(unsupported)?;
45 let watch = platform::Watch::new(parent)?;
46 if path.symlink_metadata()?.file_type().is_symlink() {
51 return Err(unsupported());
52 }
53 Ok(Self {
54 watch,
55 process: std::process::id(),
56 changed: false,
57 })
58 }
59 #[cfg(not(any(target_os = "linux", target_os = "macos")))]
60 {
61 let _ = path;
62 Err(unsupported())
63 }
64 }
65
66 pub fn changed(&mut self) -> io::Result<bool> {
68 if self.changed || self.process != std::process::id() {
69 return Ok(true);
70 }
71 self.changed = true;
73 #[cfg(any(target_os = "linux", target_os = "macos"))]
74 {
75 self.changed = self.watch.changed()?;
76 }
77 Ok(self.changed)
78 }
79}
80
81fn unsupported() -> io::Error {
82 io::Error::new(
83 io::ErrorKind::Unsupported,
84 "pathname requires direct identity checks",
85 )
86}
87
88#[cfg(all(test, any(target_os = "linux", target_os = "macos")))]
89mod tests;