1- use std:: path:: { Path , PathBuf } ;
2- use std:: sync:: mpsc:: Receiver ;
3- use std:: { collections:: HashSet , sync:: mpsc:: sync_channel} ;
1+ use std:: {
2+ collections:: HashSet ,
3+ path:: { Path , PathBuf } ,
4+ sync:: mpsc:: { Receiver , sync_channel} ,
5+ } ;
46
57use notify:: { Event , RecommendedWatcher , RecursiveMode , Watcher } ;
68use rustc_codegen_spirv_types:: CompileResult ;
@@ -14,13 +16,16 @@ impl SpirvBuilder {
1416 }
1517}
1618
19+ type WatchedPaths = HashSet < PathBuf > ;
20+
21+ /// Watcher of a crate which rebuilds it on changes.
1722#[ derive( Debug ) ]
1823pub struct SpirvWatcher < B > {
1924 builder : B ,
2025 watcher : RecommendedWatcher ,
2126 rx : Receiver < ( ) > ,
2227 watch_path : PathBuf ,
23- watched_paths : HashSet < PathBuf > ,
28+ watched_paths : WatchedPaths ,
2429 first_result : bool ,
2530}
2631
6772 } )
6873 }
6974
75+ /// Blocks the current thread until a change is detected
76+ /// and the crate is rebuilt.
77+ ///
78+ /// Result of rebuilding of the crate is then returned to the caller.
7079 pub fn recv ( & mut self ) -> Result < CompileResult , SpirvBuilderError > {
7180 if !self . first_result {
7281 return self . recv_first_result ( ) ;
7786 let metadata_file = crate :: invoke_rustc ( builder) ?;
7887 let result = builder. parse_metadata_file ( & metadata_file) ?;
7988
80- self . watch_leaf_deps ( & self . watch_path . clone ( ) ) ?;
89+ Self :: watch_leaf_deps ( & self . watch_path , & mut self . watched_paths , & mut self . watcher ) ?;
8190 Ok ( result)
8291 }
8392
8897 Err ( err) => {
8998 log:: error!( "{err}" ) ;
9099
100+ let watch_path = self . watch_path . as_ref ( ) ;
91101 self . watcher
92- . watch ( & self . watch_path , RecursiveMode :: Recursive )
102+ . watch ( watch_path, RecursiveMode :: Recursive )
93103 . map_err ( SpirvWatcherError :: NotifyFailed ) ?;
94104 let path = loop {
95105 self . rx . recv ( ) . expect ( "watcher should be alive" ) ;
@@ -99,26 +109,28 @@ where
99109 }
100110 } ;
101111 self . watcher
102- . unwatch ( & self . watch_path )
112+ . unwatch ( watch_path)
103113 . map_err ( SpirvWatcherError :: NotifyFailed ) ?;
104114 path
105115 }
106116 } ;
107117 let result = builder. parse_metadata_file ( & metadata_file) ?;
108118
109- self . watch_leaf_deps ( & metadata_file) ?;
119+ Self :: watch_leaf_deps ( & metadata_file, & mut self . watched_paths , & mut self . watcher ) ?;
110120 self . watch_path = metadata_file;
111121 self . first_result = true ;
112122 Ok ( result)
113123 }
114124
115- fn watch_leaf_deps ( & mut self , metadata_file : & Path ) -> Result < ( ) , SpirvBuilderError > {
116- leaf_deps ( metadata_file, |it| {
117- let path = it. to_path ( ) . unwrap ( ) ;
118- if self . watched_paths . insert ( path. to_owned ( ) )
119- && let Err ( err) = self
120- . watcher
121- . watch ( it. to_path ( ) . unwrap ( ) , RecursiveMode :: NonRecursive )
125+ fn watch_leaf_deps (
126+ metadata_file : & Path ,
127+ watched_paths : & mut WatchedPaths ,
128+ watcher : & mut RecommendedWatcher ,
129+ ) -> Result < ( ) , SpirvBuilderError > {
130+ leaf_deps ( metadata_file, |artifact| {
131+ let path = artifact. to_path ( ) . unwrap ( ) ;
132+ if watched_paths. insert ( path. to_owned ( ) )
133+ && let Err ( err) = watcher. watch ( path, RecursiveMode :: NonRecursive )
122134 {
123135 log:: error!( "files of cargo dependencies are not valid: {err}" ) ;
124136 }
@@ -127,10 +139,14 @@ where
127139 }
128140}
129141
130- impl SpirvWatcher < & SpirvBuilder > {
142+ impl < B > SpirvWatcher < B >
143+ where
144+ B : AsRef < SpirvBuilder > ,
145+ {
146+ #[ inline]
131147 pub fn forget_lifetime ( self ) -> SpirvWatcher < SpirvBuilder > {
132148 SpirvWatcher {
133- builder : self . builder . clone ( ) ,
149+ builder : self . builder . as_ref ( ) . clone ( ) ,
134150 watcher : self . watcher ,
135151 rx : self . rx ,
136152 watch_path : self . watch_path ,
0 commit comments