diff options
-rw-r--r-- | src/core/common/Argument.cpp | 51 | ||||
-rw-r--r-- | src/core/common/Argument.hpp | 65 | ||||
-rw-r--r-- | test/core/common/ArgumentTest.cpp | 78 |
3 files changed, 113 insertions, 81 deletions
diff --git a/src/core/common/Argument.cpp b/src/core/common/Argument.cpp index 05c9761..385bae1 100644 --- a/src/core/common/Argument.cpp +++ b/src/core/common/Argument.cpp @@ -28,12 +28,12 @@ namespace ousia { /* Class Argument */ Argument::Argument(std::string name, const Rtti &type, const Rtti &innerType, - Variant defaultValue, bool hasDefault) - : type(type), - innerType(innerType), - name(std::move(name)), + Variant defaultValue, bool hasDefaultValue) + : name(std::move(name)), + type(&type), + innerType(&innerType), defaultValue(std::move(defaultValue)), - hasDefault(hasDefault) + hasDefaultValue(hasDefaultValue) { } @@ -181,9 +181,9 @@ Argument Argument::Cardinality(std::string name, bool Argument::validate(Variant &var, Logger &logger) const { - if (!VariantConverter::convert(var, type, innerType, logger, + if (!VariantConverter::convert(var, *type, *innerType, logger, VariantConverter::Mode::SAFE)) { - if (hasDefault) { + if (hasDefaultValue) { var = defaultValue; } return false; @@ -191,6 +191,12 @@ bool Argument::validate(Variant &var, Logger &logger) const return true; } +const std::string &Argument::getName() const { return name; } + +const Variant &Argument::getDefaultValue() const { return defaultValue; } + +bool Argument::hasDefault() const { return hasDefaultValue; } + /* Class Arguments */ // Instantiations of the "None" arguments @@ -203,14 +209,14 @@ static std::unordered_map<std::string, size_t> buildArgumentNames( std::unordered_map<std::string, size_t> res; size_t i = 0; for (const Argument &arg : arguments) { - if (!Utils::isIdentifier(arg.name)) { - throw OusiaException{std::string("Argument name ") + arg.name + + const std::string &name = arg.getName(); + if (!Utils::isIdentifier(name)) { + throw OusiaException{std::string("Argument name ") + name + std::string(" is not a valid identifier")}; } - if (!res.emplace(arg.name, i++).second) { - throw OusiaException{ - std::string("Argument names must be unique (") + arg.name + - std::string(")")}; + if (!res.emplace(name, i++).second) { + throw OusiaException{std::string("Argument name \"") + name + + std::string("\" is not unique")}; } } return res; @@ -252,15 +258,15 @@ bool Arguments::validateArray(Variant::arrayType &arr, Logger &logger) const if (a < n) { ok = ok && arguments[a].validate(arr[a], logger); } else { - if (arguments[a].hasDefault) { - arr[a] = arguments[a].defaultValue; + if (arguments[a].hasDefault()) { + arr[a] = arguments[a].getDefaultValue(); } else { // Call "validate" to inject a standard value arr[a] = Variant::fromObject(nullptr); arguments[a].validate(arr[a], nullLogger); logger.error(std::string("Missing argument ") + std::to_string(a + 1) + std::string(" \"") + - arguments[a].name + std::string("\"")); + arguments[a].getName() + std::string("\"")); ok = false; } } @@ -308,14 +314,15 @@ bool Arguments::validateMap(Variant::mapType &map, Logger &logger, // Insert all unset arguments for (size_t a = 0; a < N; a++) { if (!set[a]) { - if (arguments[a].hasDefault) { - map[arguments[a].name] = arguments[a].defaultValue; + const std::string &name = arguments[a].getName(); + if (arguments[a].hasDefault()) { + map[name] = arguments[a].getDefaultValue(); } else { // Call "validate" to inject a standard value - map[arguments[a].name] = Variant::fromObject(nullptr); - arguments[a].validate(map[arguments[a].name], nullLogger); - logger.error(std::string("Missing argument \"") + - arguments[a].name + std::string("\"")); + map[name] = Variant::fromObject(nullptr); + arguments[a].validate(map[name], nullLogger); + logger.error(std::string("Missing argument \"") + name + + std::string("\"")); ok = false; } } diff --git a/src/core/common/Argument.hpp b/src/core/common/Argument.hpp index 42b1722..ea68e3c 100644 --- a/src/core/common/Argument.hpp +++ b/src/core/common/Argument.hpp @@ -53,15 +53,33 @@ class Rtti; class Argument { private: /** + * Contains the name of the argument. Used for logging and in case the + * arguments are presented as map. + */ + std::string name; + + /** * Type that should be returned by the Variant rttiType function. */ - const Rtti &type; + Rtti const* type; /** * Describes the inner type of the variant -- e.g. the type of the elements * inside an array. Normally set to RttiTypes::None. */ - const Rtti &innerType; + Rtti const* innerType; + + /** + * Default value. Note that a value of nullptr does not indicate that no + * default value has been set. Use the "hasDefault" flag for this purpose. + * Nullptr is a valid value for objects. + */ + Variant defaultValue; + + /** + * True if a default value is set, false otherwise. + */ + bool hasDefaultValue; /** * Private constructor used for manually setting all internal data fields. @@ -101,24 +119,6 @@ private: public: /** - * Contains the name of the argument. Used for logging and in case the - * arguments are presented as map. - */ - const std::string name; - - /** - * Default value. Note that a value of nullptr does not indicate that no - * default value has been set. Use the "hasDefault" flag for this purpose. - * Nullptr is a valid value for objects. - */ - const Variant defaultValue; - - /** - * True if a default value is set, false otherwise. - */ - const bool hasDefault; - - /** * Named constructor for an argument with any type. * * @param name is the name of the argument as used for error messages and in @@ -404,6 +404,31 @@ public: * @return true if the given variant was valid, false otherwise. */ bool validate(Variant &var, Logger &logger) const; + + /** + * Returns the name of the argument. The name is used for logging and in + * case a map is presented as arguments. + * + * @return the name of the argument given in the constructor. + */ + const std::string &getName() const; + + /** + * Returns the default value. Note that a value of nullptr does not indicate + * that no default value has been set. Use the "hasDefault" flag for this + * purpose. Nullptr is a valid value for objects. + * + * @return the default value that was given in the constructor (may be + * nullptr) and nullptr if no default value was given. + */ + const Variant& getDefaultValue() const; + + /** + * Returns true if a default value was set in the constructor. + * + * @return true if a default value is set, false otherwise. + */ + bool hasDefault() const; }; /** diff --git a/test/core/common/ArgumentTest.cpp b/test/core/common/ArgumentTest.cpp index 8b74a19..43574c1 100644 --- a/test/core/common/ArgumentTest.cpp +++ b/test/core/common/ArgumentTest.cpp @@ -55,7 +55,7 @@ TEST(Argument, validateAny) { Argument a = Argument::Any("a"); - ASSERT_FALSE(a.hasDefault); + ASSERT_FALSE(a.hasDefault()); { Variant v{true}; @@ -83,8 +83,8 @@ TEST(Argument, validateAnyDefault) { Argument a = Argument::Any("a", true); - ASSERT_TRUE(a.hasDefault); - ASSERT_TRUE(a.defaultValue.asBool()); + ASSERT_TRUE(a.hasDefault()); + ASSERT_TRUE(a.getDefaultValue().asBool()); { Variant v{true}; @@ -112,7 +112,7 @@ TEST(Argument, validateBool) { Argument a = Argument::Bool("a"); - ASSERT_FALSE(a.hasDefault); + ASSERT_FALSE(a.hasDefault()); { Variant v{true}; @@ -140,8 +140,8 @@ TEST(Argument, validateBoolDefault) { Argument a = Argument::Bool("a", true); - ASSERT_TRUE(a.hasDefault); - ASSERT_TRUE(a.defaultValue.asBool()); + ASSERT_TRUE(a.hasDefault()); + ASSERT_TRUE(a.getDefaultValue().asBool()); { Variant v{true}; @@ -169,7 +169,7 @@ TEST(Argument, validateInt) { Argument a = Argument::Int("a"); - ASSERT_FALSE(a.hasDefault); + ASSERT_FALSE(a.hasDefault()); { Variant v{123}; @@ -190,8 +190,8 @@ TEST(Argument, validateIntDefault) { Argument a = Argument::Int("a", 42); - ASSERT_TRUE(a.hasDefault); - ASSERT_EQ(42, a.defaultValue.asInt()); + ASSERT_TRUE(a.hasDefault()); + ASSERT_EQ(42, a.getDefaultValue().asInt()); { Variant v{123}; @@ -212,7 +212,7 @@ TEST(Argument, validateDouble) { Argument a = Argument::Double("a"); - ASSERT_FALSE(a.hasDefault); + ASSERT_FALSE(a.hasDefault()); { Variant v{123}; @@ -240,8 +240,8 @@ TEST(Argument, validateDoubleDefault) { Argument a = Argument::Double("a", 42.0); - ASSERT_TRUE(a.hasDefault); - ASSERT_EQ(42.0, a.defaultValue.asDouble()); + ASSERT_TRUE(a.hasDefault()); + ASSERT_EQ(42.0, a.getDefaultValue().asDouble()); { Variant v{123}; @@ -269,7 +269,7 @@ TEST(Argument, validateString) { Argument a = Argument::String("a"); - ASSERT_FALSE(a.hasDefault); + ASSERT_FALSE(a.hasDefault()); { Variant v{"test"}; @@ -318,8 +318,8 @@ TEST(Argument, validateStringDefault) { Argument a = Argument::String("a", "test2"); - ASSERT_TRUE(a.hasDefault); - ASSERT_EQ("test2", a.defaultValue.asString()); + ASSERT_TRUE(a.hasDefault()); + ASSERT_EQ("test2", a.getDefaultValue().asString()); { Variant v{"test"}; @@ -369,7 +369,7 @@ TEST(Argument, validateObject) Manager mgr; Argument a = Argument::Object("a", RttiTypes::TestManaged1); - ASSERT_FALSE(a.hasDefault); + ASSERT_FALSE(a.hasDefault()); { Rooted<Managed> m{new Managed(mgr)}; @@ -421,9 +421,9 @@ TEST(Argument, validateObjectDefault) Manager mgr; Argument a = Argument::Object("a", RttiTypes::TestManaged1, nullptr); - ASSERT_TRUE(a.hasDefault); - ASSERT_TRUE(a.defaultValue.isObject()); - ASSERT_EQ(nullptr, a.defaultValue.asObject()); + ASSERT_TRUE(a.hasDefault()); + ASSERT_TRUE(a.getDefaultValue().isObject()); + ASSERT_EQ(nullptr, a.getDefaultValue().asObject()); { Rooted<Managed> m{new Managed(mgr)}; @@ -481,7 +481,7 @@ TEST(Argument, validateFunction) { Argument a = Argument::Function("a"); - ASSERT_FALSE(a.hasDefault); + ASSERT_FALSE(a.hasDefault()); { Variant v = Variant::fromFunction(helloWorldFun); @@ -504,9 +504,9 @@ TEST(Argument, validateFunctionDefault) { Argument a = Argument::Function("a", goodbyeWorldFun); - ASSERT_TRUE(a.hasDefault); - ASSERT_TRUE(a.defaultValue.isFunction()); - ASSERT_EQ(goodbyeWorldFun, a.defaultValue.asFunction()); + ASSERT_TRUE(a.hasDefault()); + ASSERT_TRUE(a.getDefaultValue().isFunction()); + ASSERT_EQ(goodbyeWorldFun, a.getDefaultValue().asFunction()); { Variant v = Variant::fromFunction(helloWorldFun); @@ -529,7 +529,7 @@ TEST(Argument, validateArray) { Argument a = Argument::Array("a"); - ASSERT_FALSE(a.hasDefault); + ASSERT_FALSE(a.hasDefault()); { Variant::arrayType arr{1, "a", nullptr}; @@ -554,9 +554,9 @@ TEST(Argument, validateArrayDefault) Variant::arrayType arrDefault{1, "a", nullptr}; Argument a = Argument::Array("a", arrDefault); - ASSERT_TRUE(a.hasDefault); - ASSERT_TRUE(a.defaultValue.isArray()); - ASSERT_EQ(arrDefault, a.defaultValue.asArray()); + ASSERT_TRUE(a.hasDefault()); + ASSERT_TRUE(a.getDefaultValue().isArray()); + ASSERT_EQ(arrDefault, a.getDefaultValue().asArray()); { Variant::arrayType arr{"test1", 42.5}; @@ -580,7 +580,7 @@ TEST(Argument, validateArrayInner) { Argument a = Argument::Array("a", RttiTypes::String); - ASSERT_FALSE(a.hasDefault); + ASSERT_FALSE(a.hasDefault()); { Variant::arrayType arr{1, "a", nullptr}; @@ -614,9 +614,9 @@ TEST(Argument, validateArrayInnerDefault) Variant::arrayType arrDefault{1, "a", nullptr}; Argument a = Argument::Array("a", RttiTypes::String, arrDefault); - ASSERT_TRUE(a.hasDefault); - ASSERT_TRUE(a.defaultValue.isArray()); - ASSERT_EQ(arrDefault, a.defaultValue.asArray()); + ASSERT_TRUE(a.hasDefault()); + ASSERT_TRUE(a.getDefaultValue().isArray()); + ASSERT_EQ(arrDefault, a.getDefaultValue().asArray()); { Variant::arrayType arr{"test1", 42.5}; @@ -649,7 +649,7 @@ TEST(Argument, validateMap) { Argument a = Argument::Map("a"); - ASSERT_FALSE(a.hasDefault); + ASSERT_FALSE(a.hasDefault()); { Variant::mapType map{{"key1", 1}, {"key2", "a"}, {"key3", nullptr}}; @@ -674,9 +674,9 @@ TEST(Argument, validateMapDefault) Variant::mapType mapDefault{{"key1", 1}, {"key2", "a"}, {"key3", nullptr}}; Argument a = Argument::Map("a", mapDefault); - ASSERT_TRUE(a.hasDefault); - ASSERT_TRUE(a.defaultValue.isMap()); - ASSERT_EQ(mapDefault, a.defaultValue.asMap()); + ASSERT_TRUE(a.hasDefault()); + ASSERT_TRUE(a.getDefaultValue().isMap()); + ASSERT_EQ(mapDefault, a.getDefaultValue().asMap()); { Variant::mapType map{{"a", true}, {"b", "a"}}; @@ -700,7 +700,7 @@ TEST(Argument, validateMapInnerType) { Argument a = Argument::Map("a", RttiTypes::String); - ASSERT_FALSE(a.hasDefault); + ASSERT_FALSE(a.hasDefault()); { Variant::mapType map{{"key1", 1}, {"key2", "a"}, {"key3", nullptr}}; @@ -739,9 +739,9 @@ TEST(Argument, validateMapInnerTypeDefault) Variant::mapType mapDefault{{"key1", "1"}}; Argument a = Argument::Map("a", RttiTypes::String, mapDefault); - ASSERT_TRUE(a.hasDefault); - ASSERT_TRUE(a.defaultValue.isMap()); - ASSERT_EQ(mapDefault, a.defaultValue.asMap()); + ASSERT_TRUE(a.hasDefault()); + ASSERT_TRUE(a.getDefaultValue().isMap()); + ASSERT_EQ(mapDefault, a.getDefaultValue().asMap()); { Variant::mapType map{{"key1", 1}, {"key2", "a"}, {"key3", nullptr}}; |