@@ -2,15 +2,18 @@ use std::{
2
2
collections:: { btree_map:: Entry , BTreeMap } ,
3
3
fs:: File ,
4
4
io:: Write ,
5
- path:: PathBuf ,
6
5
} ;
7
6
8
7
use anyhow:: { anyhow, bail, Context , Result } ;
9
8
use argp:: FromArgs ;
10
9
use object:: { Object , ObjectSymbol , SymbolScope } ;
10
+ use typed_path:: Utf8NativePathBuf ;
11
11
12
12
use crate :: {
13
- util:: file:: { buf_writer, process_rsp} ,
13
+ util:: {
14
+ file:: { buf_writer, process_rsp} ,
15
+ path:: native_path,
16
+ } ,
14
17
vfs:: open_file,
15
18
} ;
16
19
@@ -33,24 +36,24 @@ enum SubCommand {
33
36
/// Creates a static library.
34
37
#[ argp( subcommand, name = "create" ) ]
35
38
pub struct CreateArgs {
36
- #[ argp( positional) ]
39
+ #[ argp( positional, from_str_fn ( native_path ) ) ]
37
40
/// output file
38
- out : PathBuf ,
39
- #[ argp( positional) ]
41
+ out : Utf8NativePathBuf ,
42
+ #[ argp( positional, from_str_fn ( native_path ) ) ]
40
43
/// input files
41
- files : Vec < PathBuf > ,
44
+ files : Vec < Utf8NativePathBuf > ,
42
45
}
43
46
44
47
#[ derive( FromArgs , PartialEq , Eq , Debug ) ]
45
48
/// Extracts a static library.
46
49
#[ argp( subcommand, name = "extract" ) ]
47
50
pub struct ExtractArgs {
48
- #[ argp( positional) ]
51
+ #[ argp( positional, from_str_fn ( native_path ) ) ]
49
52
/// input files
50
- files : Vec < PathBuf > ,
51
- #[ argp( option, short = 'o' ) ]
53
+ files : Vec < Utf8NativePathBuf > ,
54
+ #[ argp( option, short = 'o' , from_str_fn ( native_path ) ) ]
52
55
/// output directory
53
- out : Option < PathBuf > ,
56
+ out : Option < Utf8NativePathBuf > ,
54
57
#[ argp( switch, short = 'q' ) ]
55
58
/// quiet output
56
59
quiet : bool ,
@@ -74,14 +77,13 @@ fn create(args: CreateArgs) -> Result<()> {
74
77
let mut identifiers = Vec :: with_capacity ( files. len ( ) ) ;
75
78
let mut symbol_table = BTreeMap :: new ( ) ;
76
79
for path in & files {
77
- let path_str =
78
- path. to_str ( ) . ok_or_else ( || anyhow ! ( "'{}' is not valid UTF-8" , path. display( ) ) ) ?;
79
- let identifier = path_str. as_bytes ( ) . to_vec ( ) ;
80
+ let unix_path = path. with_unix_encoding ( ) ;
81
+ let identifier = unix_path. as_str ( ) . as_bytes ( ) . to_vec ( ) ;
80
82
identifiers. push ( identifier. clone ( ) ) ;
81
83
82
84
let entries = match symbol_table. entry ( identifier) {
83
85
Entry :: Vacant ( e) => e. insert ( Vec :: new ( ) ) ,
84
- Entry :: Occupied ( _) => bail ! ( "Duplicate file name '{path_str }'" ) ,
86
+ Entry :: Occupied ( _) => bail ! ( "Duplicate file name '{unix_path }'" ) ,
85
87
} ;
86
88
let mut file = open_file ( path, false ) ?;
87
89
let obj = object:: File :: parse ( file. map ( ) ?) ?;
@@ -102,10 +104,8 @@ fn create(args: CreateArgs) -> Result<()> {
102
104
symbol_table,
103
105
) ?;
104
106
for path in files {
105
- let path_str =
106
- path. to_str ( ) . ok_or_else ( || anyhow ! ( "'{}' is not valid UTF-8" , path. display( ) ) ) ?;
107
107
let mut file = File :: open ( & path) ?;
108
- builder. append_file ( path_str . as_bytes ( ) , & mut file) ?;
108
+ builder. append_file ( path . as_str ( ) . as_bytes ( ) , & mut file) ?;
109
109
}
110
110
builder. into_inner ( ) ?. flush ( ) ?;
111
111
Ok ( ( ) )
@@ -118,22 +118,22 @@ fn extract(args: ExtractArgs) -> Result<()> {
118
118
// Extract files
119
119
let mut num_files = 0 ;
120
120
for path in & files {
121
- let mut out_dir = if let Some ( out) = & args. out { out. clone ( ) } else { PathBuf :: new ( ) } ;
121
+ let mut out_dir =
122
+ if let Some ( out) = & args. out { out. clone ( ) } else { Utf8NativePathBuf :: new ( ) } ;
122
123
// If there are multiple files, extract to separate directories
123
124
if files. len ( ) > 1 {
124
125
out_dir
125
126
. push ( path. with_extension ( "" ) . file_name ( ) . ok_or_else ( || anyhow ! ( "No file name" ) ) ?) ;
126
127
}
127
128
std:: fs:: create_dir_all ( & out_dir) ?;
128
129
if !args. quiet {
129
- println ! ( "Extracting {} to {}" , path. display ( ) , out_dir. display ( ) ) ;
130
+ println ! ( "Extracting {} to {}" , path, out_dir) ;
130
131
}
131
132
132
133
let mut file = open_file ( path, false ) ?;
133
134
let mut archive = ar:: Archive :: new ( file. map ( ) ?) ;
134
135
while let Some ( entry) = archive. next_entry ( ) {
135
- let mut entry =
136
- entry. with_context ( || format ! ( "Processing entry in {}" , path. display( ) ) ) ?;
136
+ let mut entry = entry. with_context ( || format ! ( "Processing entry in {}" , path) ) ?;
137
137
let file_name = std:: str:: from_utf8 ( entry. header ( ) . identifier ( ) ) ?;
138
138
if !args. quiet && args. verbose {
139
139
println ! ( "\t {}" , file_name) ;
@@ -146,7 +146,7 @@ fn extract(args: ExtractArgs) -> Result<()> {
146
146
std:: fs:: create_dir_all ( parent) ?;
147
147
}
148
148
let mut file = File :: create ( & file_path)
149
- . with_context ( || format ! ( "Failed to create file {}" , file_path. display ( ) ) ) ?;
149
+ . with_context ( || format ! ( "Failed to create file {}" , file_path) ) ?;
150
150
std:: io:: copy ( & mut entry, & mut file) ?;
151
151
file. flush ( ) ?;
152
152
0 commit comments