Constraints

Constraints run after parsing, before handler invocation. Execution order: defaults first (may promote EmptyOption to DefaultOption), then option-level constraints, then command-level constraints.

Option-Level Constraints

Applied to a single option’s value. MustAssign and Default are applied automatically when the option is defined — the rest you apply explicitly.

ConstraintAppliedBehavior
MustAssignautomaticArgument is required. Added when no defaultArg is supplied.
DefaultautomaticFalls back to a value when the argument is omitted. Added when a defaultArg is supplied (bool always defaults to false).
AcceptedValuesAcceptedValues(…)Restricts the option argument to a set of allowed values.
CustomArgumentConstraintApplyConstraint(…)User-supplied predicate: Func<T, bool>
// AcceptedValues
cmdDef.AddOption<string>(
    key: "format", 
    defaultArg: "D", 
    help: "GUID format specifier.", 
    ("-f", "--format")
);
cmdDef["format"].AcceptedValues("N", "D", "B", "P", "X");
// CustomArgumentConstraint
cmdDef.AddOption<int>(
    key: "count", 
    defaultArg: 1,
     help: "Number of items.", 
     ("-c", "--count")
);
cmdDef["count"].ApplyConstraint<int>(
    cnt => cnt > 0 && cnt <= 100, 
    "Allowed Range", 
    "1..100."
);

cmdDef.AddOption<double>(key: "hours", help: "Hours logged.", ("-h", "--hours"));
cmdDef["hours"].ApplyConstraint<double>(
    h => h > 0 && 2 * h == (int)(2 * h),
    "Valid Increment",
    "Must be a positive multiple of 0.5."
);

cmdDef.AddOption<string>(key: "path", help: "Target path.", ("-p", "--path"));
cmdDef["path"].ApplyConstraint<string>(
    Path.IsPathFullyQualified,
    "Fully Qualified Path",
    "Must be a valid fully qualified path."
);

cmdDef.AddOption<string>(key: "comment", help: "Entry comment.", ("-c", "--comment"));
cmdDef["comment"].ApplyConstraint<string>(
    s => !string.IsNullOrWhiteSpace(s),
    "Not Whitespace",
    "Must contain a non-whitespace value."
);

Command-Level Constraints

Can access the full set of parsed options:

ConstraintBehavior
MustAssignOneOfAt least one option from a named set must be present
MutuallyExclusiveSetAt most one option from a named set may be present
CustomCommandConstraintReceives an ICommand allowing access to the full set of parsed options.
// MustAssignOneOf
cmdDef.AddOption<bool>(key: "json", help: "Output as JSON.", (null, "--json"));
cmdDef.AddOption<bool>(key: "xml", help: "Output as XML.", (null, "--xml"));
cmdDef.AddOption<bool>(key: "csv", help: "Output as CSV.", (null, "--csv"));
cmdDef.MustAssignOneOf("json", "xml", "csv");
// MutuallyExclusiveSet
cmdDef.AddOption<bool>(key: "json", help: "Output as JSON.", (null, "--json"));
cmdDef.AddOption<bool>(key: "xml", help: "Output as XML.", (null, "--xml"));
cmdDef.AddOption<bool>(key: "csv", help: "Output as CSV.", (null, "--csv"));
cmdDef.MutuallyExclusiveSet("json", "xml", "csv");
// Can be combined with MustAssignOneOf to enforce 1 and only 1.
cmdDef.MustAssignOneOf("json", "xml", "csv");
// CustomCommandConstraint
cmdDef.AddOption<int>(key: "age", help: "Applicant age.", ("-a", "--age"));
cmdDef.ApplyConstraint(
    cmd => cmd["age"].GetValue<int>() >= 18,
    "Age Restriction",
    "Must be 18 or older."
);