@@ -97,9 +97,8 @@ impl<'a> ResourcePaths<'a> {
9797 iter : ResourcePathsIter {
9898 pattern_iter : PatternIter :: Slice ( patterns. iter ( ) ) ,
9999 allow_walk,
100- current_pattern : None ,
101- walk_iter : None ,
102- glob_iter : None ,
100+ current_dest : None ,
101+ current_iter : None ,
103102 } ,
104103 }
105104 }
@@ -110,9 +109,8 @@ impl<'a> ResourcePaths<'a> {
110109 iter : ResourcePathsIter {
111110 pattern_iter : PatternIter :: Map ( patterns. iter ( ) ) ,
112111 allow_walk,
113- current_pattern : None ,
114- walk_iter : None ,
115- glob_iter : None ,
112+ current_dest : None ,
113+ current_iter : None ,
116114 } ,
117115 }
118116 }
@@ -132,122 +130,139 @@ pub struct ResourcePathsIter<'a> {
132130 /// whether the resource paths allows directories or not.
133131 allow_walk : bool ,
134132
135- /// The (key, value) of map when ` pattern_iter` is a [`PatternIter::Map`],
133+ /// The value of map when [`Self:: pattern_iter`] is a [`PatternIter::Map`],
136134 /// used for determining [`Resource::target`]
137- current_pattern : Option < ( String , PathBuf ) > ,
138-
139- walk_iter : Option < walkdir :: IntoIter > ,
140- glob_iter : Option < glob :: Paths > ,
135+ current_dest : Option < PathBuf > ,
136+ /// The iter for the current pattern. The cycle goes like this:
137+ /// [`ResourcePaths::next`] -> [`Self::next`] -> [`Self::pattern_iter::next`] -> [`Self::current_iter::next`]
138+ current_iter : Option < ResourcePathsInnerIter > ,
141139}
142140
143- impl ResourcePathsIter < ' _ > {
144- fn next_glob_iter ( & mut self ) -> Option < crate :: Result < Resource > > {
145- let entry = self . glob_iter . as_mut ( ) . unwrap ( ) . next ( ) ?;
141+ #[ derive( Debug ) ]
142+ enum ResourcePathsInnerIter {
143+ Walk {
144+ iter : walkdir:: IntoIter ,
145+ /// The key of map when [`ResourcePathsIter::pattern_iter`] is a [`PatternIter::Map`],
146+ /// used for determining [`Resource::target`]
147+ current_pattern : Option < PathBuf > ,
148+ } ,
149+ Glob {
150+ iter : glob:: Paths ,
151+ } ,
152+ }
146153
147- let entry = match entry {
148- Ok ( entry) => entry,
149- Err ( err) => return Some ( Err ( err. into ( ) ) ) ,
150- } ;
154+ impl Iterator for ResourcePathsInnerIter {
155+ type Item = crate :: Result < PathBuf > ;
151156
152- self . next_current_path ( normalize ( & entry) )
157+ fn next ( & mut self ) -> Option < crate :: Result < PathBuf > > {
158+ match self {
159+ ResourcePathsInnerIter :: Walk { iter, .. } => Some (
160+ iter
161+ . next ( ) ?
162+ . map ( |entry| entry. into_path ( ) )
163+ . map_err ( Into :: into) ,
164+ ) ,
165+ ResourcePathsInnerIter :: Glob { iter } => Some ( iter. next ( ) ?. map_err ( Into :: into) ) ,
166+ }
153167 }
168+ }
154169
155- fn next_walk_iter ( & mut self ) -> Option < crate :: Result < Resource > > {
156- let entry = self . walk_iter . as_mut ( ) . unwrap ( ) . next ( ) ?;
157-
158- let entry = match entry {
159- Ok ( entry) => entry,
160- Err ( err) => return Some ( Err ( err. into ( ) ) ) ,
161- } ;
162-
163- self . next_current_path ( normalize ( entry. path ( ) ) )
170+ impl ResourcePathsIter < ' _ > {
171+ fn next_current_iter ( & mut self ) -> Option < crate :: Result < Resource > > {
172+ let current_iter = self . current_iter . as_mut ( ) . unwrap ( ) ;
173+ let entry = current_iter. next ( ) ?;
174+
175+ Some ( match entry {
176+ Ok ( entry) => {
177+ // Skip directories
178+ if entry. is_dir ( ) {
179+ self . next_current_iter ( ) ?
180+ } else {
181+ self . resource_from_path ( normalize ( & entry) )
182+ }
183+ }
184+ Err ( error) => Err ( error) ,
185+ } )
164186 }
165187
166- fn resource_from_path ( & mut self , path : & Path ) -> crate :: Result < Resource > {
188+ fn resource_from_path ( & self , path : PathBuf ) -> crate :: Result < Resource > {
167189 if !path. exists ( ) {
168- return Err ( crate :: Error :: ResourcePathNotFound ( path. to_path_buf ( ) ) ) ;
190+ return Err ( crate :: Error :: ResourcePathNotFound ( path) ) ;
169191 }
170192
171193 Ok ( Resource {
172- path : path. to_path_buf ( ) ,
173- target : if let Some ( ( pattern, dest) ) = & self . current_pattern {
174- // if processing a directory, preserve directory structure under current_dest
175- if self . walk_iter . is_some ( ) {
176- dest. join ( path. strip_prefix ( pattern) . unwrap_or ( path) )
177- } else if dest. components ( ) . count ( ) == 0 {
178- // if current_dest is empty while processing a file pattern or glob
179- // we preserve the file name as it is
180- PathBuf :: from ( path. file_name ( ) . unwrap ( ) )
181- } else if self . glob_iter . is_some ( ) {
182- // if processing a glob and current_dest is not empty
183- // we put all globbed paths under current_dest
184- // preserving the file name as it is
185- dest. join ( path. file_name ( ) . unwrap ( ) )
186- } else {
187- dest. clone ( )
194+ target : if let Some ( dest) = & self . current_dest {
195+ match & self . current_iter {
196+ Some ( current_iter) => match current_iter {
197+ // if processing a directory, preserve directory structure under current_dest
198+ ResourcePathsInnerIter :: Walk {
199+ current_pattern, ..
200+ } => {
201+ if let Some ( pattern) = current_pattern {
202+ dest. join ( path. strip_prefix ( pattern) . unwrap_or ( & path) )
203+ } else {
204+ dest. join ( & path)
205+ }
206+ }
207+ // if processing a glob and current_dest is not empty
208+ // we put all globbed paths under current_dest
209+ // preserving the file name as it is
210+ ResourcePathsInnerIter :: Glob { .. } => dest. join ( path. file_name ( ) . unwrap ( ) ) ,
211+ } ,
212+ None => dest. clone ( ) ,
188213 }
189214 } else {
190- // If ` pattern_iter` is a [`PatternIter::Slice`]
191- resource_relpath ( path)
215+ // If [`ResourcePathsIter:: pattern_iter`] is a [`PatternIter::Slice`]
216+ resource_relpath ( & path)
192217 } ,
218+ path,
193219 } )
194220 }
195221
196- fn next_current_path ( & mut self , path : PathBuf ) -> Option < crate :: Result < Resource > > {
197- let is_dir = path. is_dir ( ) ;
198-
199- if is_dir {
200- if self . glob_iter . is_some ( ) {
201- return self . next ( ) ;
202- }
203-
204- if !self . allow_walk {
205- return Some ( Err ( crate :: Error :: NotAllowedToWalkDir ( path. to_path_buf ( ) ) ) ) ;
206- }
207-
208- if self . walk_iter . is_none ( ) {
209- self . walk_iter = Some ( WalkDir :: new ( & path) . into_iter ( ) ) ;
210- }
211-
212- match self . next_walk_iter ( ) {
213- Some ( resource) => Some ( resource) ,
214- None => {
215- self . walk_iter = None ;
216- self . next ( )
217- }
218- }
219- } else {
220- Some ( self . resource_from_path ( & path) )
221- }
222- }
223-
224222 fn next_pattern ( & mut self ) -> Option < crate :: Result < Resource > > {
225- self . current_pattern = None ;
223+ self . current_dest = None ;
226224
227225 let pattern = match & mut self . pattern_iter {
228226 PatternIter :: Slice ( iter) => iter. next ( ) ?,
229227 PatternIter :: Map ( iter) => {
230228 let ( pattern, dest) = iter. next ( ) ?;
231- self . current_pattern = Some ( ( pattern . clone ( ) , resource_relpath ( Path :: new ( dest) ) ) ) ;
229+ self . current_dest = Some ( resource_relpath ( Path :: new ( dest) ) ) ;
232230 pattern
233231 }
234232 } ;
235233
236234 if pattern. contains ( '*' ) {
237- self . glob_iter = match glob:: glob ( pattern) {
238- Ok ( glob) => Some ( glob) ,
235+ self . current_iter = match glob:: glob ( pattern) {
236+ Ok ( glob) => Some ( ResourcePathsInnerIter :: Glob { iter : glob } ) ,
239237 Err ( error) => return Some ( Err ( error. into ( ) ) ) ,
240238 } ;
241- match self . next_glob_iter ( ) {
239+ match self . next_current_iter ( ) {
242240 Some ( r) => return Some ( r) ,
243241 None => {
244- self . glob_iter = None ;
242+ self . current_iter = None ;
245243 return Some ( Err ( crate :: Error :: GlobPathNotFound ( pattern. clone ( ) ) ) ) ;
246244 }
247245 }
246+ } else {
247+ let path = normalize ( Path :: new ( pattern) ) ;
248+ if path. is_dir ( ) {
249+ if !self . allow_walk {
250+ return Some ( Err ( crate :: Error :: NotAllowedToWalkDir ( path) ) ) ;
251+ }
252+ self . current_iter = Some ( ResourcePathsInnerIter :: Walk {
253+ iter : WalkDir :: new ( & path) . into_iter ( ) ,
254+ current_pattern : if matches ! ( self . pattern_iter, PatternIter :: Map ( _) ) {
255+ Some ( path)
256+ } else {
257+ None
258+ } ,
259+ } ) ;
260+ } else {
261+ return Some ( self . resource_from_path ( path) ) ;
262+ }
248263 }
249264
250- self . next_current_path ( normalize ( Path :: new ( pattern ) ) )
265+ self . next_current_iter ( )
251266 }
252267}
253268
@@ -263,17 +278,10 @@ impl Iterator for ResourcePathsIter<'_> {
263278 type Item = crate :: Result < Resource > ;
264279
265280 fn next ( & mut self ) -> Option < crate :: Result < Resource > > {
266- if self . walk_iter . is_some ( ) {
267- match self . next_walk_iter ( ) {
281+ if self . current_iter . is_some ( ) {
282+ match self . next_current_iter ( ) {
268283 Some ( r) => return Some ( r) ,
269- None => self . walk_iter = None ,
270- }
271- }
272-
273- if self . glob_iter . is_some ( ) {
274- match self . next_glob_iter ( ) {
275- Some ( r) => return Some ( r) ,
276- None => self . glob_iter = None ,
284+ None => self . current_iter = None ,
277285 }
278286 }
279287
@@ -322,6 +330,7 @@ mod tests {
322330 "src-tauri/Cargo.toml" ,
323331 "src-tauri/Tauri.toml" ,
324332 "src-tauri/build.rs" ,
333+ "src-tauri/some-folder/some-file.txt" ,
325334 "src/assets/javascript.svg" ,
326335 "src/assets/tauri.svg" ,
327336 "src/assets/rust.svg" ,
@@ -403,11 +412,11 @@ mod tests {
403412 // From `../src/textures/**/*`
404413 (
405414 "../src/textures/ground/earth.tex" ,
406- "_up_/src/textures/earth.tex" ,
415+ "_up_/src/textures/ground/ earth.tex" ,
407416 ) ,
408417 (
409418 "../src/textures/ground/sand.tex" ,
410- "_up_/src/textures/sand.tex" ,
419+ "_up_/src/textures/ground/ sand.tex" ,
411420 ) ,
412421 ( "../src/textures/water.tex" , "_up_/src/textures/water.tex" ) ,
413422 ( "../src/textures/fire.tex" , "_up_/src/textures/fire.tex" ) ,
@@ -483,6 +492,7 @@ mod tests {
483492 ( "../src/tiles/**/*" , "tiles" ) ,
484493 ( "*.toml" , "" ) ,
485494 ( "*.conf.json" , "json" ) ,
495+ ( "./some-folder/" , "some-target-folder/" ) ,
486496 ( "../non-existent-file" , "asd" ) , // invalid case
487497 ( "../non/*" , "asd" ) , // invalid case
488498 ] ) ,
@@ -511,6 +521,10 @@ mod tests {
511521 ( "Cargo.toml" , "Cargo.toml" ) ,
512522 ( "Tauri.toml" , "Tauri.toml" ) ,
513523 ( "tauri.conf.json" , "json/tauri.conf.json" ) ,
524+ (
525+ "some-folder/some-file.txt" ,
526+ "some-target-folder/some-file.txt" ,
527+ ) ,
514528 ] ) ;
515529
516530 assert_eq ! ( resources. len( ) , expected. len( ) ) ;
@@ -584,7 +598,7 @@ mod tests {
584598 . iter ( )
585599 . collect :: < Vec < _ > > ( ) ;
586600
587- assert_eq ! ( resources. len( ) , 4 ) ;
601+ assert_eq ! ( resources. len( ) , 5 ) ;
588602
589603 assert ! ( resources. iter( ) . all( |r| r. is_err( ) ) ) ;
590604
@@ -617,7 +631,7 @@ mod tests {
617631 . iter( )
618632 . filter( |r| matches!( r, Err ( crate :: Error :: GlobPathNotFound ( _) ) ) )
619633 . count( ) ,
620- 1
634+ 2
621635 ) ;
622636 }
623637}
0 commit comments