29
29
using Fclp . Internals ;
30
30
using Fclp . Internals . Errors ;
31
31
using Fclp . Internals . Extensions ;
32
+ using Fclp . Internals . Validators ;
32
33
33
34
namespace Fclp
34
35
{
@@ -44,6 +45,7 @@ public class FluentCommandLineParser : IFluentCommandLineParser
44
45
ICommandLineOptionFormatter _optionFormatter ;
45
46
IHelpCommandLineOption _helpOption ;
46
47
ICommandLineParserErrorFormatter _errorFormatter ;
48
+ ICommandLineOptionValidator _optionValidator ;
47
49
48
50
///// <summary>
49
51
///// Gets or sets whether the parser is case-sensitive. E.g. If <c>true</c> then <c>/a</c> will be treated as identical to <c>/A</c>.
@@ -95,6 +97,15 @@ public ICommandLineOptionFactory OptionFactory
95
97
set { _optionFactory = value ; }
96
98
}
97
99
100
+ /// <summary>
101
+ /// Gets or sets the <see cref="ICommandLineOptionValidator"/> used to validate each setup Option.
102
+ /// </summary>
103
+ public ICommandLineOptionValidator OptionValidator
104
+ {
105
+ get { return _optionValidator ?? ( _optionValidator = new CommandLineOptionValidator ( this ) ) ; }
106
+ set { _optionValidator = value ; }
107
+ }
108
+
98
109
/// <summary>
99
110
/// Gets or sets the <see cref="ICommandLineParserEngine"/> to use for parsing the command line args.
100
111
/// </summary>
@@ -122,58 +133,23 @@ internal IHelpCommandLineOption HelpOption
122
133
/// </exception>
123
134
public ICommandLineOptionFluent < T > Setup < T > ( char shortOption , string longOption )
124
135
{
125
- EnsureIsValidShortName ( shortOption ) ;
126
- EnsureIsValidLongName ( longOption ) ;
127
- //EnsureHasShortNameOrLongName(shortOption, longOption);
128
-
129
136
return SetupInternal < T > ( shortOption . ToString ( CultureInfo . InvariantCulture ) , longOption ) ;
130
137
}
131
138
132
139
private ICommandLineOptionFluent < T > SetupInternal < T > ( string shortOption , string longOption )
133
140
{
134
- foreach ( var option in this . Options )
135
- {
136
- if ( shortOption != null && shortOption . Equals ( option . ShortName , this . StringComparison ) )
137
- throw new OptionAlreadyExistsException ( shortOption ) ;
138
-
139
- if ( longOption != null && longOption . Equals ( option . LongName , this . StringComparison ) )
140
- throw new OptionAlreadyExistsException ( longOption ) ;
141
- }
142
-
143
141
var argOption = this . OptionFactory . CreateOption < T > ( shortOption , longOption ) ;
144
142
145
143
if ( argOption == null )
146
144
throw new InvalidOperationException ( "OptionFactory is producing unexpected results." ) ;
147
145
146
+ OptionValidator . Validate ( argOption ) ;
147
+
148
148
this . Options . Add ( argOption ) ;
149
149
150
150
return argOption ;
151
151
}
152
152
153
- private static void EnsureIsValidShortName ( char value )
154
- {
155
- if ( char . IsWhiteSpace ( value ) || char . IsControl ( value ) || value == ':' || value == '=' )
156
- throw new ArgumentOutOfRangeException ( "value" ) ;
157
- }
158
-
159
- private static void EnsureIsValidLongName ( string value )
160
- {
161
- if ( string . IsNullOrEmpty ( value ) ) return ;
162
-
163
- if ( value . Trim ( ) . Length < 2 )
164
- throw new ArgumentOutOfRangeException ( "value" ) ;
165
-
166
- var invalidChars = SpecialCharacters . ValueAssignments . Union ( new [ ] { SpecialCharacters . Whitespace } ) ;
167
- if ( invalidChars . Any ( value . Contains ) )
168
- throw new ArgumentOutOfRangeException ( "value" ) ;
169
- }
170
-
171
- private static void EnsureHasShortNameOrLongName ( char shortOption , string longOption )
172
- {
173
- if ( char . IsWhiteSpace ( shortOption ) && longOption . IsNullOrWhiteSpace ( ) )
174
- throw new ArgumentOutOfRangeException ( "shortOption" , "Either shortOption or longOption must be specified" ) ;
175
- }
176
-
177
153
/// <summary>
178
154
/// Setup a new <see cref="ICommandLineOptionFluent{T}"/> using the specified short Option name.
179
155
/// </summary>
@@ -184,7 +160,6 @@ private static void EnsureHasShortNameOrLongName(char shortOption, string longOp
184
160
/// </exception>
185
161
public ICommandLineOptionFluent < T > Setup < T > ( char shortOption )
186
162
{
187
- EnsureIsValidShortName ( shortOption ) ;
188
163
return SetupInternal < T > ( shortOption . ToString ( CultureInfo . InvariantCulture ) , null ) ;
189
164
}
190
165
@@ -198,7 +173,6 @@ public ICommandLineOptionFluent<T> Setup<T>(char shortOption)
198
173
/// </exception>
199
174
public ICommandLineOptionFluent < T > Setup < T > ( string longOption )
200
175
{
201
- EnsureIsValidLongName ( longOption ) ;
202
176
return SetupInternal < T > ( null , longOption ) ;
203
177
}
204
178
@@ -242,10 +216,10 @@ public ICommandLineParserResult Parse(string[] args)
242
216
{
243
217
option . Bind ( match ) ;
244
218
}
245
- catch ( OptionSyntaxException )
219
+ catch ( OptionSyntaxException )
246
220
{
247
221
result . Errors . Add ( new OptionSyntaxParseError ( option , match ) ) ;
248
- if ( option . HasDefault )
222
+ if ( option . HasDefault )
249
223
option . BindDefault ( ) ;
250
224
}
251
225
0 commit comments