14#include <range/v3/range/concepts.hpp>
15#include <AUI/Json/AJson.h>
16#include <AUI/IO/APath.h>
17#include "AUI/Traits/parameter_pack.h"
18#include "AUI/Traits/members.h"
19#include <AUI/Reflect/AEnumerate.h>
20#include <AUI/Traits/strings.h>
42template<
typename T,
typename Specialization =
void>
50 inline AJson to_json(
const T& t) {
51 static_assert(aui::has_json_converter<T>,
"this type does not implement AJsonConv<T> trait");
55 inline T from_json(
const AJson& v) {
57 static_assert(aui::has_json_converter<T>,
"this type does not implement AJsonConv<T> trait");
62 throw AJsonException(
"While converting from json to cpp\n" + AJson::toString(v), std::current_exception());
67 inline void from_json(
const AJson& v, T& dst) {
69 static_assert(aui::has_json_converter<T>,
"this type does not implement AJsonConv<T> trait");
70 AJsonConv<T>::fromJson(v, dst);
72 throw AJsonException(
"While converting from json to cpp\n" + AJson::toString(v), std::current_exception());
92namespace aui::impl::json {
98 AJsonFieldFlags flags;
100 Field(T& value,
const char* name, AJsonFieldFlags flags) : value(value), name(name), flags(flags) {}
102 void operator()(
const AJson::Object&
object) {
103 if (
auto c =
object.contains(name)) {
104 aui::from_json<T>(c->second, value);
106 if (!(flags & AJsonFieldFlags::OPTIONAL)) {
107 throw AJsonException(R
"(field "{}" is not present)"_format(name));
111 void operator()(AJson::Object&
object) {
112 object[name] = aui::to_json<T>(value);
116 template<
typename... Items>
117 struct my_tuple: std::tuple<Items...> {
118 my_tuple(Items... items): std::tuple<Items...>(std::move(items)...) {}
121 auto operator()(T& v,
const char* n, AJsonFieldFlags flags = AJsonFieldFlags::DEFAULT) {
122 return (std::apply)([&](
auto&&...
args) {
127 std::tuple<Items...>& stdTuple() {
128 return (std::tuple<Items...>&)*
this;
134 auto operator()(T& v,
const char* n, AJsonFieldFlags flags = AJsonFieldFlags::DEFAULT) {
192#define AJSON_FIELDS(N, ...) \
193template<> struct AJsonConvFieldDescriptor<N>: N { \
194 auto operator()() { \
195 return aui::impl::json::empty_tuple() \
205#define AJSON_FIELDS_ENTRY(name) (name, AUI_PP_STRINGIZE(name))
213struct AJsonConv<T, std::enable_if_t<aui::is_complete<AJsonConvFieldDescriptor<T>>>> {
215 static AJson toJson(
const T& t) {
217 std::apply([&](
auto&&... fields) {
218 aui::parameter_pack::for_each([&](
auto&& field) {
222 return std::move(json);
225 static void fromJson(
const AJson& json, T& dst) {
226 const auto& jsonObject = json.asObject();
227 std::apply([&](
auto&&... fields) {
228 aui::parameter_pack::for_each([&](
auto&& field) {
238 static AJson toJson(
int v) {
241 static void fromJson(
const AJson& json,
int& dst) {
248 static AJson toJson(
const std::shared_ptr<T>& v) {
249 return aui::to_json(*v);
251 static void fromJson(
const AJson& json, std::shared_ptr<T>& dst) {
252 dst = std::make_shared<T>(aui::from_json<T>(json));
261 static AJson toJson(int64_t v) {
264 static void fromJson(
const AJson& json, int64_t& dst) {
265 dst = json.asLongInt();
270 static AJson toJson(
int v) {
273 static int fromJson(
const AJson& json) {
280 static AJson toJson(
float v) {
283 static void fromJson(
const AJson& json,
float& dst) {
284 dst = json.asNumber();
290 static AJson toJson(
double v) {
293 static void fromJson(
const AJson& json,
double& dst) {
294 dst = json.asNumber();
298template<aui::arithmetic UnderlyingType, auto min, auto max>
300struct AJsonConv<aui::ranged_number<UnderlyingType, min, max>> {
302 return (UnderlyingType) v;
306 dst = (UnderlyingType) json.asNumber();
308 dst = (UnderlyingType) json.asLongInt();
315 static AJson toJson(
bool v) {
318 static void fromJson(
const AJson& json,
bool& dst) {
329 dst = json.asString();
337 static void fromJson(
const AJson& json,
APath& dst) {
338 dst = json.asString();
342template<
typename T1,
typename T2>
344 static AJson toJson(std::pair<T1, T2> v) {
345 return AJson::Array({aui::to_json(v.first), aui::to_json(v.second)});
347 static void fromJson(
const AJson& json, std::pair<T1, T2>& dst) {
348 const auto& array = json.asArray();
349 dst = { aui::from_json<T1>(array.at(0)), aui::from_json<T2>(array.at(1)) };
355 static AJson toJson(AJson::Array v) {
358 static void fromJson(
const AJson& json, AJson::Array& dst) {
359 dst = json.asArray();
365 static AJson toJson(AJson::Object v) {
368 static void fromJson(
const AJson& json, AJson::Object& dst) {
369 dst = json.asObject();
373template<ranges::range T>
375 static AJson toJson(
const T& v) {
377 if constexpr (ranges::sized_range<T>) {
378 array.reserve(v.size());
380 for (
const auto& elem : v) {
381 array << aui::to_json(elem);
383 return std::move(array);
385 static void fromJson(
const AJson& json, T& dst) {
386 auto& array = json.asArray();
389 if constexpr (
requires(T&& t) { t.reserve(
static_cast<size_t>(0)); }) {
390 dst.reserve(array.size());
392 for (
const auto& elem : array) {
393 dst << aui::from_json<std::decay_t<
decltype(*dst.begin())>>(elem);
400struct AJsonConv<T, typename std::enable_if_t<std::is_enum_v<T>>> {
401 static AJson toJson(
const T& v) {
404 static void fromJson(
const AJson& json, T& dst) {
410template<APropertyWritable T>
412 static AJson toJson(
const T& t) {
415 static void fromJson(
const AJson& json, T& dst) {
416 dst = aui::from_json<typename T::Underlying>(json);
static enum_t byName(const AString &name)
Map runtime name to enum value. Transforms name to uppercase as a fallback. Throws an exception if no...
Definition AEnumerate.h:121
static const AMap< enum_t, AString, enum_less > & valueToNameMap()
Map runtime enum value to name.
Definition AEnumerate.h:183
Definition Exception.h:17
Json atom.
Definition AJson.h:84
An add-on to AString with functions for working with the path.
Definition APath.h:128
Represents a Unicode character string.
Definition AString.h:38
An std::weak_ptr with AUI extensions.
Definition SharedPtrTypes.h:179
#define AUI_ENUM_FLAG(name)
Make a bitfield-style enum class.
Definition AEnumerate.h:227
API_AUI_CORE const ACommandLineArgs & args() noexcept
constexpr bool is_complete
Determines whether T is complete or not.
Definition types.h:23
@ DEFAULT
There's no concrete input action. Let the OS decide which action is the most appropriate.
Definition ATextInputActionIcon.h:36
Definition Conversion.h:142
Definition Conversion.h:43
Definition Conversion.h:95
Definition Conversion.h:132
Definition Conversion.h:117
Clamps the possible values for a number to the specified range: [min;max].
Definition values.h:423