- Small header-only library for creating objects from dynamic json or yaml data.
- Uses nlohmann_json and yaml-cpp for parsing.
- Documentation.
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>>>();
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);
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);
- Extra yaml types decode
- Extra yaml types encode
- Extra json types decode
- Extra json types encode