yaml-cpp
yaml-cpp copied to clipboard
Add an `into()` operator on `Node` to do optional assignment.
It would be useful to have an into() operator on the Node class modeled off the get_to() operator in the popular nlohmann::json library. (See: https://github.com/nlohmann/json#basic-usage)
This operator assigns a casted value to an existing variable if that node has a defined value, and otherwise leaves the variable unchanged. It returns true if the variable was overwritten and false if the variable was unchanged.
This operator is extremely useful in applications where YAML is being used as a configuration source that overrides default values coming from another source, e.g.:
struct MyConfig {
int foo = 4;
double bar = 5.0;
std::string baz = "six";
};
MyConfig config;
node["foo"].into(config.foo);
node["bar"].into(config.bar);
if (!node["baz"].into(config.baz))
std::cerr << "Using default value for .baz!" << std::endl;
This removes a lot of the boilerplate associated with optionally filling in a value from a YAML. Without this operator, we have to do the following:
MyConfig config;
if (!node["foo"].IsDefined())
config.foo = node["foo"].as(config.foo);
if (!node["bar"].IsDefined())
config.bar = node["bar"].as(config.bar);
[...]
Implemented in https://github.com/jbeder/yaml-cpp/pull/1069
Thanks for filing. Reiterating here for other observers: I'm so-so on the utility of this, but if enough people thumbs-up the issue, then I'll merge the PR.
This is major for us, and would save us from spending a lot of time creating many nearly duplicate config files for many slightly different client and server configurations, which are hard to maintain. I've used the override style of configuration very successfully on past multiple projects, with other non-YAML file formats, and not having it in yaml-cpp is painful. If you haven't had the pleasure of benefitting from the utility of it, I assure you it's out there.
Besides allowing a base config file, and then separate override config files to tweak things for the different setups, it also allows easy injection of override values from the command line.
In this example command line, -c specifies a config file, and -o specifies a YAML string to pass to the config loader:
MyApplication.exe -c standard_config.yaml -c segment_2_config_override.yaml -o "thread_count: 10" -o "pool_size: 100000"
In both types of option, multiples are all passed to the YAML config loader, in order of appearance on the command line. into() would make this much easier.
Without this feature, we're stuck creating either dozens or hundreds of nearly identical config files (and then tasked with keeping them up to date when one common value needs to be changed in all of them), or complicating the code with the optional loading described by psigen above.