-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lazy configuration validator #124
Conversation
@@ -43,6 +45,228 @@ Config::Config() { | |||
|
|||
node_["double_quote_to_single_quote"] = false; | |||
node_["single_quote_to_double_quote"] = false; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You propagated the same lambda throughout this function. Why not a variable?
auto validate_integer = [](std::pair<std::string, std::any> elem) {
if (strcmp(elem.second.type().name(), "i") != 0) {
// Bug in the code
assert(0);
}
int value = std::any_cast<int>(elem.second);
if (value > 0) {
return value;
}
std::cerr << "Integer value of " << elem.first << " is out of range" << std::endl;
exit(1);
};
validator["column_limit"] = validate_integer;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not repeat code
src/Config.h
Outdated
@@ -30,4 +32,6 @@ class Config { | |||
void set(const char *key, T value) const { | |||
node_[key] = value; | |||
} | |||
typedef std::function<int(std::pair<std::string, std::any>)> Validator; | |||
std::map<std::string, Validator> validation; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::map<std::string, Validator> validation; | |
std::map<std::string, Validator> validators; |
src/Config.h
Outdated
@@ -30,4 +32,6 @@ class Config { | |||
void set(const char *key, T value) const { | |||
node_[key] = value; | |||
} | |||
typedef std::function<int(std::pair<std::string, std::any>)> Validator; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why a std::pair
instead of two arguments?
Seems overkill to me.
// Validators | ||
auto validate_integer = [](std::string key, std::any elem) { | ||
int value = std::any_cast<int>(elem); | ||
if (value > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would split this like you did because it might be desirable to have some configurations with 0s as well.
if (value > 0) { | |
if (value >= 0) { |
And then make validators["spaces_before_call"] = validate_integer;
as well
src/Config.h
Outdated
@@ -30,4 +33,6 @@ class Config { | |||
void set(const char *key, T value) const { | |||
node_[key] = value; | |||
} | |||
typedef std::function<std::any(std::string, std::any)> Validator; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this typedef to before the class declaration
test/test_validation.cpp
Outdated
string configFileName(file); \ | ||
Config config; \ | ||
if (fs::exists(configFileName)) { \ | ||
std::cout << configFileName << " exist" << endl; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::cout << configFileName << " exist" << endl; \ |
test/test_validation.cpp
Outdated
TEST_CASE("Config file " + string(file) + " have error", "format_file") { \ | ||
string configFileName(file); \ | ||
Config config; \ | ||
if (fs::exists(configFileName)) { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this check, I think we can drop it
src/Config.cpp
Outdated
if (value > 0) { | ||
return value; | ||
} | ||
std::cerr << "Integer value of " << key << " is out of range" << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::cerr << "Integer value of " << key << " is out of range" << std::endl; | |
std::cerr << "[ERROR] Processing " << key << " failed"; |
src/Config.cpp
Outdated
return value; | ||
} | ||
std::cerr << "Integer value of " << key << " is out of range" << std::endl; | ||
throw domain_error("Config value is out of Range"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw domain_error("Config value is out of Range"); | |
throw domain_error("[ERROR] Configuration value is out of range. Must be a positive integer."); |
src/Config.cpp
Outdated
node_[key] = any_cast<bool>(kv.second); | ||
} else if (strcmp(kv.second.type().name(), "c") == 0) { | ||
node_[key] = any_cast<char>(kv.second); | ||
if(datatype[key]== 'i'){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A switch
statement here makes the code more readable.
Also don't forget to useclang-format
test/test_validation.cpp
Outdated
namespace fs = filesystem; | ||
|
||
#define TEST_CONFIG_FILE(file) \ | ||
TEST_CASE("Config file " + string(file) + " have error", "format_file") { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TEST_CASE("Config file " + string(file) + " have error", "format_file") { \ | |
TEST_CASE("Configuration file " + string(file) + " has an error", "format_file") { \ |
Ok, time to do things right in the git history. |
src/Config.cpp
Outdated
return value; | ||
} | ||
std::cerr << "[ERROR] Processing " << key << " failed" << std::endl; | ||
throw domain_error("[ERROR] Configuration value is out of range. Must be a positive integer."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw domain_error("[ERROR] Configuration value is out of range. Must be a positive integer."); | |
throw domain_error("[ERROR] Configuration value is out of range. Must be a positive integer greater than 0."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@karanankit01 LGTM.
Please squash all commits using git rebase origin/master -i --autosquash
@Koihik please merge after squashing
configuration field value validation