6 #include "jsonh/jsonh.h"
35 std::string
could_be(
const std::string& invalid_value,
const std::vector<std::string>& possible_values);
47 std::optional<jsonh::Value>
get(
const std::string& name);
53 #define JSON_PARSE_FUNC(TYPE) \
54 bool parse(::eu::log::Logger* log, TYPE* owner, jsonh::Value root_val, const jsonh::Document* doc)
56 #define JSON_EXPECT(x, msg) \
65 #define JSON_BEGIN_ENUM(TYPE) \
66 const auto* dnu_val = root_val.AsString(doc);\
67 JSON_EXPECT(dnu_val, "Expected string value for " #TYPE);\
68 const std::string dnu_enum_name = #TYPE; \
69 using dnu_enum_type = TYPE; \
70 std::vector<std::string> dnu_values
72 #define JSON_ENUM_VAL(VAL) \
73 if(dnu_val->value == #VAL) {\
74 *owner = dnu_enum_type::VAL;\
78 dnu_values.emplace_back(#VAL);\
80 #define JSON_END_ENUM() \
81 log->error(fmt::format("{} was invalid for {}, could be {}",\
82 dnu_val->value, dnu_enum_name,\
83 eu::io::could_be(dnu_val->value, dnu_values)));\
86 #define JSON_BEGIN_OBJECT() \
87 const auto* root = root_val.AsObject(doc);\
88 JSON_EXPECT(root, "root is not a object");\
89 auto object = ::eu::io::ObjectQuery{ root }
91 #define JSON_VAL_X(TYPE, PROP, REQUIRED) \
93 auto dnu_json = object.get(#PROP);\
96 auto* dnu_prop = dnu_json->As ## TYPE(doc);\
97 JSON_EXPECT(dnu_prop, #PROP " is not a " #TYPE);\
98 owner->PROP = dnu_prop->value;\
100 else if constexpr(REQUIRED)\
102 object.required.emplace_back(#PROP);\
106 #define JSON_VAL_OBJ_X(TYPE, PROP, REQUIRED, CON) \
108 auto dnu_json = object.get(#PROP);\
112 if (false == parse(log, &dnu_prop, *dnu_json, doc))\
116 owner->PROP = CON(std::move(dnu_prop));\
118 else if constexpr(REQUIRED)\
120 object.required.emplace_back(#PROP);\
124 #define JSON_VAL_OBJ(TYPE, PROP) JSON_VAL_OBJ_X(TYPE, PROP, true, )
125 #define JSON_VAL_OPT_OBJ(TYPE, PROP) JSON_VAL_OBJ_X(TYPE, PROP, false, )
126 #define JSON_VAL_OPT_OBJ_CON(TYPE, PROP, CON) JSON_VAL_OBJ_X(TYPE, PROP, false, CON)
128 #define JSON_VAL(TYPE, PROP) JSON_VAL_X(TYPE, PROP, true)
129 #define JSON_OPT_VAL(TYPE, PROP) JSON_VAL_X(TYPE, PROP, false)
132 #define JSON_ARRAY(TYPE, PROP) \
134 auto dnu_val = object.get(#PROP);\
135 JSON_EXPECT(dnu_val, "missing property " #PROP);\
136 auto* dnu_array = dnu_val->AsArray(doc);\
137 JSON_EXPECT(dnu_array, #PROP " is not a array");\
138 for (const auto dnu_json : dnu_array->array)\
141 if (false == parse(log, &dnu_prop, dnu_json, doc))\
145 owner->PROP.emplace_back(std::move(dnu_prop));\
149 #define JSON_ARRAY_PROP_CON(TYPE, PROP, CON) \
151 auto dnu_val = object.get(#PROP);\
152 JSON_EXPECT(dnu_val, "missing property " #PROP);\
153 auto* dnu_array = dnu_val->AsArray(doc);\
154 JSON_EXPECT(dnu_array, #PROP " is not a array");\
155 for (const auto dnu_json : dnu_array->array)\
157 const auto* dnu_prop = dnu_json.As ## TYPE(doc);\
158 JSON_EXPECT(dnu_prop, #PROP " is not a " #TYPE);\
159 owner->PROP.emplace_back(CON(dnu_prop->value));\
163 #define JSON_ARRAY_PROP(TYPE, PROP) \
164 JSON_ARRAY_PROP_CON(TYPE, PROP, )
166 #define JSON_END_OBJECT() \
167 const auto missing = object.get_missing_errors_message();\
170 log->error(*missing);\
JsonResult read_json_file(FileSystem *fs, const FilePath &file_name)
std::string could_be(const std::string &invalid_value, const std::vector< std::string > &possible_values)
std::string get_string_from_path_for_debugging(FileSystem *fs, const FilePath &p)
std::optional< std::string > get_missing_errors_message()
ObjectQuery(const jsonh::Object *o)
const jsonh::Object * object
std::vector< std::string > required
std::set< std::string > found
std::optional< jsonh::Value > get(const std::string &name)
std::set< std::string > missing