3
3
//! installation / uninstallation process.
4
4
5
5
use std:: borrow:: Cow ;
6
+ use std:: convert:: Infallible ;
7
+ use std:: fmt;
6
8
use std:: io:: BufWriter ;
7
9
use std:: path:: { Path , PathBuf } ;
10
+ use std:: str:: FromStr ;
8
11
9
12
use anyhow:: { bail, Result } ;
10
13
@@ -103,28 +106,28 @@ pub(crate) struct ComponentBuilder<'a> {
103
106
impl < ' a > ComponentBuilder < ' a > {
104
107
pub ( crate ) fn copy_file ( & mut self , path : PathBuf , src : & Path ) -> Result < ( ) > {
105
108
self . parts . push ( ComponentPart {
106
- kind : "file" . to_owned ( ) ,
109
+ kind : ComponentPartKind :: File ,
107
110
path : path. clone ( ) ,
108
111
} ) ;
109
112
self . tx . copy_file ( & self . name , path, src)
110
113
}
111
114
pub ( crate ) fn copy_dir ( & mut self , path : PathBuf , src : & Path ) -> Result < ( ) > {
112
115
self . parts . push ( ComponentPart {
113
- kind : "dir" . to_owned ( ) ,
116
+ kind : ComponentPartKind :: Dir ,
114
117
path : path. clone ( ) ,
115
118
} ) ;
116
119
self . tx . copy_dir ( & self . name , path, src)
117
120
}
118
121
pub ( crate ) fn move_file ( & mut self , path : PathBuf , src : & Path ) -> Result < ( ) > {
119
122
self . parts . push ( ComponentPart {
120
- kind : "file" . to_owned ( ) ,
123
+ kind : ComponentPartKind :: File ,
121
124
path : path. clone ( ) ,
122
125
} ) ;
123
126
self . tx . move_file ( & self . name , path, src)
124
127
}
125
128
pub ( crate ) fn move_dir ( & mut self , path : PathBuf , src : & Path ) -> Result < ( ) > {
126
129
self . parts . push ( ComponentPart {
127
- kind : "dir" . to_owned ( ) ,
130
+ kind : ComponentPartKind :: Dir ,
128
131
path : path. clone ( ) ,
129
132
} ) ;
130
133
self . tx . move_dir ( & self . name , path, src)
@@ -156,12 +159,40 @@ impl<'a> ComponentBuilder<'a> {
156
159
#[ derive( Debug ) ]
157
160
pub struct ComponentPart {
158
161
/// Kind of the [`ComponentPart`], such as `"file"` or `"dir"`.
159
- pub kind : String ,
162
+ pub kind : ComponentPartKind ,
160
163
/// Relative path of the [`ComponentPart`],
161
164
/// with components separated by the system's main path separator.
162
165
pub path : PathBuf ,
163
166
}
164
167
168
+ #[ derive( Debug , PartialEq ) ]
169
+ pub enum ComponentPartKind {
170
+ File ,
171
+ Dir ,
172
+ Unknown ( String ) ,
173
+ }
174
+
175
+ impl fmt:: Display for ComponentPartKind {
176
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
177
+ match self {
178
+ Self :: File => write ! ( f, "file" ) ,
179
+ Self :: Dir => write ! ( f, "dir" ) ,
180
+ Self :: Unknown ( s) => write ! ( f, "{s}" ) ,
181
+ }
182
+ }
183
+ }
184
+
185
+ impl FromStr for ComponentPartKind {
186
+ type Err = Infallible ;
187
+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
188
+ match s {
189
+ "file" => Ok ( Self :: File ) ,
190
+ "dir" => Ok ( Self :: Dir ) ,
191
+ s => Ok ( Self :: Unknown ( s. to_owned ( ) ) ) ,
192
+ }
193
+ }
194
+ }
195
+
165
196
impl ComponentPart {
166
197
const PATH_SEP_MANIFEST : & str = "/" ;
167
198
const PATH_SEP_MAIN : & str = std:: path:: MAIN_SEPARATOR_STR ;
@@ -183,7 +214,8 @@ impl ComponentPart {
183
214
path_str = Cow :: Owned ( path_str. replace ( Self :: PATH_SEP_MANIFEST , Self :: PATH_SEP_MAIN ) ) ;
184
215
} ;
185
216
Some ( Self {
186
- kind : line[ 0 ..pos] . to_owned ( ) ,
217
+ // FIXME: Use `.into_ok()` when it's available.
218
+ kind : line[ 0 ..pos] . parse ( ) . unwrap ( ) ,
187
219
path : PathBuf :: from ( path_str. as_ref ( ) ) ,
188
220
} )
189
221
}
@@ -337,9 +369,9 @@ impl Component {
337
369
prefix : self . components . prefix . abs_path ( "" ) ,
338
370
} ;
339
371
for part in self . parts ( ) ?. into_iter ( ) . rev ( ) {
340
- match & * part. kind {
341
- "file" => tx. remove_file ( & self . name , part. path . clone ( ) ) ?,
342
- "dir" => tx. remove_dir ( & self . name , part. path . clone ( ) ) ?,
372
+ match part. kind {
373
+ ComponentPartKind :: File => tx. remove_file ( & self . name , part. path . clone ( ) ) ?,
374
+ ComponentPartKind :: Dir => tx. remove_dir ( & self . name , part. path . clone ( ) ) ?,
343
375
_ => return Err ( RustupError :: CorruptComponent ( self . name . clone ( ) ) . into ( ) ) ,
344
376
}
345
377
pset. seen ( part. path ) ;
@@ -362,7 +394,7 @@ mod tests {
362
394
#[ test]
363
395
fn decode_component_part ( ) {
364
396
let part = ComponentPart :: decode ( "dir:share/doc/rust/html" ) . unwrap ( ) ;
365
- assert_eq ! ( part. kind, "dir" ) ;
397
+ assert_eq ! ( part. kind, ComponentPartKind :: Dir ) ;
366
398
assert_eq ! (
367
399
part. path,
368
400
Path :: new( & "share/doc/rust/html" . replace( "/" , ComponentPart :: PATH_SEP_MAIN ) )
@@ -372,7 +404,7 @@ mod tests {
372
404
#[ test]
373
405
fn encode_component_part ( ) {
374
406
let part = ComponentPart {
375
- kind : "dir" . to_owned ( ) ,
407
+ kind : ComponentPartKind :: Dir ,
376
408
path : [ "share" , "doc" , "rust" , "html" ] . into_iter ( ) . collect ( ) ,
377
409
} ;
378
410
assert_eq ! ( part. encode( ) , "dir:share/doc/rust/html" ) ;
0 commit comments