1+ use alloc:: sync:: Arc ;
12#[ cfg( all( not( feature = "std" ) , feature = "alloc" , feature = "lfn" ) ) ]
23use alloc:: vec:: Vec ;
34use core:: num;
@@ -21,12 +22,12 @@ use super::time::TimeProvider;
2122#[ cfg( feature = "lfn" ) ]
2223const LFN_PADDING : u16 = 0xFFFF ;
2324
24- pub ( crate ) enum DirRawStream < ' a , IO : ReadWriteSeek + Send + Sync , TP , OCC > {
25- File ( File < ' a , IO , TP , OCC > ) ,
26- Root ( DiskSlice < FsIoAdapter < ' a , IO , TP , OCC > , FsIoAdapter < ' a , IO , TP , OCC > > ) ,
25+ pub ( crate ) enum DirRawStream < IO : ReadWriteSeek + Send + Sync , TP , OCC > {
26+ File ( File < IO , TP , OCC > ) ,
27+ Root ( DiskSlice < FsIoAdapter < IO , TP , OCC > , FsIoAdapter < IO , TP , OCC > > ) ,
2728}
2829
29- impl < IO : ReadWriteSeek + Send + Sync , TP , OCC > DirRawStream < ' _ , IO , TP , OCC > {
30+ impl < IO : ReadWriteSeek + Send + Sync , TP , OCC > DirRawStream < IO , TP , OCC > {
3031 fn abs_pos ( & self ) -> Option < u64 > {
3132 match self {
3233 DirRawStream :: File ( file) => file. abs_pos ( ) ,
@@ -50,7 +51,7 @@ impl<IO: ReadWriteSeek + Send + Sync, TP, OCC> DirRawStream<'_, IO, TP, OCC> {
5051}
5152
5253// Note: derive cannot be used because of invalid bounds. See: https://github.com/rust-lang/rust/issues/26925
53- impl < IO : ReadWriteSeek + Send + Sync , TP , OCC > Clone for DirRawStream < ' _ , IO , TP , OCC > {
54+ impl < IO : ReadWriteSeek + Send + Sync , TP , OCC > Clone for DirRawStream < IO , TP , OCC > {
5455 fn clone ( & self ) -> Self {
5556 match self {
5657 DirRawStream :: File ( file) => DirRawStream :: File ( file. clone ( ) ) ,
@@ -59,13 +60,11 @@ impl<IO: ReadWriteSeek + Send + Sync, TP, OCC> Clone for DirRawStream<'_, IO, TP
5960 }
6061}
6162
62- impl < IO : ReadWriteSeek + Send + Sync , TP , OCC > IoBase for DirRawStream < ' _ , IO , TP , OCC > {
63+ impl < IO : ReadWriteSeek + Send + Sync , TP , OCC > IoBase for DirRawStream < IO , TP , OCC > {
6364 type Error = Error < IO :: Error > ;
6465}
6566
66- impl < IO : ReadWriteSeek + Send + Sync , TP : TimeProvider , OCC > Read
67- for DirRawStream < ' _ , IO , TP , OCC >
68- {
67+ impl < IO : ReadWriteSeek + Send + Sync , TP : TimeProvider , OCC > Read for DirRawStream < IO , TP , OCC > {
6968 fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , Self :: Error > {
7069 match self {
7170 DirRawStream :: File ( file) => file. read ( buf) ,
@@ -74,9 +73,7 @@ impl<IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC> Read
7473 }
7574}
7675
77- impl < IO : ReadWriteSeek + Send + Sync , TP : TimeProvider , OCC > Write
78- for DirRawStream < ' _ , IO , TP , OCC >
79- {
76+ impl < IO : ReadWriteSeek + Send + Sync , TP : TimeProvider , OCC > Write for DirRawStream < IO , TP , OCC > {
8077 fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize , Self :: Error > {
8178 match self {
8279 DirRawStream :: File ( file) => file. write ( buf) ,
@@ -91,7 +88,7 @@ impl<IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC> Write
9188 }
9289}
9390
94- impl < IO : ReadWriteSeek + Send + Sync , TP , OCC > Seek for DirRawStream < ' _ , IO , TP , OCC > {
91+ impl < IO : ReadWriteSeek + Send + Sync , TP , OCC > Seek for DirRawStream < IO , TP , OCC > {
9592 fn seek ( & mut self , pos : SeekFrom ) -> Result < u64 , Self :: Error > {
9693 match self {
9794 DirRawStream :: File ( file) => file. seek ( pos) ,
@@ -107,45 +104,40 @@ fn split_path(path: &str) -> (&str, Option<&str>) {
107104 } )
108105}
109106
110- enum DirEntryOrShortName < ' a , IO : ReadWriteSeek + Send + Sync , TP , OCC > {
111- DirEntry ( DirEntry < ' a , IO , TP , OCC > ) ,
107+ enum DirEntryOrShortName < IO : ReadWriteSeek + Send + Sync , TP , OCC > {
108+ DirEntry ( DirEntry < IO , TP , OCC > ) ,
112109 ShortName ( [ u8 ; SFN_SIZE ] ) ,
113110}
114111
115112/// A FAT filesystem directory.
116113///
117114/// This struct is created by the `open_dir` or `create_dir` methods on `Dir`.
118115/// The root directory is returned by the `root_dir` method on `FileSystem`.
119- pub struct Dir < ' a , IO : ReadWriteSeek + Send + Sync , TP , OCC > {
120- stream : DirRawStream < ' a , IO , TP , OCC > ,
121- fs : & ' a FileSystem < IO , TP , OCC > ,
116+ pub struct Dir < IO : ReadWriteSeek + Send + Sync , TP , OCC > {
117+ stream : DirRawStream < IO , TP , OCC > ,
118+ fs : Arc < FileSystem < IO , TP , OCC > > ,
122119}
123120
124- impl < ' a , IO : ReadWriteSeek + Send + Sync , TP , OCC > Dir < ' a , IO , TP , OCC > {
125- pub ( crate ) fn new (
126- stream : DirRawStream < ' a , IO , TP , OCC > ,
127- fs : & ' a FileSystem < IO , TP , OCC > ,
128- ) -> Self {
121+ impl < IO : ReadWriteSeek + Send + Sync , TP , OCC > Dir < IO , TP , OCC > {
122+ pub ( crate ) fn new ( stream : DirRawStream < IO , TP , OCC > , fs : Arc < FileSystem < IO , TP , OCC > > ) -> Self {
129123 Dir { stream, fs }
130124 }
131125
132126 /// Creates directory entries iterator.
133127 #[ must_use]
134128 #[ allow( clippy:: iter_not_returning_iterator) ]
135- pub fn iter ( & self ) -> DirIter < ' a , IO , TP , OCC > {
136- DirIter :: new ( self . stream . clone ( ) , self . fs , true )
129+ pub fn iter ( & self ) -> DirIter < IO , TP , OCC > {
130+ DirIter :: new ( self . stream . clone ( ) , self . fs . clone ( ) , true )
137131 }
138132}
139133
140- impl < ' a , IO : ReadWriteSeek + Send + Sync , TP : TimeProvider , OCC : OemCpConverter >
141- Dir < ' a , IO , TP , OCC >
142- {
134+ impl < IO : ReadWriteSeek + Send + Sync , TP : TimeProvider , OCC : OemCpConverter > Dir < IO , TP , OCC > {
143135 fn find_entry (
144136 & self ,
145137 name : & str ,
146138 is_dir : Option < bool > ,
147139 mut short_name_gen : Option < & mut ShortNameGenerator > ,
148- ) -> Result < DirEntry < ' a , IO , TP , OCC > , Error < IO :: Error > > {
140+ ) -> Result < DirEntry < IO , TP , OCC > , Error < IO :: Error > > {
149141 for r in self . iter ( ) {
150142 let e = r?;
151143 // compare name ignoring case
@@ -172,8 +164,8 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC: OemCpConverter>
172164 #[ allow( clippy:: type_complexity) ]
173165 pub ( crate ) fn find_volume_entry (
174166 & self ,
175- ) -> Result < Option < DirEntry < ' a , IO , TP , OCC > > , Error < IO :: Error > > {
176- for r in DirIter :: new ( self . stream . clone ( ) , self . fs , false ) {
167+ ) -> Result < Option < DirEntry < IO , TP , OCC > > , Error < IO :: Error > > {
168+ for r in DirIter :: new ( self . stream . clone ( ) , self . fs . clone ( ) , false ) {
177169 let e = r?;
178170 if e. data . is_volume ( ) {
179171 return Ok ( Some ( e) ) ;
@@ -186,7 +178,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC: OemCpConverter>
186178 & self ,
187179 name : & str ,
188180 is_dir : Option < bool > ,
189- ) -> Result < DirEntryOrShortName < ' a , IO , TP , OCC > , Error < IO :: Error > > {
181+ ) -> Result < DirEntryOrShortName < IO , TP , OCC > , Error < IO :: Error > > {
190182 let mut short_name_gen = ShortNameGenerator :: new ( name) ;
191183 loop {
192184 // find matching entry
@@ -241,7 +233,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC: OemCpConverter>
241233 /// * `Error::NotFound` will be returned if `path` points to a non-existing directory entry.
242234 /// * `Error::InvalidInput` will be returned if `path` points to a file that is a directory.
243235 /// * `Error::Io` will be returned if the underlying storage object returned an I/O error.
244- pub fn open_file ( & self , path : & str ) -> Result < File < ' a , IO , TP , OCC > , Error < IO :: Error > > {
236+ pub fn open_file ( & self , path : & str ) -> Result < File < IO , TP , OCC > , Error < IO :: Error > > {
245237 log:: trace!( "Dir::open_file {path}" ) ;
246238 // traverse path
247239 let ( name, rest_opt) = split_path ( path) ;
@@ -268,7 +260,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC: OemCpConverter>
268260 /// * `Error::UnsupportedFileNameCharacter` will be returned if the file name contains an invalid character.
269261 /// * `Error::NotEnoughSpace` will be returned if there is not enough free space to create a new file.
270262 /// * `Error::Io` will be returned if the underlying storage object returned an I/O error.
271- pub fn create_file ( & self , path : & str ) -> Result < File < ' a , IO , TP , OCC > , Error < IO :: Error > > {
263+ pub fn create_file ( & self , path : & str ) -> Result < File < IO , TP , OCC > , Error < IO :: Error > > {
272264 log:: trace!( "Dir::create_file {path}" ) ;
273265 // traverse path
274266 let ( name, rest_opt) = split_path ( path) ;
@@ -321,7 +313,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC: OemCpConverter>
321313 // directory does not exist - create it
322314 DirEntryOrShortName :: ShortName ( short_name) => {
323315 // alloc cluster for directory data
324- let cluster = self . fs . alloc_cluster ( None , true ) ?;
316+ let cluster = FileSystem :: alloc_cluster ( & self . fs , None , true ) ?;
325317 // create entry in parent directory
326318 let sfn_entry =
327319 self . create_sfn_entry ( short_name, FileAttributes :: DIRECTORY , Some ( cluster) ) ;
@@ -395,7 +387,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC: OemCpConverter>
395387 }
396388 // free data
397389 if let Some ( n) = e. first_cluster ( ) {
398- self . fs . free_cluster_chain ( n) ?;
390+ FileSystem :: free_cluster_chain ( & self . fs , n) ?;
399391 }
400392 // free long and short name entries
401393 let mut stream = self . stream . clone ( ) ;
@@ -495,7 +487,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC: OemCpConverter>
495487 fn find_free_entries (
496488 & self ,
497489 num_entries : u32 ,
498- ) -> Result < DirRawStream < ' a , IO , TP , OCC > , Error < IO :: Error > > {
490+ ) -> Result < DirRawStream < IO , TP , OCC > , Error < IO :: Error > > {
499491 let mut stream = self . stream . clone ( ) ;
500492 let mut first_free: u32 = 0 ;
501493 let mut num_free: u32 = 0 ;
@@ -559,7 +551,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC: OemCpConverter>
559551 & self ,
560552 lfn_utf16 : & LfnBuffer ,
561553 short_name : & [ u8 ; SFN_SIZE ] ,
562- ) -> Result < ( DirRawStream < ' a , IO , TP , OCC > , u64 ) , Error < IO :: Error > > {
554+ ) -> Result < ( DirRawStream < IO , TP , OCC > , u64 ) , Error < IO :: Error > > {
563555 // get short name checksum
564556 let lfn_chsum = lfn_checksum ( short_name) ;
565557 // create LFN entries generator
@@ -576,7 +568,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC: OemCpConverter>
576568 }
577569
578570 #[ allow( clippy:: type_complexity) ]
579- fn alloc_sfn_entry ( & self ) -> Result < ( DirRawStream < ' a , IO , TP , OCC > , u64 ) , Error < IO :: Error > > {
571+ fn alloc_sfn_entry ( & self ) -> Result < ( DirRawStream < IO , TP , OCC > , u64 ) , Error < IO :: Error > > {
580572 let mut stream = self . find_free_entries ( 1 ) ?;
581573 let start_pos = stream. seek ( super :: super :: io:: SeekFrom :: Current ( 0 ) ) ?;
582574 Ok ( ( stream, start_pos) )
@@ -586,7 +578,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC: OemCpConverter>
586578 & self ,
587579 name : & str ,
588580 raw_entry : DirFileEntryData ,
589- ) -> Result < DirEntry < ' a , IO , TP , OCC > , Error < IO :: Error > > {
581+ ) -> Result < DirEntry < IO , TP , OCC > , Error < IO :: Error > > {
590582 log:: trace!( "Dir::write_entry {name}" ) ;
591583 // check if name doesn't contain unsupported characters
592584 validate_long_name ( name) ?;
@@ -618,7 +610,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC: OemCpConverter>
618610 short_name,
619611 #[ cfg( feature = "lfn" ) ]
620612 lfn_utf16,
621- fs : self . fs ,
613+ fs : self . fs . clone ( ) ,
622614 entry_pos : start_abs_pos,
623615 offset_range : ( start_pos, end_pos) ,
624616 } )
@@ -627,30 +619,30 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC: OemCpConverter>
627619
628620// Note: derive cannot be used because of invalid bounds. See: https://github.com/rust-lang/rust/issues/26925
629621impl < IO : ReadWriteSeek + Send + Sync , TP : TimeProvider , OCC : OemCpConverter > Clone
630- for Dir < ' _ , IO , TP , OCC >
622+ for Dir < IO , TP , OCC >
631623{
632624 fn clone ( & self ) -> Self {
633625 Self {
634626 stream : self . stream . clone ( ) ,
635- fs : self . fs ,
627+ fs : self . fs . clone ( ) ,
636628 }
637629 }
638630}
639631
640632/// An iterator over the directory entries.
641633///
642634/// This struct is created by the `iter` method on `Dir`.
643- pub struct DirIter < ' a , IO : ReadWriteSeek + Send + Sync , TP , OCC > {
644- stream : DirRawStream < ' a , IO , TP , OCC > ,
645- fs : & ' a FileSystem < IO , TP , OCC > ,
635+ pub struct DirIter < IO : ReadWriteSeek + Send + Sync , TP , OCC > {
636+ stream : DirRawStream < IO , TP , OCC > ,
637+ fs : Arc < FileSystem < IO , TP , OCC > > ,
646638 skip_volume : bool ,
647639 err : bool ,
648640}
649641
650- impl < ' a , IO : ReadWriteSeek + Send + Sync , TP , OCC > DirIter < ' a , IO , TP , OCC > {
642+ impl < IO : ReadWriteSeek + Send + Sync , TP , OCC > DirIter < IO , TP , OCC > {
651643 fn new (
652- stream : DirRawStream < ' a , IO , TP , OCC > ,
653- fs : & ' a FileSystem < IO , TP , OCC > ,
644+ stream : DirRawStream < IO , TP , OCC > ,
645+ fs : Arc < FileSystem < IO , TP , OCC > > ,
654646 skip_volume : bool ,
655647 ) -> Self {
656648 DirIter {
@@ -662,7 +654,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP, OCC> DirIter<'a, IO, TP, OCC> {
662654 }
663655}
664656
665- impl < ' a , IO : ReadWriteSeek + Send + Sync , TP : TimeProvider , OCC > DirIter < ' a , IO , TP , OCC > {
657+ impl < IO : ReadWriteSeek + Send + Sync , TP : TimeProvider , OCC > DirIter < IO , TP , OCC > {
666658 fn should_skip_entry ( & self , raw_entry : & DirEntryData ) -> bool {
667659 if raw_entry. is_deleted ( ) {
668660 return true ;
@@ -674,7 +666,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC> DirIter<'a, IO,
674666 }
675667
676668 #[ allow( clippy:: type_complexity) ]
677- fn read_dir_entry ( & mut self ) -> Result < Option < DirEntry < ' a , IO , TP , OCC > > , Error < IO :: Error > > {
669+ fn read_dir_entry ( & mut self ) -> Result < Option < DirEntry < IO , TP , OCC > > , Error < IO :: Error > > {
678670 log:: trace!( "DirIter::read_dir_entry" ) ;
679671 let mut lfn_builder = LongNameBuilder :: new ( ) ;
680672 let mut offset = self . stream . seek ( SeekFrom :: Current ( 0 ) ) ?;
@@ -713,7 +705,7 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC> DirIter<'a, IO,
713705 short_name,
714706 #[ cfg( feature = "lfn" ) ]
715707 lfn_utf16 : lfn_builder. into_buf ( ) ,
716- fs : self . fs ,
708+ fs : self . fs . clone ( ) ,
717709 entry_pos : abs_pos,
718710 offset_range : ( begin_offset, offset) ,
719711 } ) ) ;
@@ -729,21 +721,19 @@ impl<'a, IO: ReadWriteSeek + Send + Sync, TP: TimeProvider, OCC> DirIter<'a, IO,
729721}
730722
731723// Note: derive cannot be used because of invalid bounds. See: https://github.com/rust-lang/rust/issues/26925
732- impl < IO : ReadWriteSeek + Send + Sync , TP , OCC > Clone for DirIter < ' _ , IO , TP , OCC > {
724+ impl < IO : ReadWriteSeek + Send + Sync , TP , OCC > Clone for DirIter < IO , TP , OCC > {
733725 fn clone ( & self ) -> Self {
734726 Self {
735727 stream : self . stream . clone ( ) ,
736- fs : self . fs ,
728+ fs : self . fs . clone ( ) ,
737729 err : self . err ,
738730 skip_volume : self . skip_volume ,
739731 }
740732 }
741733}
742734
743- impl < ' a , IO : ReadWriteSeek + Send + Sync , TP : TimeProvider , OCC > Iterator
744- for DirIter < ' a , IO , TP , OCC >
745- {
746- type Item = Result < DirEntry < ' a , IO , TP , OCC > , Error < IO :: Error > > ;
735+ impl < IO : ReadWriteSeek + Send + Sync , TP : TimeProvider , OCC > Iterator for DirIter < IO , TP , OCC > {
736+ type Item = Result < DirEntry < IO , TP , OCC > , Error < IO :: Error > > ;
747737
748738 fn next ( & mut self ) -> Option < Self :: Item > {
749739 if self . err {
0 commit comments