Added daisychain methods to easily create more complex parameter constraints

This commit is contained in:
Leonetienne 2021-09-05 12:56:34 +02:00
parent 93746d40cf
commit b45e305122
4 changed files with 159 additions and 10 deletions

View File

@ -22,6 +22,17 @@ namespace Hazelnp
return pc;
}
//! Daisychain-method. Will add a the "required-argument" aspect.
//! Think of the default value like of a list ofparameters. Like {"--width", "800"}
ParamConstraint AddRequire(const std::initializer_list<std::string>& defaultValue = {}, bool required = true)
{
ParamConstraint pc = *this;
pc.defaultValue = defaultValue;
pc.required = required;
return pc;
}
//! Constructs a type-safety constraint
static ParamConstraint TypeSafety(DATA_TYPE requiredType, bool constrainType = true)
{
@ -32,6 +43,17 @@ namespace Hazelnp
return pc;
}
//! Daisychain-method. Will add a the "type-safety" aspect.
//! Constructs a type-safety constraint
ParamConstraint AddTypeSafety(DATA_TYPE requiredType, bool constrainType = true)
{
ParamConstraint pc = *this;
pc.constrainType = constrainType;
pc.requiredType = requiredType;
return pc;
}
//! Constructs an incompatibility constraint.
//! This means, that the following parameters are NOT compatible with this one and will throw an error if passed together
static ParamConstraint Incompatibility(const std::initializer_list<std::string>& incompatibleParameters)
@ -53,6 +75,17 @@ namespace Hazelnp
return pc;
}
//! Daisychain-method. Will add a the "incompatiblity" aspect.
//! This means, that the following parameters are NOT compatible with this one and will throw an error if passed together.
//! Syntactical-sugar proxy method that will convert the lonely string to an initializer list for you :3
ParamConstraint AddIncompatibility(const std::string& incompatibleParameters)
{
ParamConstraint pc = *this;
pc.incompatibleParameters = { incompatibleParameters };
return pc;
}
//! Whole constructor
ParamConstraint(bool constrainType, DATA_TYPE requiredType, const std::initializer_list<std::string>& defaultValue, bool required, const std::initializer_list<std::string>& incompatibleParameters)
:

View File

@ -1,2 +1,2 @@
#pragma once
#define HAZELNUPP_VERSION (1.11)
#define HAZELNUPP_VERSION (1.12)

View File

@ -676,5 +676,121 @@ namespace TestHazelnupp
return;
}
// Tests that daisychained construction of constraints works. Tests for the require constraint to work
TEST_METHOD(Daisychained_Construction_Test_Require)
{
// Setup
ArgList args({
"/my/fake/path/wahoo.out",
});
Assert::ExpectException<HazelnuppConstraintMissingValue>(
[args]
{
CmdArgsInterface cmdArgsI;
cmdArgsI.SetCrashOnFail(false);
cmdArgsI.RegisterConstraint(
"--width",
ParamConstraint::Require()
.AddTypeSafety(DATA_TYPE::FLOAT)
.AddIncompatibility({ "--antiwidth" })
);
cmdArgsI.Parse(C_Ify(args));
}
);
return;
}
// Tests that daisychained construction of constraints works. Tests for the type safety constraint to work
TEST_METHOD(Daisychained_Construction_Test_TypeSafety)
{
// Setup
ArgList args({
"/my/fake/path/wahoo.out",
"--width",
"alejandro"
});
Assert::ExpectException<HazelnuppConstraintTypeMissmatch>(
[args]
{
CmdArgsInterface cmdArgsI;
cmdArgsI.SetCrashOnFail(false);
cmdArgsI.RegisterConstraint(
"--width",
ParamConstraint::TypeSafety(DATA_TYPE::FLOAT)
.AddRequire()
.AddIncompatibility({ "--antiwidth" })
);
cmdArgsI.Parse(C_Ify(args));
}
);
return;
}
// Tests that daisychained construction of constraints works. Tests for the incompatibility constraint to work
TEST_METHOD(Daisychained_Construction_Test_Incompatibility)
{
// Setup
ArgList args({
"/my/fake/path/wahoo.out",
"--width",
"8930",
"--antiwidth"
});
Assert::ExpectException<HazelnuppConstraintIncompatibleParameters>(
[args]
{
CmdArgsInterface cmdArgsI;
cmdArgsI.SetCrashOnFail(false);
cmdArgsI.RegisterConstraint(
"--width",
ParamConstraint::Incompatibility({ "--antiwidth" })
.AddTypeSafety(DATA_TYPE::FLOAT)
.AddRequire()
);
cmdArgsI.Parse(C_Ify(args));
}
);
return;
}
// Tests that daisychained construction of constraints works. Tests for the command to pass, because all constraints should be respected
TEST_METHOD(Daisychained_Construction_Test_AllOkay)
{
// Setup
ArgList args({
"/my/fake/path/wahoo.out",
"--width",
"8930"
});
{
CmdArgsInterface cmdArgsI;
cmdArgsI.SetCrashOnFail(false);
cmdArgsI.RegisterConstraint(
"--width",
ParamConstraint::Require()
.AddTypeSafety(DATA_TYPE::FLOAT)
.AddIncompatibility({ "--antiwidth" })
);
cmdArgsI.Parse(C_Ify(args));
}
return;
}
};
}

View File

@ -275,17 +275,17 @@ int main(int argc, char** argv)
```
---
Note that you can also combine these two constraint-types by populating the struct yourself:
Keep in mind that you can only register ONE constraint for each parameter!
Adding another one will just overwrite the prior one.
However, one constraint can do all three "types" at once if you daisychain them:
```cpp
ParamConstraint pc;
pc.constrainType = true;
pc.requiredType = DATA_TYPE::STRING;
pc.defaultValue = {}; // no default value
pc.required = true;
args.RegisterConstraint("--my-key", pc);
args.RegisterConstraint(
"--width",
ParamConstraint::Require() // Make this parameter mandatory
.AddTypeSafety(DATA_TYPE::FLOAT) // Force this param to be a float
.AddIncompatibility({ "--antiwidth" }) // Make this param incompatible with '--antiwidth'
);
```
What doesn't work is inserting multiple constraints for one key. It will just discard the older one. But that's okay because one can describe all possible constraints for a single key in **one** struct.
<span id="automatic-parameter-documentation"></span>
## Automatic parameter documentation