1
1
use serde:: Deserialize ;
2
- use std:: { path:: { Path , PathBuf } , str:: Utf8Error } ;
2
+ use std:: {
3
+ path:: { Path , PathBuf } ,
4
+ str:: Utf8Error ,
5
+ } ;
3
6
4
7
use crate :: zip:: Zip ;
5
8
@@ -79,18 +82,14 @@ pub enum Error {
79
82
pub fn open_zip_via_mmap < P : AsRef < Path > > ( p : P ) -> Result < Zip < mmap_rs:: Mmap > , std:: io:: Error > {
80
83
let file = fs:: File :: open ( p) ?;
81
84
82
- let mmap_builder = mmap_rs :: MmapOptions :: new ( file . metadata ( ) . unwrap ( ) . len ( ) . try_into ( ) . unwrap ( ) )
83
- . unwrap ( ) ;
85
+ let mmap_builder =
86
+ mmap_rs :: MmapOptions :: new ( file . metadata ( ) . unwrap ( ) . len ( ) . try_into ( ) . unwrap ( ) ) . unwrap ( ) ;
84
87
85
- let mmap = unsafe {
86
- mmap_builder
87
- . with_file ( file, 0 )
88
- . map ( )
89
- . unwrap ( )
90
- } ;
88
+ let mmap = unsafe { mmap_builder. with_file ( file, 0 ) . map ( ) . unwrap ( ) } ;
91
89
92
- let zip = Zip :: new ( mmap)
93
- . map_err ( |_| std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "Failed to read the zip file" ) ) ?;
90
+ let zip = Zip :: new ( mmap) . map_err ( |_| {
91
+ std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "Failed to read the zip file" )
92
+ } ) ?;
94
93
95
94
Ok ( zip)
96
95
}
@@ -103,8 +102,9 @@ pub fn open_zip_via_mmap_p(p: &Path) -> Result<Zip<mmap_rs::Mmap>, std::io::Erro
103
102
pub fn open_zip_via_read < P : AsRef < Path > > ( p : P ) -> Result < Zip < Vec < u8 > > , std:: io:: Error > {
104
103
let data = std:: fs:: read ( p) ?;
105
104
106
- let zip = Zip :: new ( data)
107
- . map_err ( |_| std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "Failed to read the zip file" ) ) ?;
105
+ let zip = Zip :: new ( data) . map_err ( |_| {
106
+ std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "Failed to read the zip file" )
107
+ } ) ?;
108
108
109
109
Ok ( zip)
110
110
}
@@ -114,50 +114,85 @@ pub fn open_zip_via_read_p(p: &Path) -> Result<Zip<Vec<u8>>, std::io::Error> {
114
114
}
115
115
116
116
pub trait ZipCache < Storage >
117
- where Storage : AsRef < [ u8 ] > + Send + Sync {
118
- fn act < T , P : AsRef < Path > , F : FnOnce ( & Zip < Storage > ) -> T > ( & self , p : P , cb : F ) -> Result < T , std:: io:: Error > ;
119
-
120
- fn file_type < P : AsRef < Path > , S : AsRef < str > > ( & self , zip_path : P , sub : S ) -> Result < FileType , std:: io:: Error > ;
121
- fn read < P : AsRef < Path > , S : AsRef < str > > ( & self , zip_path : P , sub : S ) -> Result < Vec < u8 > , std:: io:: Error > ;
122
- fn read_to_string < P : AsRef < Path > , S : AsRef < str > > ( & self , zip_path : P , sub : S ) -> Result < String , std:: io:: Error > ;
117
+ where
118
+ Storage : AsRef < [ u8 ] > + Send + Sync ,
119
+ {
120
+ fn act < T , P : AsRef < Path > , F : FnOnce ( & Zip < Storage > ) -> T > (
121
+ & self ,
122
+ p : P ,
123
+ cb : F ,
124
+ ) -> Result < T , std:: io:: Error > ;
125
+
126
+ fn file_type < P : AsRef < Path > , S : AsRef < str > > (
127
+ & self ,
128
+ zip_path : P ,
129
+ sub : S ,
130
+ ) -> Result < FileType , std:: io:: Error > ;
131
+ fn read < P : AsRef < Path > , S : AsRef < str > > (
132
+ & self ,
133
+ zip_path : P ,
134
+ sub : S ,
135
+ ) -> Result < Vec < u8 > , std:: io:: Error > ;
136
+ fn read_to_string < P : AsRef < Path > , S : AsRef < str > > (
137
+ & self ,
138
+ zip_path : P ,
139
+ sub : S ,
140
+ ) -> Result < String , std:: io:: Error > ;
123
141
}
124
142
125
143
#[ derive( Debug ) ]
126
144
pub struct LruZipCache < Storage >
127
- where Storage : AsRef < [ u8 ] > + Send + Sync {
145
+ where
146
+ Storage : AsRef < [ u8 ] > + Send + Sync ,
147
+ {
128
148
lru : concurrent_lru:: sharded:: LruCache < PathBuf , Zip < Storage > > ,
129
149
open : fn ( & Path ) -> std:: io:: Result < Zip < Storage > > ,
130
150
}
131
151
132
152
impl < Storage > LruZipCache < Storage >
133
- where Storage : AsRef < [ u8 ] > + Send + Sync {
153
+ where
154
+ Storage : AsRef < [ u8 ] > + Send + Sync ,
155
+ {
134
156
pub fn new ( n : u64 , open : fn ( & Path ) -> std:: io:: Result < Zip < Storage > > ) -> LruZipCache < Storage > {
135
- LruZipCache {
136
- lru : concurrent_lru:: sharded:: LruCache :: new ( n) ,
137
- open,
138
- }
157
+ LruZipCache { lru : concurrent_lru:: sharded:: LruCache :: new ( n) , open }
139
158
}
140
159
}
141
160
142
161
impl < Storage > ZipCache < Storage > for LruZipCache < Storage >
143
- where Storage : AsRef < [ u8 ] > + Send + Sync {
144
- fn act < T , P : AsRef < Path > , F : FnOnce ( & Zip < Storage > ) -> T > ( & self , p : P , cb : F ) -> Result < T , std:: io:: Error > {
145
- let zip = self . lru . get_or_try_init ( p. as_ref ( ) . to_path_buf ( ) , 1 , |p| {
146
- ( self . open ) ( & p)
147
- } ) ?;
162
+ where
163
+ Storage : AsRef < [ u8 ] > + Send + Sync ,
164
+ {
165
+ fn act < T , P : AsRef < Path > , F : FnOnce ( & Zip < Storage > ) -> T > (
166
+ & self ,
167
+ p : P ,
168
+ cb : F ,
169
+ ) -> Result < T , std:: io:: Error > {
170
+ let zip = self . lru . get_or_try_init ( p. as_ref ( ) . to_path_buf ( ) , 1 , |p| ( self . open ) ( & p) ) ?;
148
171
149
172
Ok ( cb ( zip. value ( ) ) )
150
173
}
151
174
152
- fn file_type < P : AsRef < Path > , S : AsRef < str > > ( & self , zip_path : P , p : S ) -> Result < FileType , std:: io:: Error > {
175
+ fn file_type < P : AsRef < Path > , S : AsRef < str > > (
176
+ & self ,
177
+ zip_path : P ,
178
+ p : S ,
179
+ ) -> Result < FileType , std:: io:: Error > {
153
180
self . act ( zip_path, |zip| zip. file_type ( p. as_ref ( ) ) ) ?
154
181
}
155
182
156
- fn read < P : AsRef < Path > , S : AsRef < str > > ( & self , zip_path : P , p : S ) -> Result < Vec < u8 > , std:: io:: Error > {
183
+ fn read < P : AsRef < Path > , S : AsRef < str > > (
184
+ & self ,
185
+ zip_path : P ,
186
+ p : S ,
187
+ ) -> Result < Vec < u8 > , std:: io:: Error > {
157
188
self . act ( zip_path, |zip| zip. read ( p. as_ref ( ) ) ) ?
158
189
}
159
190
160
- fn read_to_string < P : AsRef < Path > , S : AsRef < str > > ( & self , zip_path : P , p : S ) -> Result < String , std:: io:: Error > {
191
+ fn read_to_string < P : AsRef < Path > , S : AsRef < str > > (
192
+ & self ,
193
+ zip_path : P ,
194
+ p : S ,
195
+ ) -> Result < String , std:: io:: Error > {
161
196
self . act ( zip_path, |zip| zip. read_to_string ( p. as_ref ( ) ) ) ?
162
197
}
163
198
}
@@ -167,31 +202,23 @@ fn vpath(p: &Path) -> std::io::Result<VPath> {
167
202
return Ok ( VPath :: Native ( p. to_path_buf ( ) ) ) ;
168
203
} ;
169
204
170
- let normalized_path
171
- = crate :: util:: normalize_path ( p_str) ;
205
+ let normalized_path = crate :: util:: normalize_path ( p_str) ;
172
206
173
207
// We remove potential leading slashes to avoid __virtual__ accidentally removing them
174
- let normalized_relative_path
175
- = normalized_path. strip_prefix ( '/' )
176
- . unwrap_or ( & normalized_path) ;
208
+ let normalized_relative_path = normalized_path. strip_prefix ( '/' ) . unwrap_or ( & normalized_path) ;
177
209
178
- let mut segment_it
179
- = normalized_relative_path. split ( '/' ) ;
210
+ let mut segment_it = normalized_relative_path. split ( '/' ) ;
180
211
181
212
// `split` returns [""] if the path is empty; we need to remove it
182
213
if normalized_relative_path. is_empty ( ) {
183
214
segment_it. next ( ) ;
184
215
}
185
216
186
- let mut base_items: Vec < & str >
187
- = Vec :: new ( ) ;
217
+ let mut base_items: Vec < & str > = Vec :: new ( ) ;
188
218
189
- let mut virtual_items: Option < Vec < & str > >
190
- = None ;
191
- let mut internal_items: Option < Vec < & str > >
192
- = None ;
193
- let mut zip_items: Option < Vec < & str > >
194
- = None ;
219
+ let mut virtual_items: Option < Vec < & str > > = None ;
220
+ let mut internal_items: Option < Vec < & str > > = None ;
221
+ let mut zip_items: Option < Vec < & str > > = None ;
195
222
196
223
while let Some ( segment) = segment_it. next ( ) {
197
224
if let Some ( zip_segments) = & mut zip_items {
@@ -200,8 +227,7 @@ fn vpath(p: &Path) -> std::io::Result<VPath> {
200
227
}
201
228
202
229
if segment == "__virtual__" && virtual_items. is_none ( ) {
203
- let mut acc_segments
204
- = Vec :: with_capacity ( 3 ) ;
230
+ let mut acc_segments = Vec :: with_capacity ( 3 ) ;
205
231
206
232
acc_segments. push ( segment) ;
207
233
@@ -212,15 +238,14 @@ fn vpath(p: &Path) -> std::io::Result<VPath> {
212
238
213
239
// We retrieve the depth
214
240
if let Some ( depth_segment) = segment_it. next ( ) {
215
- let depth = depth_segment
216
- . parse :: < usize > ( ) ;
241
+ let depth = depth_segment. parse :: < usize > ( ) ;
217
242
218
243
acc_segments. push ( depth_segment) ;
219
244
220
245
// We extract the backward segments from the base ones
221
246
if let Ok ( depth) = depth {
222
- let parent_segments = base_items
223
- . split_off ( base_items. len ( ) . saturating_sub ( depth) ) ;
247
+ let parent_segments =
248
+ base_items . split_off ( base_items. len ( ) . saturating_sub ( depth) ) ;
224
249
225
250
acc_segments. splice ( 0 ..0 , parent_segments) ;
226
251
}
@@ -259,9 +284,7 @@ fn vpath(p: &Path) -> std::io::Result<VPath> {
259
284
Some ( ( virtual_segments. join ( "/" ) , internal_segments. join ( "/" ) ) )
260
285
}
261
286
262
- _ => {
263
- None
264
- } ,
287
+ _ => None ,
265
288
} ;
266
289
267
290
if let Some ( zip_segments) = zip_items {
@@ -273,12 +296,9 @@ fn vpath(p: &Path) -> std::io::Result<VPath> {
273
296
} ) ) ;
274
297
}
275
298
}
276
-
299
+
277
300
if let Some ( virtual_info) = virtual_info {
278
- return Ok ( VPath :: Virtual ( VirtualInfo {
279
- base_path,
280
- virtual_segments : virtual_info,
281
- } ) ) ;
301
+ return Ok ( VPath :: Virtual ( VirtualInfo { base_path, virtual_segments : virtual_info } ) ) ;
282
302
}
283
303
284
304
Ok ( VPath :: Native ( PathBuf :: from ( base_path) ) )
@@ -328,39 +348,53 @@ mod tests {
328
348
329
349
#[ test]
330
350
fn test_zip_list ( ) {
331
- let zip = open_zip_via_read ( & PathBuf :: from ( "data/@babel-plugin-syntax-dynamic-import-npm-7.8.3-fb9ff5634a-8.zip" ) )
332
- . unwrap ( ) ;
351
+ let zip = open_zip_via_read ( & PathBuf :: from (
352
+ "data/@babel-plugin-syntax-dynamic-import-npm-7.8.3-fb9ff5634a-8.zip" ,
353
+ ) )
354
+ . unwrap ( ) ;
333
355
334
356
let mut dirs: Vec < & String > = zip. dirs . iter ( ) . collect ( ) ;
335
357
let mut files: Vec < & String > = zip. files . keys ( ) . collect ( ) ;
336
358
337
359
dirs. sort ( ) ;
338
360
files. sort ( ) ;
339
361
340
- assert_eq ! ( dirs, vec![
341
- "node_modules/" ,
342
- "node_modules/@babel/" ,
343
- "node_modules/@babel/plugin-syntax-dynamic-import/" ,
344
- "node_modules/@babel/plugin-syntax-dynamic-import/lib/" ,
345
- ] ) ;
346
-
347
- assert_eq ! ( files, vec![
348
- "node_modules/@babel/plugin-syntax-dynamic-import/LICENSE" ,
349
- "node_modules/@babel/plugin-syntax-dynamic-import/README.md" ,
350
- "node_modules/@babel/plugin-syntax-dynamic-import/lib/index.js" ,
351
- "node_modules/@babel/plugin-syntax-dynamic-import/package.json" ,
352
- ] ) ;
362
+ assert_eq ! (
363
+ dirs,
364
+ vec![
365
+ "node_modules/" ,
366
+ "node_modules/@babel/" ,
367
+ "node_modules/@babel/plugin-syntax-dynamic-import/" ,
368
+ "node_modules/@babel/plugin-syntax-dynamic-import/lib/" ,
369
+ ]
370
+ ) ;
371
+
372
+ assert_eq ! (
373
+ files,
374
+ vec![
375
+ "node_modules/@babel/plugin-syntax-dynamic-import/LICENSE" ,
376
+ "node_modules/@babel/plugin-syntax-dynamic-import/README.md" ,
377
+ "node_modules/@babel/plugin-syntax-dynamic-import/lib/index.js" ,
378
+ "node_modules/@babel/plugin-syntax-dynamic-import/package.json" ,
379
+ ]
380
+ ) ;
353
381
}
354
382
355
383
#[ test]
356
384
fn test_zip_read ( ) {
357
- let zip = open_zip_via_read ( & PathBuf :: from ( "data/@babel-plugin-syntax-dynamic-import-npm-7.8.3-fb9ff5634a-8.zip" ) )
358
- . unwrap ( ) ;
385
+ let zip = open_zip_via_read ( & PathBuf :: from (
386
+ "data/@babel-plugin-syntax-dynamic-import-npm-7.8.3-fb9ff5634a-8.zip" ,
387
+ ) )
388
+ . unwrap ( ) ;
359
389
360
- let res = zip. read_to_string ( "node_modules/@babel/plugin-syntax-dynamic-import/package.json" )
390
+ let res = zip
391
+ . read_to_string ( "node_modules/@babel/plugin-syntax-dynamic-import/package.json" )
361
392
. unwrap ( ) ;
362
393
363
- assert_eq ! ( res, "{\n \" name\" : \" @babel/plugin-syntax-dynamic-import\" ,\n \" version\" : \" 7.8.3\" ,\n \" description\" : \" Allow parsing of import()\" ,\n \" repository\" : \" https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-dynamic-import\" ,\n \" license\" : \" MIT\" ,\n \" publishConfig\" : {\n \" access\" : \" public\" \n },\n \" main\" : \" lib/index.js\" ,\n \" keywords\" : [\n \" babel-plugin\" \n ],\n \" dependencies\" : {\n \" @babel/helper-plugin-utils\" : \" ^7.8.0\" \n },\n \" peerDependencies\" : {\n \" @babel/core\" : \" ^7.0.0-0\" \n },\n \" devDependencies\" : {\n \" @babel/core\" : \" ^7.8.0\" \n }\n }\n " ) ;
394
+ assert_eq ! (
395
+ res,
396
+ "{\n \" name\" : \" @babel/plugin-syntax-dynamic-import\" ,\n \" version\" : \" 7.8.3\" ,\n \" description\" : \" Allow parsing of import()\" ,\n \" repository\" : \" https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-dynamic-import\" ,\n \" license\" : \" MIT\" ,\n \" publishConfig\" : {\n \" access\" : \" public\" \n },\n \" main\" : \" lib/index.js\" ,\n \" keywords\" : [\n \" babel-plugin\" \n ],\n \" dependencies\" : {\n \" @babel/helper-plugin-utils\" : \" ^7.8.0\" \n },\n \" peerDependencies\" : {\n \" @babel/core\" : \" ^7.0.0-0\" \n },\n \" devDependencies\" : {\n \" @babel/core\" : \" ^7.8.0\" \n }\n }\n "
397
+ ) ;
364
398
}
365
399
366
400
#[ rstest]
0 commit comments