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
+ } ;
4
6
5
7
use notify:: { Event , RecommendedWatcher , RecursiveMode , Watcher } ;
6
8
use rustc_codegen_spirv_types:: CompileResult ;
@@ -14,13 +16,16 @@ impl SpirvBuilder {
14
16
}
15
17
}
16
18
19
+ type WatchedPaths = HashSet < PathBuf > ;
20
+
21
+ /// Watcher of a crate which rebuilds it on changes.
17
22
#[ derive( Debug ) ]
18
23
pub struct SpirvWatcher < B > {
19
24
builder : B ,
20
25
watcher : RecommendedWatcher ,
21
26
rx : Receiver < ( ) > ,
22
27
watch_path : PathBuf ,
23
- watched_paths : HashSet < PathBuf > ,
28
+ watched_paths : WatchedPaths ,
24
29
first_result : bool ,
25
30
}
26
31
67
72
} )
68
73
}
69
74
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.
70
79
pub fn recv ( & mut self ) -> Result < CompileResult , SpirvBuilderError > {
71
80
if !self . first_result {
72
81
return self . recv_first_result ( ) ;
77
86
let metadata_file = crate :: invoke_rustc ( builder) ?;
78
87
let result = builder. parse_metadata_file ( & metadata_file) ?;
79
88
80
- self . watch_leaf_deps ( & self . watch_path . clone ( ) ) ?;
89
+ Self :: watch_leaf_deps ( & self . watch_path , & mut self . watched_paths , & mut self . watcher ) ?;
81
90
Ok ( result)
82
91
}
83
92
88
97
Err ( err) => {
89
98
log:: error!( "{err}" ) ;
90
99
100
+ let watch_path = self . watch_path . as_ref ( ) ;
91
101
self . watcher
92
- . watch ( & self . watch_path , RecursiveMode :: Recursive )
102
+ . watch ( watch_path, RecursiveMode :: Recursive )
93
103
. map_err ( SpirvWatcherError :: NotifyFailed ) ?;
94
104
let path = loop {
95
105
self . rx . recv ( ) . expect ( "watcher should be alive" ) ;
@@ -99,26 +109,28 @@ where
99
109
}
100
110
} ;
101
111
self . watcher
102
- . unwatch ( & self . watch_path )
112
+ . unwatch ( watch_path)
103
113
. map_err ( SpirvWatcherError :: NotifyFailed ) ?;
104
114
path
105
115
}
106
116
} ;
107
117
let result = builder. parse_metadata_file ( & metadata_file) ?;
108
118
109
- self . watch_leaf_deps ( & metadata_file) ?;
119
+ Self :: watch_leaf_deps ( & metadata_file, & mut self . watched_paths , & mut self . watcher ) ?;
110
120
self . watch_path = metadata_file;
111
121
self . first_result = true ;
112
122
Ok ( result)
113
123
}
114
124
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 )
122
134
{
123
135
log:: error!( "files of cargo dependencies are not valid: {err}" ) ;
124
136
}
@@ -127,10 +139,14 @@ where
127
139
}
128
140
}
129
141
130
- impl SpirvWatcher < & SpirvBuilder > {
142
+ impl < B > SpirvWatcher < B >
143
+ where
144
+ B : AsRef < SpirvBuilder > ,
145
+ {
146
+ #[ inline]
131
147
pub fn forget_lifetime ( self ) -> SpirvWatcher < SpirvBuilder > {
132
148
SpirvWatcher {
133
- builder : self . builder . clone ( ) ,
149
+ builder : self . builder . as_ref ( ) . clone ( ) ,
134
150
watcher : self . watcher ,
135
151
rx : self . rx ,
136
152
watch_path : self . watch_path ,
0 commit comments