25#include "../../char8_t_remediation.hpp"
26#include "../../json.hpp"
27#include "../../optional.hpp"
28#include "../detail/json.hpp"
29#include "../fingerprint.hpp"
30#include "../naming_convention.hpp"
40namespace essence::meta::runtime {
45 template <
typename T,
typename =
void>
47 template <
typename U,
typename BasicJsonContext>
48 requires nlohmann::detail::is_basic_json_context<BasicJsonContext>::value
49 [[noreturn]]
static void throw_exception(
const U& member, std::string_view json_key, std::string_view message,
50 std::string_view internal, BasicJsonContext context) {
52 throw nlohmann::detail::parse_error::create(112, 0U,
53 nlohmann::detail::concat(U8(
"Accessing class data member '"), member.enclosing_type_name, U8(
"."),
54 member.name, U8(
"' required by JSON key '"), json_key, U8(
"' -- "), message,
55 U8(
"\nInternal error: "), internal),
66 template <
typename BasicJson,
typename U = T>
68 nlohmann::detail::is_basic_json<BasicJson>::value
69 && (nlohmann::detail::is_compatible_type<nlohmann::json, U>::value || std::ranges::forward_range<U>)
70 && !std::is_enum_v<U>)
71 static void to_json(BasicJson& json,
const U& value) {
72 nlohmann::to_json(json, value);
82 template <
typename BasicJson,
typename U = T>
84 nlohmann::detail::is_basic_json<BasicJson>::value
85 && (nlohmann::detail::is_compatible_type<nlohmann::json, U>::value || std::ranges::forward_range<U>)
86 && !std::is_enum_v<U>)
87 static void from_json(
const BasicJson& json, U& value) {
88 nlohmann::from_json(json, value);
98 template <
typename BasicJson,
typename U = T>
99 requires(nlohmann::detail::is_basic_json<BasicJson>::value &&
std_optional<U>)
100 static void to_json(BasicJson& json,
const U& value) {
115 template <
typename BasicJson,
typename U = T>
116 requires(nlohmann::detail::is_basic_json<BasicJson>::value &&
std_optional<U>)
117 static void from_json(
const BasicJson& json, U& value) {
118 if (json.is_null()) {
121 typename U::value_type new_value{};
124 value.emplace(std::move(new_value));
135 template <
typename BasicJson,
typename U = T>
136 requires(std::is_class_v<U> && nlohmann::detail::is_basic_json<BasicJson>::value
137 && !nlohmann::detail::is_compatible_type<nlohmann::json, U>::value
139 static void to_json(BasicJson& json,
const U& value) {
140 auto handler = [&](
const auto& item) {
142 if (!detail::check_json_omitted<U>(item.raw_name)) {
145 to_json(subjson, item.reference);
146 json.emplace(item.name, std::move(subjson));
148 }
catch (
const std::exception& ex) {
150 item, item.name, U8(
"Failed to serialize the data member to a JSON value."), ex.what(), &json);
154 enumerate_data_members<detail::get_json_naming_convention<U>()>(
155 value, [&](
const auto&... members) { (handler(members), ...); });
165 template <
typename BasicJson,
typename U = T>
166 requires(std::is_class_v<U> && nlohmann::detail::is_basic_json<BasicJson>::value
167 && !nlohmann::detail::is_compatible_type<nlohmann::json, U>::value
169 static void from_json(
const BasicJson& json, U& value) {
170 auto handler = [&](
const auto& item) {
172 if (!detail::check_json_omitted<U>(item.raw_name)) {
173 from_json(json.value(item.name, BasicJson{}), item.reference);
175 }
catch (
const std::exception& ex) {
176 throw_exception(item, item.name, U8(
"Failed to deserialize the JSON value to the data member."),
181 enumerate_data_members<detail::get_json_naming_convention<U>()>(
182 value, [&](
const auto&... members) { (handler(members), ...); });
192 template <
typename BasicJson,
typename U = T>
193 requires(nlohmann::detail::is_basic_json<BasicJson>::value
194 && std::same_as<typename BasicJson::string_t::value_type, char> && std::is_enum_v<U>)
195 static void to_json(BasicJson& json,
const U& value) {
198 json, convert_naming_convention(to_string(value), detail::get_json_naming_convention<T>()));
200 nlohmann::to_json(json, value);
211 template <
typename BasicJson,
typename U = T>
212 requires(nlohmann::detail::is_basic_json<BasicJson>::value
213 && std::same_as<typename BasicJson::string_t::value_type, char> && std::is_enum_v<U>)
214 static void from_json(
const BasicJson& json, U& value) {
215 if (json.is_string()) {
216 const auto name = json.template get_ptr<const typename BasicJson::string_t*>();
218 if (
auto enum_value = from_string<U>(*name)) {
221 throw nlohmann::detail::parse_error::create(112, 0U,
222 nlohmann::detail::concat(U8(
"invalid enumeration name '"), *name, U8(
"' of type '"),
227 nlohmann::from_json(json, value);
Definition optional.hpp:39