jbeder / yaml-cpp

A YAML parser and emitter in C++
MIT License
4.91k stars 1.77k forks source link

Allow Overriding of custom type default values #1265

Closed jasonbeach closed 5 months ago

jasonbeach commented 5 months ago

This is a simple PR that allows us to override defaults when decoding custom types. Consider:

struct Foo {
  int bar = 0;
};

namespace YAML {
template <>
struct convert<Foo> {
  static bool decode(const Node& node, Foo& f) {

    if (node["Bar"]) {
      f.bar = node["Bar"].as<int>();
    }
    // use the value that's already in f.bar
    return true;
  }
};

}  // namespace YAML

int main(int argc, char* argv[]) {
  auto node_good = YAML::Load("{Foo: {Bar: 3}}");
  auto node_bad = YAML::Load("{Foo: {}}");

  Foo f;
  f.bar = 99;
  f = node_good["Foo"].as<Foo>(f);
  fmt::print("bar: {} \n", f.bar);

  f.bar = 99;
  f = node_bad["Foo"].as<Foo>(f);
  fmt::print("bar: {} \n", f.bar);
}

Without the PR the output would be

bar: 3 
bar: 0 

result with this PR the output would be

$ ./build/Release/yaml_demo 
bar: 3 
bar: 99 

The big thing this enables diffing. i.e. if I have two yaml files, one that is a "base" that has all the my values and one that is a "diff" or a small subset that I may want to change, this makes overriding them much easier.