chore: change std optional json serialization to not include property if unset

This commit is contained in:
Jan 2024-04-01 14:58:57 +02:00
parent f8c9e62624
commit a2d649ed66
No known key found for this signature in database
GPG Key ID: 44B581F78FF5C57C
5 changed files with 122 additions and 100 deletions

View File

@ -2,7 +2,7 @@
#include "Game/T6/T6.h"
#include "Json/JsonOptional.h"
#include "Json/JsonExtension.h"
#include <memory>
#include <nlohmann/json.hpp>
#include <optional>
@ -44,7 +44,7 @@ namespace T6
GfxStencilFunc func;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonStencil, pass, fail, zfail, func);
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStencil, pass, fail, zfail, func);
enum class JsonAlphaTest
{
@ -154,7 +154,7 @@ namespace T6
std::optional<JsonStencil> stencilBack;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonStateBitsTableEntry,
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStateBitsTableEntry,
srcBlendRgb,
dstBlendRgb,
blendOpRgb,
@ -186,12 +186,12 @@ namespace T6
{
if (in.name.has_value())
{
out["name"] = in.name;
optional_to_json(out, "name", in.name);
}
else
{
out["nameFragment"] = in.nameFragment;
out["nameHash"] = in.nameHash;
optional_to_json(out, "nameFragment", in.nameFragment);
optional_to_json(out, "nameHash", in.nameHash);
}
out["literal"] = in.literal;
@ -199,9 +199,9 @@ namespace T6
inline void from_json(const nlohmann::json& in, JsonConstant& out)
{
in.value("name", nlohmann::json()).get_to(out.name);
in.value("nameFragment", nlohmann::json()).get_to(out.nameFragment);
in.value("nameHash", nlohmann::json()).get_to(out.nameHash);
optional_from_json(in, "name", out.name);
optional_from_json(in, "nameFragment", out.nameFragment);
optional_from_json(in, "nameHash", out.nameHash);
in.at("literal").get_to(out.literal);
};
@ -232,7 +232,7 @@ namespace T6
bool clampW;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonSamplerState, filter, mipMap, clampU, clampV, clampW);
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonSamplerState, filter, mipMap, clampU, clampV, clampW);
NLOHMANN_JSON_SERIALIZE_ENUM(TextureSemantic,
{
@ -284,13 +284,13 @@ namespace T6
{
if (in.name.has_value())
{
out["name"] = in.name;
optional_to_json(out, "name", in.name);
}
else
{
out["nameHash"] = in.nameHash;
out["nameStart"] = in.nameStart;
out["nameEnd"] = in.nameEnd;
optional_to_json(out, "nameHash", in.nameHash);
optional_to_json(out, "nameStart", in.nameStart);
optional_to_json(out, "nameEnd", in.nameEnd);
}
out["semantic"] = in.semantic;
@ -301,10 +301,10 @@ namespace T6
inline void from_json(const nlohmann::json& in, JsonTexture& out)
{
in.value("name", nlohmann::json()).get_to(out.name);
in.value("nameHash", nlohmann::json()).get_to(out.nameHash);
in.value("nameStart", nlohmann::json()).get_to(out.nameStart);
in.value("nameEnd", nlohmann::json()).get_to(out.nameEnd);
optional_from_json(in, "name", out.name);
optional_from_json(in, "nameHash", out.nameHash);
optional_from_json(in, "nameStart", out.nameStart);
optional_from_json(in, "nameEnd", out.nameEnd);
in.at("semantic").get_to(out.semantic);
in.at("isMatureContent").get_to(out.isMatureContent);
in.at("samplerState").get_to(out.samplerState);
@ -318,7 +318,7 @@ namespace T6
uint8_t columns;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonTextureAtlas, rows, columns);
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonTextureAtlas, rows, columns);
NLOHMANN_JSON_SERIALIZE_ENUM(MaterialGameFlags,
{
@ -376,7 +376,7 @@ namespace T6
std::optional<std::string> thermalMaterial;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonMaterial,
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonMaterial,
gameFlags,
sortKey,
textureAtlas,

View File

@ -3,7 +3,7 @@
#include "Game/T6/T6.h"
#include "Json/JsonCommon.h"
#include "Json/JsonOptional.h"
#include "Json/JsonExtension.h"
#include <memory>
#include <nlohmann/json.hpp>
#include <optional>
@ -21,7 +21,7 @@ namespace T6
float patternScale;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamoSet, solidCamoImage, patternCamoImage, patternOffset, patternScale);
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamoSet, solidCamoImage, patternCamoImage, patternOffset, patternScale);
class JsonWeaponCamoMaterialOverride
{
@ -30,7 +30,7 @@ namespace T6
std::string camoMaterial;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamoMaterialOverride, baseMaterial, camoMaterial);
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamoMaterialOverride, baseMaterial, camoMaterial);
constexpr auto SHADER_CONST_COUNT = 8;
@ -46,7 +46,7 @@ namespace T6
static_assert(SHADER_CONST_COUNT == std::extent_v<decltype(WeaponCamoMaterial::shaderConsts)>);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamoMaterial, useColorMap, useNormalMap, useSpecularMap, materialOverrides, shaderConsts);
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamoMaterial, useColorMap, useNormalMap, useSpecularMap, materialOverrides, shaderConsts);
class JsonWeaponCamoMaterialSet
{
@ -54,7 +54,7 @@ namespace T6
std::vector<JsonWeaponCamoMaterial> materials;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamoMaterialSet, materials);
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamoMaterialSet, materials);
class JsonWeaponCamo
{
@ -65,5 +65,5 @@ namespace T6
std::vector<JsonWeaponCamoMaterialSet> camoMaterials;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamo, solidBaseImage, patternBaseImage, camoSets, camoMaterials);
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamo, solidBaseImage, patternBaseImage, camoSets, camoMaterials);
} // namespace T6

View File

@ -1,5 +1,6 @@
#pragma once
#include "Json/JsonExtension.h"
#include <nlohmann/json.hpp>
class JsonVec2
@ -9,7 +10,7 @@ public:
float y;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonVec2, x, y);
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonVec2, x, y);
class JsonVec3
{
@ -19,7 +20,7 @@ public:
float z;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonVec3, x, y, z);
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonVec3, x, y, z);
class JsonVec4
{
@ -30,4 +31,4 @@ public:
float w;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonVec4, x, y, z, w);
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonVec4, x, y, z, w);

View File

@ -0,0 +1,58 @@
#pragma once
// Credits to
// https://www.kdab.com/jsonify-with-nlohmann-json/
#include <nlohmann/json.hpp>
#include <optional>
// partial specialization (full specialization works too)
namespace nlohmann
{
template<class T> void optional_to_json(nlohmann::json& j, const char* name, const std::optional<T>& value)
{
if (value)
j[name] = *value;
}
template<class T> void optional_from_json(const nlohmann::json& j, const char* name, std::optional<T>& value)
{
const auto it = j.find(name);
if (it != j.end())
value = it->get<T>();
else
value = std::nullopt;
}
template<typename> constexpr bool is_optional = false;
template<typename T> constexpr bool is_optional<std::optional<T>> = true;
template<typename T> void extended_to_json(const char* key, nlohmann::json& j, const T& value)
{
if constexpr (is_optional<T>)
nlohmann::optional_to_json(j, key, value);
else
j[key] = value;
}
template<typename T> void extended_from_json(const char* key, const nlohmann::json& j, T& value)
{
if constexpr (is_optional<T>)
nlohmann::optional_from_json(j, key, value);
else
j.at(key).get_to(value);
}
} // namespace nlohmann
#define EXTEND_JSON_TO(v1) extended_to_json(#v1, nlohmann_json_j, nlohmann_json_t.v1);
#define EXTEND_JSON_FROM(v1) extended_from_json(#v1, nlohmann_json_j, nlohmann_json_t.v1);
#define NLOHMANN_DEFINE_TYPE_EXTENSION(Type, ...) \
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_TO, __VA_ARGS__)) \
} \
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_FROM, __VA_ARGS__)) \
}

View File

@ -1,37 +0,0 @@
#pragma once
#include <nlohmann/json.hpp>
#include <optional>
// partial specialization (full specialization works too)
namespace nlohmann
{
template<typename T> struct adl_serializer<std::optional<T>>
{
static void to_json(json& j, const std::optional<T>& opt)
{
if (!opt.has_value())
{
j = nullptr;
}
else
{
j = *opt; // this will call adl_serializer<T>::to_json which will
// find the free function to_json in T's namespace!
}
}
static void from_json(const json& j, std::optional<T>& opt)
{
if (j.is_null())
{
opt = std::nullopt;
}
else
{
opt = j.template get<T>(); // same as above, but with
// adl_serializer<T>::from_json
}
}
};
} // namespace nlohmann