@@ -26,7 +26,10 @@ public static Result<IEnumerable<Token>, Error> Tokenize(
26
26
bool allowDashDash )
27
27
{
28
28
var errors = new List < Error > ( ) ;
29
- Action < Error > onError = errors . Add ;
29
+ Action < string > onBadFormatToken = arg => errors . Add ( new BadFormatTokenError ( arg ) ) ;
30
+ Action < string > unknownOptionError = name => errors . Add ( new UnknownOptionError ( name ) ) ;
31
+ Action < string > doNothing = name => { } ;
32
+ Action < string > onUnknownOption = ignoreUnknownArguments ? doNothing : unknownOptionError ;
30
33
31
34
int consumeNext = 0 ;
32
35
var tokens = new List < Token > ( ) ;
@@ -36,154 +39,116 @@ public static Result<IEnumerable<Token>, Error> Tokenize(
36
39
var enumerator = arguments . GetEnumerator ( ) ;
37
40
while ( enumerator . MoveNext ( ) )
38
41
{
39
- string arg = enumerator . Current ;
40
- // TODO: Turn this into a switch statement with pattern matching
41
- if ( arg == null )
42
- {
43
- continue ;
44
- }
42
+ switch ( enumerator . Current ) {
43
+ case null :
44
+ break ;
45
45
46
- if ( consumeNext > 0 )
47
- {
48
- addValue ( arg ) ;
49
- consumeNext = consumeNext - 1 ;
50
- continue ;
51
- }
46
+ case string arg when consumeNext > 0 :
47
+ addValue ( arg ) ;
48
+ consumeNext = consumeNext - 1 ;
49
+ break ;
52
50
53
- if ( arg == "--" )
54
- {
55
- if ( allowDashDash )
56
- {
51
+ case "--" when allowDashDash :
57
52
consumeNext = System . Int32 . MaxValue ;
58
- continue ;
59
- }
60
- else
61
- {
62
- addValue ( arg ) ;
63
- continue ;
64
- }
65
- }
53
+ break ;
66
54
67
- if ( arg . StartsWith ( "--" ) )
68
- {
69
- if ( arg . Contains ( "=" ) )
70
- {
55
+ case "--" :
56
+ addValue ( "--" ) ;
57
+ break ;
58
+
59
+ case "-" :
60
+ // A single hyphen is always a value (it usually means "read from stdin" or "write to stdout")
61
+ addValue ( "-" ) ;
62
+ break ;
63
+
64
+ case string arg when arg . StartsWith ( "--" ) && arg . Contains ( "=" ) :
71
65
string [ ] parts = arg . Substring ( 2 ) . Split ( new char [ ] { '=' } , 2 ) ;
72
66
if ( String . IsNullOrWhiteSpace ( parts [ 0 ] ) || parts [ 0 ] . Contains ( " " ) )
73
67
{
74
- onError ( new BadFormatTokenError ( arg ) ) ;
75
- continue ;
68
+ onBadFormatToken ( arg ) ;
76
69
}
77
70
else
78
71
{
79
- var name = parts [ 0 ] ;
80
- var tokenType = nameLookup ( name ) ;
81
- if ( tokenType == NameLookupResult . NoOptionFound )
72
+ switch ( nameLookup ( parts [ 0 ] ) )
82
73
{
83
- if ( ignoreUnknownArguments )
84
- {
85
- continue ;
86
- }
87
- else
88
- {
89
- onError ( new UnknownOptionError ( name ) ) ;
90
- continue ;
91
- }
74
+ case NameLookupResult . NoOptionFound :
75
+ onUnknownOption ( parts [ 0 ] ) ;
76
+ break ;
77
+
78
+ default :
79
+ addName ( parts [ 0 ] ) ;
80
+ addValue ( parts [ 1 ] ) ;
81
+ break ;
92
82
}
93
- addName ( parts [ 0 ] ) ;
94
- addValue ( parts [ 1 ] ) ;
95
- continue ;
96
83
}
97
- }
98
- else
99
- {
84
+ break ;
85
+
86
+ case string arg when arg . StartsWith ( "--" ) :
100
87
var name = arg . Substring ( 2 ) ;
101
- var tokenType = nameLookup ( name ) ;
102
- if ( tokenType == NameLookupResult . OtherOptionFound )
103
- {
104
- addName ( name ) ;
105
- consumeNext = 1 ;
106
- continue ;
107
- }
108
- else if ( tokenType == NameLookupResult . NoOptionFound )
88
+ switch ( nameLookup ( name ) )
109
89
{
110
- if ( ignoreUnknownArguments )
111
- {
90
+ case NameLookupResult . OtherOptionFound :
91
+ addName ( name ) ;
92
+ consumeNext = 1 ;
93
+ break ;
94
+
95
+ case NameLookupResult . NoOptionFound :
112
96
// When ignoreUnknownArguments is true and AutoHelp is true, calling code is responsible for
113
97
// setting up nameLookup so that it will return a known name for --help, so that we don't skip it here
114
- continue ;
115
- }
116
- else
117
- {
118
- onError ( new UnknownOptionError ( name ) ) ;
119
- continue ;
120
- }
98
+ onUnknownOption ( name ) ;
99
+ break ;
100
+
101
+ default :
102
+ addName ( name ) ;
103
+ break ;
121
104
}
122
- else
105
+ break ;
106
+
107
+ case string arg when arg . StartsWith ( "-" ) :
108
+ // First option char that requires a value means we swallow the rest of the string as the value
109
+ // But if there is no rest of the string, then instead we swallow the next argument
110
+ string chars = arg . Substring ( 1 ) ;
111
+ int len = chars . Length ;
112
+ if ( len > 0 && Char . IsDigit ( chars [ 0 ] ) )
123
113
{
124
- addName ( name ) ;
114
+ // Assume it's a negative number
115
+ addValue ( arg ) ;
125
116
continue ;
126
117
}
127
- }
128
- }
129
-
130
- if ( arg == "-" )
131
- {
132
- // A single hyphen is always a value (it usually means "read from stdin" or "write to stdout")
133
- addValue ( arg ) ;
134
- continue ;
135
- }
136
-
137
- if ( arg . StartsWith ( "-" ) )
138
- {
139
- // First option char that requires a value means we swallow the rest of the string as the value
140
- // But if there is no rest of the string, then instead we swallow the next argument
141
- string chars = arg . Substring ( 1 ) ;
142
- int len = chars . Length ;
143
- if ( len > 0 && Char . IsDigit ( chars [ 0 ] ) )
144
- {
145
- // Assume it's a negative number
146
- addValue ( arg ) ;
147
- continue ;
148
- }
149
- for ( int i = 0 ; i < len ; i ++ )
150
- {
151
- var s = new String ( chars [ i ] , 1 ) ;
152
- var tokenType = nameLookup ( s ) ;
153
- if ( tokenType == NameLookupResult . OtherOptionFound )
118
+ for ( int i = 0 ; i < len ; i ++ )
154
119
{
155
- addName ( s ) ;
156
- if ( i + 1 < len )
157
- {
158
- addValue ( chars . Substring ( i + 1 ) ) ;
159
- break ;
160
- }
161
- else
120
+ var s = new String ( chars [ i ] , 1 ) ;
121
+ switch ( nameLookup ( s ) )
162
122
{
163
- consumeNext = 1 ;
123
+ case NameLookupResult . OtherOptionFound :
124
+ addName ( s ) ;
125
+ if ( i + 1 < len )
126
+ {
127
+ addValue ( chars . Substring ( i + 1 ) ) ;
128
+ i = len ; // Can't use "break" inside a switch, so this breaks out of the loop
129
+ }
130
+ else
131
+ {
132
+ consumeNext = 1 ;
133
+ }
134
+ break ;
135
+
136
+ case NameLookupResult . NoOptionFound :
137
+ onUnknownOption ( s ) ;
138
+ break ;
139
+
140
+ default :
141
+ addName ( s ) ;
142
+ break ;
164
143
}
165
144
}
166
- else if ( tokenType == NameLookupResult . NoOptionFound )
167
- {
168
- if ( ignoreUnknownArguments )
169
- {
170
- continue ;
171
- }
172
- else
173
- {
174
- onError ( new UnknownOptionError ( s ) ) ;
175
- }
176
- }
177
- else
178
- {
179
- addName ( s ) ;
180
- }
181
- }
182
- continue ;
183
- }
145
+ break ;
184
146
185
- // If we get this far, it's a plain value
186
- addValue ( arg ) ;
147
+ case string arg :
148
+ // If we get this far, it's a plain value
149
+ addValue ( arg ) ;
150
+ break ;
151
+ }
187
152
}
188
153
189
154
return Result . Succeed < IEnumerable < Token > , Error > ( tokens . AsEnumerable ( ) , errors . AsEnumerable ( ) ) ;
0 commit comments