14#include <AUI/Json/AJson.h>
15#include <AUI/IO/APath.h>
16#include "AUI/Traits/parameter_pack.h"
17#include "AUI/Traits/members.h"
18#include <AUI/Reflect/AEnumerate.h>
19#include <AUI/Traits/strings.h>
41template<
typename T,
typename Specialization =
void>
46 constexpr bool has_json_converter = aui::is_complete<AJsonConv<T>>;
49 inline AJson to_json(
const T& t) {
50 static_assert(aui::has_json_converter<T>,
"this type does not implement AJsonConv<T> trait");
54 inline T from_json(
const AJson& v) {
55 static_assert(aui::has_json_converter<T>,
"this type does not implement AJsonConv<T> trait");
62 inline void from_json(
const AJson& v, T& dst) {
63 static_assert(aui::has_json_converter<T>,
"this type does not implement AJsonConv<T> trait");
83namespace aui::impl::json {
89 AJsonFieldFlags flags;
91 Field(T& value,
const char* name, AJsonFieldFlags flags) : value(value), name(name), flags(flags) {}
94 if (
auto c =
object.
contains(name)) {
95 aui::from_json<T>(c->second, value);
97 if (!(flags & AJsonFieldFlags::OPTIONAL)) {
103 object[name] = aui::to_json<T>(value);
107 template<
typename... Items>
109 my_tuple(Items... items): std::tuple<Items...>(std::move(items)...) {}
112 auto operator()(T& v,
const char* n, AJsonFieldFlags flags = AJsonFieldFlags::DEFAULT) {
113 return (std::apply)([&](
auto&&...
args) {
118 std::tuple<Items...>& stdTuple() {
119 return (std::tuple<Items...>&)*
this;
125 auto operator()(T& v,
const char* n, AJsonFieldFlags flags = AJsonFieldFlags::DEFAULT) {
183#define AJSON_FIELDS(N, ...) \
184template<> struct AJsonConvFieldDescriptor<N>: N { \
185 auto operator()() { \
186 return aui::impl::json::empty_tuple() \
196#define AJSON_FIELDS_ENTRY(name) (name, AUI_PP_STRINGIZE(name))
204struct AJsonConv<T, std::enable_if_t<aui::is_complete<AJsonConvFieldDescriptor<T>>>> {
206 static AJson toJson(
const T& t) {
208 std::apply([&](
auto&&... fields) {
209 aui::parameter_pack::for_each([&](
auto&& field) {
213 return std::move(json);
216 static void fromJson(
const AJson& json, T& dst) {
217 const auto& jsonObject = json.asObject();
218 std::apply([&](
auto&&... fields) {
219 aui::parameter_pack::for_each([&](
auto&& field) {
229 static AJson toJson(
int v) {
232 static void fromJson(
const AJson& json,
int& dst) {
239 static AJson toJson(int64_t v) {
242 static void fromJson(
const AJson& json, int64_t& dst) {
243 dst = json.asLongInt();
248 static AJson toJson(
int v) {
251 static int fromJson(
const AJson& json) {
258 static AJson toJson(
float v) {
261 static void fromJson(
const AJson& json,
float& dst) {
262 dst = json.asNumber();
268 static AJson toJson(
double v) {
271 static void fromJson(
const AJson& json,
double& dst) {
272 dst = json.asNumber();
276template<aui::arithmetic UnderlyingType, auto min, auto max>
277 requires aui::convertible_to<
decltype(min), UnderlyingType> && aui::convertible_to<
decltype(max), UnderlyingType>
278struct AJsonConv<aui::ranged_number<UnderlyingType, min, max>> {
280 return (UnderlyingType) v;
283 if constexpr (aui::same_as<UnderlyingType, float> || aui::same_as<UnderlyingType, double>) {
284 dst = (UnderlyingType) json.asNumber();
286 dst = (UnderlyingType) json.asLongInt();
293 static AJson toJson(
bool v) {
296 static void fromJson(
const AJson& json,
bool& dst) {
307 dst = json.asString();
315 static void fromJson(
const AJson& json,
APath& dst) {
316 dst = json.asString();
320template<
typename T1,
typename T2>
322 static AJson toJson(std::pair<T1, T2> v) {
323 return AJson::Array({aui::to_json(v.first), aui::to_json(v.second)});
325 static void fromJson(
const AJson& json, std::pair<T1, T2>& dst) {
326 const auto& array = json.asArray();
327 dst = { aui::from_json<T1>(array.at(0)), aui::from_json<T2>(array.at(1)) };
337 dst = json.asArray();
347 dst = json.asObject();
355 array.reserve(v.size());
356 for (
const auto& elem : v) {
357 array << aui::to_json(elem);
359 return std::move(array);
362 auto& array = json.asArray();
364 dst.reserve(array.size());
365 for (
const auto& elem : array) {
366 dst << aui::from_json<T>(elem);
373struct AJsonConv<T, typename std::enable_if_t<std::is_enum_v<T>>> {
374 static AJson toJson(
const T& v) {
377 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
Represents a Unicode character string.
Definition: AString.h:37
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:123
Definition: Conversion.h:108
Clamps the possible values for a number to the specified range: [min;max].
Definition: values.h:452