11use cfg_if:: cfg_if;
2+ use futures:: future:: BoxFuture ;
23use std:: {
34 fs, io,
45 path:: { Path , PathBuf } ,
@@ -19,7 +20,7 @@ pub trait FileSystem {
1920 /// because object safety requirements, it is especially useful, when
2021 /// you want to store multiple `dyn FileSystem` in a `Vec` or use a `ResolverGeneric<Fs>` in
2122 /// napi env.
22- async fn read_to_string ( & self , path : & Path ) -> io:: Result < String > ;
23+ fn read_to_string < ' a > ( & ' a self , path : & ' a Path ) -> BoxFuture < ' a , io:: Result < String > > ;
2324
2425 /// See [std::fs::metadata]
2526 ///
@@ -30,7 +31,7 @@ pub trait FileSystem {
3031 /// because object safety requirements, it is especially useful, when
3132 /// you want to store multiple `dyn FileSystem` in a `Vec` or use a `ResolverGeneric<Fs>` in
3233 /// napi env.
33- async fn metadata ( & self , path : & Path ) -> io:: Result < FileMetadata > ;
34+ fn metadata < ' a > ( & ' a self , path : & ' a Path ) -> BoxFuture < ' a , io:: Result < FileMetadata > > ;
3435
3536 /// See [std::fs::symlink_metadata]
3637 ///
@@ -42,7 +43,7 @@ pub trait FileSystem {
4243 /// because object safety requirements, it is especially useful, when
4344 /// you want to store multiple `dyn FileSystem` in a `Vec` or use a `ResolverGeneric<Fs>` in
4445 /// napi env.
45- async fn symlink_metadata ( & self , path : & Path ) -> io:: Result < FileMetadata > ;
46+ fn symlink_metadata < ' a > ( & ' a self , path : & ' a Path ) -> BoxFuture < ' a , io:: Result < FileMetadata > > ;
4647
4748 /// See [std::fs::canonicalize]
4849 ///
@@ -54,7 +55,7 @@ pub trait FileSystem {
5455 /// because object safety requirements, it is especially useful, when
5556 /// you want to store multiple `dyn FileSystem` in a `Vec` or use a `ResolverGeneric<Fs>` in
5657 /// napi env.
57- async fn canonicalize ( & self , path : & Path ) -> io:: Result < PathBuf > ;
58+ fn canonicalize < ' a > ( & ' a self , path : & ' a Path ) -> BoxFuture < ' a , io:: Result < PathBuf > > ;
5859}
5960
6061/// Metadata information about a file
@@ -120,92 +121,102 @@ impl Default for FileSystemOs {
120121// }
121122
122123impl FileSystem for FileSystemOs {
123- async fn read_to_string ( & self , path : & Path ) -> io:: Result < String > {
124- cfg_if ! {
125- if #[ cfg( feature = "yarn_pnp" ) ] {
126- match VPath :: from( path) ? {
127- VPath :: Zip ( info) => {
128- self . pnp_lru. read_to_string( info. physical_base_path( ) , info. zip_path)
124+ fn read_to_string < ' a > ( & ' a self , path : & ' a Path ) -> BoxFuture < ' a , io:: Result < String > > {
125+ let fut = async move {
126+ cfg_if ! {
127+ if #[ cfg( feature = "yarn_pnp" ) ] {
128+ match VPath :: from( path) ? {
129+ VPath :: Zip ( info) => {
130+ self . pnp_lru. read_to_string( info. physical_base_path( ) , info. zip_path)
131+ }
132+ VPath :: Virtual ( info) => tokio:: fs:: read_to_string( & info. physical_base_path( ) ) . await ,
133+ VPath :: Native ( path) => tokio:: fs:: read_to_string( & path) . await ,
129134 }
130- VPath :: Virtual ( info ) => tokio :: fs :: read_to_string ( & info . physical_base_path ( ) ) . await ,
131- VPath :: Native ( path ) => tokio:: fs:: read_to_string( & path) . await ,
135+ } else {
136+ tokio:: fs:: read_to_string( path) . await
132137 }
133- } else {
134- tokio:: fs:: read_to_string( path) . await
135138 }
136- }
139+ } ;
140+ Box :: pin ( fut)
137141 }
138142
139- async fn metadata ( & self , path : & Path ) -> io:: Result < FileMetadata > {
140- cfg_if ! {
141- if #[ cfg( feature = "yarn_pnp" ) ] {
142- match VPath :: from( path) ? {
143- VPath :: Zip ( info) => self
144- . pnp_lru
145- . file_type( info. physical_base_path( ) , info. zip_path)
146- . map( FileMetadata :: from) ,
147- VPath :: Virtual ( info) => {
148- tokio:: fs:: metadata( info. physical_base_path( ) ) . await . map( FileMetadata :: from)
143+ fn metadata < ' a > ( & ' a self , path : & ' a Path ) -> BoxFuture < ' a , io:: Result < FileMetadata > > {
144+ let fut = async move {
145+ cfg_if ! {
146+ if #[ cfg( feature = "yarn_pnp" ) ] {
147+ match VPath :: from( path) ? {
148+ VPath :: Zip ( info) => self
149+ . pnp_lru
150+ . file_type( info. physical_base_path( ) , info. zip_path)
151+ . map( FileMetadata :: from) ,
152+ VPath :: Virtual ( info) => {
153+ tokio:: fs:: metadata( info. physical_base_path( ) ) . await . map( FileMetadata :: from)
154+ }
155+ VPath :: Native ( path) => tokio:: fs:: metadata( path) . await . map( FileMetadata :: from) ,
149156 }
150- VPath :: Native ( path) => tokio:: fs:: metadata( path) . await . map( FileMetadata :: from) ,
157+ } else {
158+ tokio:: fs:: metadata( path) . await . map( FileMetadata :: from)
151159 }
152- } else {
153- tokio:: fs:: metadata( path) . await . map( FileMetadata :: from)
154160 }
155- }
161+ } ;
162+ Box :: pin ( fut)
156163 }
157164
158- async fn symlink_metadata ( & self , path : & Path ) -> io:: Result < FileMetadata > {
159- tokio:: fs:: symlink_metadata ( path) . await . map ( FileMetadata :: from)
165+ fn symlink_metadata < ' a > ( & ' a self , path : & ' a Path ) -> BoxFuture < ' a , io:: Result < FileMetadata > > {
166+ let fut = async move { tokio:: fs:: symlink_metadata ( path) . await . map ( FileMetadata :: from) } ;
167+ Box :: pin ( fut)
160168 }
161169
162- async fn canonicalize ( & self , path : & Path ) -> io:: Result < PathBuf > {
163- cfg_if ! {
164- if #[ cfg( feature = "yarn_pnp" ) ] {
165- match VPath :: from( path) ? {
166- VPath :: Zip ( info) => {
167- dunce:: canonicalize( info. physical_base_path( ) . join( info. zip_path) )
170+ fn canonicalize < ' a > ( & ' a self , path : & ' a Path ) -> BoxFuture < ' a , io:: Result < PathBuf > > {
171+ let fut = async move {
172+ cfg_if ! {
173+ if #[ cfg( feature = "yarn_pnp" ) ] {
174+ match VPath :: from( path) ? {
175+ VPath :: Zip ( info) => {
176+ dunce:: canonicalize( info. physical_base_path( ) . join( info. zip_path) )
177+ }
178+ VPath :: Virtual ( info) => dunce:: canonicalize( info. physical_base_path( ) ) ,
179+ VPath :: Native ( path) => dunce:: canonicalize( path) ,
168180 }
169- VPath :: Virtual ( info) => dunce:: canonicalize( info. physical_base_path( ) ) ,
170- VPath :: Native ( path) => dunce:: canonicalize( path) ,
171- }
172- } else if #[ cfg( not( target_os = "wasi" ) ) ] {
173- dunce:: canonicalize( path)
174- } else {
175- use std:: path:: Component ;
176- let mut path_buf = path. to_path_buf( ) ;
177- loop {
178- let link = tokio:: fs:: read_link( & path_buf) . await ?;
179- path_buf. pop( ) ;
180- for component in link. components( ) {
181- match component {
182- Component :: ParentDir => {
183- path_buf. pop( ) ;
184- }
185- Component :: Normal ( seg) => {
186- #[ cfg( target_family = "wasm" ) ]
187- // Need to trim the extra \0 introduces by https://github.com/nodejs/uvwasi/issues/262
188- {
189- path_buf. push( seg. to_string_lossy( ) . trim_end_matches( '\0' ) ) ;
181+ } else if #[ cfg( not( target_os = "wasi" ) ) ] {
182+ dunce:: canonicalize( path)
183+ } else {
184+ use std:: path:: Component ;
185+ let mut path_buf = path. to_path_buf( ) ;
186+ loop {
187+ let link = tokio:: fs:: read_link( & path_buf) . await ?;
188+ path_buf. pop( ) ;
189+ for component in link. components( ) {
190+ match component {
191+ Component :: ParentDir => {
192+ path_buf. pop( ) ;
190193 }
191- #[ cfg( not( target_family = "wasm" ) ) ]
192- {
193- path_buf. push( seg) ;
194+ Component :: Normal ( seg) => {
195+ #[ cfg( target_family = "wasm" ) ]
196+ // Need to trim the extra \0 introduces by https://github.com/nodejs/uvwasi/issues/262
197+ {
198+ path_buf. push( seg. to_string_lossy( ) . trim_end_matches( '\0' ) ) ;
199+ }
200+ #[ cfg( not( target_family = "wasm" ) ) ]
201+ {
202+ path_buf. push( seg) ;
203+ }
194204 }
205+ Component :: RootDir => {
206+ path_buf = PathBuf :: from( "/" ) ;
207+ }
208+ Component :: CurDir | Component :: Prefix ( _) => { }
195209 }
196- Component :: RootDir => {
197- path_buf = PathBuf :: from( "/" ) ;
198- }
199- Component :: CurDir | Component :: Prefix ( _) => { }
210+ }
211+ if !tokio:: fs:: symlink_metadata( & path_buf) . await ?. is_symlink( ) {
212+ break ;
200213 }
201214 }
202- if !tokio:: fs:: symlink_metadata( & path_buf) . await ?. is_symlink( ) {
203- break ;
204- }
215+ Ok ( path_buf)
205216 }
206- Ok ( path_buf)
207217 }
208- }
218+ } ;
219+ Box :: pin ( fut)
209220 }
210221}
211222
0 commit comments