Json fields definition.
#pragma once
#include <AUI/Json/AJson.h>
#include <AUI/IO/APath.h>
#include "AUI/Traits/parameter_pack.h"
#include "AUI/Traits/members.h"
#include <AUI/Reflect/AEnumerate.h>
#include <AUI/Traits/strings.h>
template<typename T, typename Specialization = void>
namespace aui {
template<typename T>
constexpr bool has_json_converter = aui::is_complete<AJsonConv<T>>;
template<typename T>
inline AJson to_json(
const T& t) {
static_assert(aui::has_json_converter<T>, "this type does not implement AJsonConv<T> trait");
}
template<typename T>
inline T from_json(
const AJson& v) {
static_assert(aui::has_json_converter<T>, "this type does not implement AJsonConv<T> trait");
T dst;
return dst;
}
template<typename T>
inline void from_json(
const AJson& v, T& dst) {
static_assert(aui::has_json_converter<T>, "this type does not implement AJsonConv<T> trait");
}
}
#ifdef OPTIONAL
#undef OPTIONAL
#endif
OPTIONAL = 0b1,
};
namespace aui::impl::json {
template<typename T>
struct Field {
T& value;
const char* name;
AJsonFieldFlags flags;
Field(T& value, const char* name, AJsonFieldFlags flags) : value(value), name(name), flags(flags) {}
aui::from_json<T>(c->second, value);
} else {
if (!(flags & AJsonFieldFlags::OPTIONAL)) {
}
}
}
object[name] = aui::to_json<T>(value);
}
};
template<typename... Items>
struct my_tuple: std::tuple<Items...> {
my_tuple(Items... items): std::tuple<Items...>(std::move(items)...) {}
template<typename T>
auto operator()(T& v, const char* n, AJsonFieldFlags flags = AJsonFieldFlags::DEFAULT) {
return (std::apply)([&](
auto&&...
args) {
}, stdTuple());
}
std::tuple<Items...>& stdTuple() {
return (std::tuple<Items...>&)*this;
}
};
struct empty_tuple {
template<typename T>
auto operator()(T& v, const char* n, AJsonFieldFlags flags = AJsonFieldFlags::DEFAULT) {
}
};
}
template<typename T>
#define AJSON_FIELDS(N, ...) \
template<> struct AJsonConvFieldDescriptor<N>: N { \
auto operator()() { \
return aui::impl::json::empty_tuple() \
__VA_ARGS__ \
; \
} \
};
#define AJSON_FIELDS_ENTRY(name) (name, AUI_PP_STRINGIZE(name))
template<typename T>
struct AJsonConv<T, std::enable_if_t<aui::is_complete<AJsonConvFieldDescriptor<T>>>> {
static AJson toJson(
const T& t) {
std::apply([&](auto&&... fields) {
aui::parameter_pack::for_each([&](auto&& field) {
field(json);
}, fields...);
return std::move(json);
}
static void fromJson(
const AJson& json, T& dst) {
const auto& jsonObject = json.
asObject();
std::apply([&](auto&&... fields) {
aui::parameter_pack::for_each([&](auto&& field) {
field(jsonObject);
}, fields...);
}
};
template<>
static AJson toJson(
int v) {
return v;
}
static void fromJson(
const AJson& json,
int& dst) {
}
};
template<>
static AJson toJson(int64_t v) {
return v;
}
static void fromJson(
const AJson& json, int64_t& dst) {
}
};
template<>
static AJson toJson(
int v) {
return v;
}
static int fromJson(
const AJson& json) {
return json.asInt();
}
};
template<>
static AJson toJson(
float v) {
return v;
}
static void fromJson(
const AJson& json,
float& dst) {
}
};
template<>
static AJson toJson(
double v) {
return v;
}
static void fromJson(
const AJson& json,
double& dst) {
dst = json.asNumber();
}
};
template<aui::arithmetic UnderlyingType, auto min, auto max>
requires aui::convertible_to<decltype(min), UnderlyingType> && aui::convertible_to<decltype(max), UnderlyingType>
struct AJsonConv<aui::ranged_number<UnderlyingType, min, max>> {
return (UnderlyingType) v;
}
if constexpr (aui::same_as<UnderlyingType, float> || aui::same_as<UnderlyingType, double>) {
dst = (UnderlyingType) json.asNumber();
} else {
dst = (UnderlyingType) json.asLongInt();
}
}
};
template<>
static AJson toJson(
bool v) {
return v;
}
static void fromJson(
const AJson& json,
bool& dst) {
}
};
template<>
return v;
}
}
};
template<>
return v;
}
static void fromJson(
const AJson& json,
APath& dst) {
dst = json.asString();
}
};
template<typename T1, typename T2>
static AJson toJson(std::pair<T1, T2> v) {
return AJson::Array({aui::to_json(v.first), aui::to_json(v.second)});
}
static void fromJson(
const AJson& json, std::pair<T1, T2>& dst) {
const auto& array = json.
asArray();
dst = { aui::from_json<T1>(array.at(0)), aui::from_json<T2>(array.at(1)) };
}
};
template<>
return std::move(v);
}
dst = json.asArray();
}
};
template<>
return std::move(v);
}
dst = json.asObject();
}
};
template<typename T>
struct AJsonConv<
AVector<T>, typename std::enable_if_t<aui::has_json_converter<T>>> {
array.reserve(v.size());
for (const auto& elem : v) {
array << aui::to_json(elem);
}
return std::move(array);
}
auto& array = json.asArray();
dst.clear();
dst.reserve(array.size());
for (const auto& elem : array) {
dst << aui::from_json<T>(elem);
}
}
};
template<typename T>
struct AJsonConv<T, typename std::enable_if_t<std::is_enum_v<T>>> {
static AJson toJson(
const T& v) {
}
static void fromJson(
const AJson& json, T& dst) {
}
};
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:79
An add-on to AString with functions for working with the path.
Definition: APath.h:106
A std::vector with AUI extensions.
Definition: AVector.h:38
API_AUI_CORE const ACommandLineArgs & args() noexcept
Definition: OSAndroid.cpp:29
bool contains(const Container &c, const typename Container::const_reference value) noexcept
Definition: containers.h:153
AUI_ENUM_FLAG(ASide)
Describes sides of a 2D rectangle.
Definition: ASide.h:24
@ DEFAULT
There's no concrete input action. Let the OS decide which action is the most appropriate.
Definition: Conversion.h:133
Definition: Conversion.h:42
Definition: Conversion.h:86
Definition: Conversion.h:108
Clamps the possible values for a number to the specified range: [min;max].
Definition: values.h:452