-
Notifications
You must be signed in to change notification settings - Fork 0
Configuring Options
Program options are configured with three types of object — options, parameters and constraints.
Each option is represented by an instance of generic class Option<T>
. To create an instance of Option<T>
, use factory methods provided by OptionFactory
.
There are two basic types of options: with and without an option parameter.
To create an option without a parameter, you simply call OptionFactory.Create()
with two arguments — the first one specifies whether the option is required (true
) or optional (false
), the second one contains option description for usage text. Example:
var verbose = OptionFactory.Create(false, "Be more verbose");
In order to create an option with a parameter, you need to create instance of class Parameter<T>
. For example
var lineWidthParam = new IntParameter(true, "WIDTH", 80);
For more information see Parameters.
Option object with a parameter is created the same way as in case of an option without a parameter, but you pass Parameter<T>
object as the third argument of OptionFactory.Create()
. This method is generic, but thanks to type inference in C# you don't need to specify the type explicitly. Thus the following two lines of code are equivalent:
var lineWidth = OptionFactory.Create(false, "Wrap lines at WIDTH", lineWidthParam);
Option<int> lineWidth = OptionFactory.Create<int>(false, "Wrap lines at WIDTH", lineWidthParam);
After you've created option object, register it to EasyOpt instance and assign it names with AddOption()
. You can specify multiple names.
Names one character long are classified as short option names, longer names are classified as long option names. This means that it is not possible to create a long option with one character long name (e.g. --v
).
There are several overloaded versions of AddOption()
:
public void AddOption<T>(Option<T> option, params String[] names)
public void AddOption<T>(Option<T> option, char shortName)
public void AddOption<T>(Option<T> option, char shortName, String longName)
Overloaded versions accepting char are there just for convenience, the char is converted to string. The following three lines are equivalent:
parser.AddOption(verbose, 'v', "verbose");
parser.AddOption(verbose, "v", "verbose");
parser.AddOption(verbose, new string[] { "v", "verbose" } );
Option names must not be null, at least one option name must be listed and one name cannot be used more than once. Option names can contain any characters except for '=', '-' and whitespace characters. If option name is invalid, an exception of type InvalidNameException
or DuplicateOptionNameException
is thrown.
Option names are case-sensitive.
Option parameters are represented by Parameter<T>
instances. This is an abstract class and in practice you use derived concrete types. The main purpose of classes derived from Parameter<T>
is to provide method for conversion from parameter value as string to the concrete type T
. The converted typed value can be accessed with Parameter<T>.Value
property.
EasyOpt provides derived classes for several concrete types:
-
StringParameter
performs no conversion and returns the string as is. -
IntParameter
converts parameter to integer value. -
FloatParameter
converts parameter to float value. *EnumParameter<T>
is generic class that converts parameter value to enum typeT
. If a parameter value matches one of the corresponding enum constants, it is converted to that enum constant. Otherwise an exception is thrown. The behaviour of conversion is different fromEnum.Parse()
because only single named constants are accepted; integer values or lists of named constants are not converted. Case-sensitivity of conversion can be set withEnumParameter<T>.IgnoreCase
. IfT
is not an enum type,EnumParameterException
is thrown.
All these classes accept three arguments in their constructors — whether the option is required (true
) or optional (false
), name displayed in the usage text and the third, optional, argument sets a default value.
When conversion fails ParameterConversionException is thrown, which is in turn wrapped by parser in OptionParameterException
.
Example of usage:
var lineWidthParam = new IntParameter(true, "WIDTH", 80);
enum Color { Never, Always, Auto }
var colorParam = new EnumParameter<Color>(false, "WHEN", Color.Auto);
You can easily define your own parameter types by extending class Parameter<T>
and implementing its abstract method T convert(String parameter)
. It is recommended that in case the conversion fails ParameterConversionException
is thrown. For an example how a custom parameter can be implemented, see ls example.
Constraints are used to restrict range of parameter values. For example you can define that an option parameter must be a number greater than zero or that a parameter value must be in a certain list of accepted values.
Constraints are classes implementing IConstraint<T>
interface and its method bool IsValid(T parameter)
. As you can see, constraints are applied to parameters after conversion from string to the corresponding parameter type (T).
EasyOpt has several predefined constraints:
Constraint | Type | Description |
---|---|---|
LowerBoundConstraint |
int |
Parameter value must be grater or equal to the number passed as the only argument of the constructor. |
UpperBoundConstraint |
int |
Parameter value must be less or equal to the number passed as the only argument of the constructor. |
StringEnumerationConstraint |
string |
Parameter value must be in the specified list of values. This constraint has two overloaded constructors: StringEnumerationConstraint(IEnumerable<String> acceptedValues, IEqualityComparer<String> comparer) StringEnumerationConstraint(IEnumerable<String> acceptedValues, bool ignoreCase) — comparer and ignoreCase parameters can be used to specify the way parameter is compared to members of acceptedValues . |
ExistingFileConstraint |
string |
Parameter must be a valid path (relative of absolute) to an existing file. |
To apply a constraint to an option parameter, create its instance and register it to the parameter object. You can define multiple constraints for a single parameter.
lineWidthParam.AddConstraint( new LowerBoundConstraint(1) );
lineWidthParam.AddConstraint( new UpperBoundConstraint(100) );
Constraints do not apply to the default parameter value.
For an example how a custom constraint can be implemented, see touch example.