Skip to content

pettni/ezconfig

Repository files navigation

ezconfig: Easy creation of C++ classes from json and yaml

Github CI Build and Test License

Examples

Suppose we have a class hierarchy with members that need to be instantiated from config files or some other dynamic data.

struct MyBase
{};

struct MyDerived : public MyBase
{
  struct Config
  {
    int x, y;
  };

  MyDerived(const Config &) {}
};

This library helps create objects in the hierarchy from json or yaml data.

After registering tags with derived types (see below) creating instances is as easy as this for yaml:

std::string yaml_data = R"(
!mytag
x: 1
y: 2
)";

auto obj = YAML::Load(yaml_data).as<std::unique_ptr<MyBase>>();

Similarly for json:

std::string json_data = R"(
{"mytag": {"x": 1, "y": 2}}
)";

auto obj = nlohmann::json::parse(json_data).get<std::unique_ptr<MyBase>>();

It also works with STL types. For example:

std::string json_data = R"(
{
    "key1": {"mytag": {"x": 1, "y": 2}},
    "key2": {"mytag": {"x": 3, "y": 4}}
}
)";

auto obj = nlohmann::json::parse(json_data).get<std::map<std::string, std::unique_ptr<MyBase>>>();

Register yaml converter

Yaml conversion uses yaml-cpp.

// In the header file
#include <ezconfig/yaml_fwd.hpp>
EZ_YAML_DECLARE(MyBase);

// In the implementation file
#include <ezconfig/yaml.hpp>
EZ_YAML_DEFINE(MyBase);

// make Config struct parse-able from json
// this can be automated with boost::hana
template<>
struct YAML::convert<MyDerived::Config>
{
  static bool decode(const YAML::Node & yaml, MyDerived::Config & obj)
  {
    obj.x = yaml["x"].as<int>();
    obj.y = yaml["y"].as<int>();
    return true;
  }
};

// register a factory method with a tag via MyDerived::Config
EZ_YAML_REGISTER(MyBase, "!mytag", MyDerived, MyDerived::Config);

Register json converter

Json conversion uses nlohmann_json.

#include <ezconfig/json_fwd.hpp>

// In the header file
EZ_JSON_DECLARE(MyBase);

// In the implementation file
#include <ezconfig/json.hpp>
EZ_JSON_DEFINE(MyBase);

// make Config struct parse-able from json
// this can be automated with boost::hana
void from_json(const nlohmann::json & j, MyDerived::Config & p)
{
  p.x = j.at("x").get<int>();
  p.y = j.at("y").get<int>();
}

// register a factory method with a tag via MyDerived::Config
EZ_JSON_REGISTER(MyBase, "mytag", MyDerived, MyDerived::Config);

TODOs

  • Extra yaml types decode
  • Extra yaml types encode
  • Extra json types decode
  • Extra json types encode

About

Instantiate C++ Objects from yaml and json

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published