1
1
use crate :: { t, VERSION } ;
2
+ use std:: fmt:: Write as _;
2
3
use std:: path:: { Path , PathBuf } ;
3
4
use std:: str:: FromStr ;
4
5
use std:: {
@@ -20,7 +21,28 @@ impl Profile {
20
21
}
21
22
22
23
pub fn all ( ) -> impl Iterator < Item = Self > {
23
- [ Profile :: Compiler , Profile :: Codegen , Profile :: Library , Profile :: User ] . iter ( ) . copied ( )
24
+ use Profile :: * ;
25
+ // N.B. these are ordered by how they are displayed, not alphabetically
26
+ [ Library , Compiler , Codegen , User ] . iter ( ) . copied ( )
27
+ }
28
+
29
+ pub fn purpose ( & self ) -> String {
30
+ use Profile :: * ;
31
+ match self {
32
+ Library => "Contribute to the standard library" ,
33
+ Compiler => "Contribute to the compiler or rustdoc" ,
34
+ Codegen => "Contribute to the compiler, and also modify LLVM or codegen" ,
35
+ User => "Install Rust from source" ,
36
+ }
37
+ . to_string ( )
38
+ }
39
+
40
+ pub fn all_for_help ( indent : & str ) -> String {
41
+ let mut out = String :: new ( ) ;
42
+ for choice in Profile :: all ( ) {
43
+ writeln ! ( & mut out, "{}{}: {}" , indent, choice, choice. purpose( ) ) . unwrap ( ) ;
44
+ }
45
+ out
24
46
}
25
47
}
26
48
@@ -29,10 +51,10 @@ impl FromStr for Profile {
29
51
30
52
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
31
53
match s {
32
- "a" | " lib" | "library" => Ok ( Profile :: Library ) ,
33
- "b" | " compiler" | "rustdoc" => Ok ( Profile :: Compiler ) ,
34
- "c" | " llvm" | "codegen" => Ok ( Profile :: Codegen ) ,
35
- "d" | " maintainer" | "user" => Ok ( Profile :: User ) ,
54
+ "lib" | "library" => Ok ( Profile :: Library ) ,
55
+ "compiler" | "rustdoc" => Ok ( Profile :: Compiler ) ,
56
+ "llvm" | "codegen" => Ok ( Profile :: Codegen ) ,
57
+ "maintainer" | "user" => Ok ( Profile :: User ) ,
36
58
_ => Err ( format ! ( "unknown profile: '{}'" , s) ) ,
37
59
}
38
60
}
@@ -104,19 +126,37 @@ pub fn setup(src_path: &Path, profile: Profile) {
104
126
105
127
// Used to get the path for `Subcommand::Setup`
106
128
pub fn interactive_path ( ) -> io:: Result < Profile > {
107
- let mut input = String :: new ( ) ;
108
- println ! (
109
- "Welcome to the Rust project! What do you want to do with x.py?
110
- a) Contribute to the standard library
111
- b) Contribute to the compiler or rustdoc
112
- c) Contribute to the compiler, and also modify LLVM or codegen
113
- d) Install Rust from source"
114
- ) ;
129
+ fn abbrev_all ( ) -> impl Iterator < Item = ( String , Profile ) > {
130
+ ( 'a' ..) . map ( |c| c. to_string ( ) ) . zip ( Profile :: all ( ) )
131
+ }
132
+
133
+ fn parse_with_abbrev ( input : & str ) -> Result < Profile , String > {
134
+ let input = input. trim ( ) . to_lowercase ( ) ;
135
+ for ( letter, profile) in abbrev_all ( ) {
136
+ if input == letter {
137
+ return Ok ( profile) ;
138
+ }
139
+ }
140
+ input. parse ( )
141
+ }
142
+
143
+ println ! ( "Welcome to the Rust project! What do you want to do with x.py?" ) ;
144
+ for ( letter, profile) in abbrev_all ( ) {
145
+ println ! ( "{}) {}: {}" , letter, profile, profile. purpose( ) ) ;
146
+ }
115
147
let template = loop {
116
- print ! ( "Please choose one (a/b/c/d): " ) ;
148
+ print ! (
149
+ "Please choose one ({}): " ,
150
+ abbrev_all( ) . map( |( l, _) | l) . collect:: <Vec <_>>( ) . join( "/" )
151
+ ) ;
117
152
io:: stdout ( ) . flush ( ) ?;
153
+ let mut input = String :: new ( ) ;
118
154
io:: stdin ( ) . read_line ( & mut input) ?;
119
- break match input. trim ( ) . to_lowercase ( ) . parse ( ) {
155
+ if input == "" {
156
+ eprintln ! ( "EOF on stdin, when expecting answer to question. Giving up." ) ;
157
+ std:: process:: exit ( 1 ) ;
158
+ }
159
+ break match parse_with_abbrev ( & input) {
120
160
Ok ( profile) => profile,
121
161
Err ( err) => {
122
162
println ! ( "error: {}" , err) ;
0 commit comments