33//! installation / uninstallation process.
44
55use std:: borrow:: Cow ;
6+ use std:: convert:: Infallible ;
7+ use std:: fmt;
68use std:: io:: BufWriter ;
79use std:: path:: { Path , PathBuf } ;
10+ use std:: str:: FromStr ;
811
912use anyhow:: { bail, Result } ;
1013
@@ -103,28 +106,28 @@ pub(crate) struct ComponentBuilder<'a> {
103106impl < ' a > ComponentBuilder < ' a > {
104107 pub ( crate ) fn copy_file ( & mut self , path : PathBuf , src : & Path ) -> Result < ( ) > {
105108 self . parts . push ( ComponentPart {
106- kind : "file" . to_owned ( ) ,
109+ kind : ComponentPartKind :: File ,
107110 path : path. clone ( ) ,
108111 } ) ;
109112 self . tx . copy_file ( & self . name , path, src)
110113 }
111114 pub ( crate ) fn copy_dir ( & mut self , path : PathBuf , src : & Path ) -> Result < ( ) > {
112115 self . parts . push ( ComponentPart {
113- kind : "dir" . to_owned ( ) ,
116+ kind : ComponentPartKind :: Dir ,
114117 path : path. clone ( ) ,
115118 } ) ;
116119 self . tx . copy_dir ( & self . name , path, src)
117120 }
118121 pub ( crate ) fn move_file ( & mut self , path : PathBuf , src : & Path ) -> Result < ( ) > {
119122 self . parts . push ( ComponentPart {
120- kind : "file" . to_owned ( ) ,
123+ kind : ComponentPartKind :: File ,
121124 path : path. clone ( ) ,
122125 } ) ;
123126 self . tx . move_file ( & self . name , path, src)
124127 }
125128 pub ( crate ) fn move_dir ( & mut self , path : PathBuf , src : & Path ) -> Result < ( ) > {
126129 self . parts . push ( ComponentPart {
127- kind : "dir" . to_owned ( ) ,
130+ kind : ComponentPartKind :: Dir ,
128131 path : path. clone ( ) ,
129132 } ) ;
130133 self . tx . move_dir ( & self . name , path, src)
@@ -156,12 +159,40 @@ impl<'a> ComponentBuilder<'a> {
156159#[ derive( Debug ) ]
157160pub struct ComponentPart {
158161 /// Kind of the [`ComponentPart`], such as `"file"` or `"dir"`.
159- pub kind : String ,
162+ pub kind : ComponentPartKind ,
160163 /// Relative path of the [`ComponentPart`],
161164 /// with components separated by the system's main path separator.
162165 pub path : PathBuf ,
163166}
164167
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+
165196impl ComponentPart {
166197 const PATH_SEP_MANIFEST : & str = "/" ;
167198 const PATH_SEP_MAIN : & str = std:: path:: MAIN_SEPARATOR_STR ;
@@ -183,7 +214,8 @@ impl ComponentPart {
183214 path_str = Cow :: Owned ( path_str. replace ( Self :: PATH_SEP_MANIFEST , Self :: PATH_SEP_MAIN ) ) ;
184215 } ;
185216 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 ( ) ,
187219 path : PathBuf :: from ( path_str. as_ref ( ) ) ,
188220 } )
189221 }
@@ -337,9 +369,9 @@ impl Component {
337369 prefix : self . components . prefix . abs_path ( "" ) ,
338370 } ;
339371 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 ( ) ) ?,
343375 _ => return Err ( RustupError :: CorruptComponent ( self . name . clone ( ) ) . into ( ) ) ,
344376 }
345377 pset. seen ( part. path ) ;
@@ -362,7 +394,7 @@ mod tests {
362394 #[ test]
363395 fn decode_component_part ( ) {
364396 let part = ComponentPart :: decode ( "dir:share/doc/rust/html" ) . unwrap ( ) ;
365- assert_eq ! ( part. kind, "dir" ) ;
397+ assert_eq ! ( part. kind, ComponentPartKind :: Dir ) ;
366398 assert_eq ! (
367399 part. path,
368400 Path :: new( & "share/doc/rust/html" . replace( "/" , ComponentPart :: PATH_SEP_MAIN ) )
@@ -372,7 +404,7 @@ mod tests {
372404 #[ test]
373405 fn encode_component_part ( ) {
374406 let part = ComponentPart {
375- kind : "dir" . to_owned ( ) ,
407+ kind : ComponentPartKind :: Dir ,
376408 path : [ "share" , "doc" , "rust" , "html" ] . into_iter ( ) . collect ( ) ,
377409 } ;
378410 assert_eq ! ( part. encode( ) , "dir:share/doc/rust/html" ) ;
0 commit comments