ezconfig
Create C++ Objects from Yaml and Json
Loading...
Searching...
No Matches
json.hpp
Go to the documentation of this file.
1// Copyright (c) 2023 Petter Nilsson. MIT License. https://github.com/pettni/ezconfig
2
10#pragma once
11
12#include <nlohmann/json.hpp>
13
14#include "factory.hpp"
15#include "json_fwd.hpp"
16
29#define EZ_JSON_DEFINE(Base) \
30 EZ_FACTORY_DEFINE(Base, const nlohmann::json &); \
31 template std::unique_ptr<Base> ezconfig::json::Create<Base>(const nlohmann::json &); \
32 template struct nlohmann::adl_serializer<std::shared_ptr<Base>>; \
33 template struct nlohmann::adl_serializer<std::unique_ptr<Base>>
34
53#define EZ_JSON_REGISTER(Base, tag, Derived, ...) \
54 EZ_STATIC_INVOKE(&ezconfig::json::Add<Base, Derived __VA_OPT__(, ) __VA_ARGS__>, tag)
55
56namespace ezconfig::json {
57
58// clang-format off
59template<typename T>
60concept JsonParseable = requires(const nlohmann::json & j) {
61 {j.get<T>()} -> std::convertible_to<T>;
62};
63// clang-format on
64
78template<typename Base, typename Derived, typename Intermediate = Derived>
79 requires(
80 std::is_base_of_v<Base, Derived> && JsonParseable<Intermediate>
81 && std::is_constructible_v<Derived, Intermediate &&>)
82void Add(const std::string & tag)
83{
84 auto creator = [](const nlohmann::json & json) { return std::make_unique<Derived>(json.get<Intermediate>()); };
85 EZ_FACTORY_INSTANCE(Base, const nlohmann::json &).add(tag, std::move(creator));
86}
87
88template<typename Base>
89std::unique_ptr<Base> Create(const nlohmann::json & json)
90{
91 if (!json.is_object() || json.size() != 1) {
92 throw std::logic_error("Expected dictionary of size 1 of format {tag: object}");
93 }
94 return EZ_FACTORY_INSTANCE(Base, const nlohmann::json &).create(json.begin().key(), json.begin().value());
95}
96
97} // namespace ezconfig::json
98
99template<ezconfig::json::Constructible Base>
100void nlohmann::adl_serializer<std::shared_ptr<Base>>::from_json(const json & j, std::shared_ptr<Base> & ptr)
101{
102 ptr = ::ezconfig::json::Create<Base>(j);
103}
104
105template<ezconfig::json::Constructible Base>
106void nlohmann::adl_serializer<std::unique_ptr<Base>>::from_json(const json & j, std::unique_ptr<Base> & ptr)
107{
108 ptr = ::ezconfig::json::Create<Base>(j);
109}
Factory base class.
std::unique_ptr< Base > Create(const nlohmann::json &json)
Create an object using the factory.
Definition json.hpp:89
void Add(const std::string &tag)
Add a factory method.
Definition json.hpp:82
Json factory forward declarations.