9#include "utils/exceptions.h"
11#include "utils/traits.h"
12#include "utils/types.h"
17#include <boost/unordered/concurrent_flat_map_fwd.hpp>
18#include <nlohmann/json.hpp>
23to_json (nlohmann::json &j,
const QString &s)
28from_json (
const nlohmann::json &j, QString &s)
30 s = QString::fromUtf8 (j.get<std::string> ());
34to_json (nlohmann::json &j,
const QUuid &uuid)
36 j = uuid.toString (QUuid::WithoutBraces);
39from_json (
const nlohmann::json &j, QUuid &uuid)
41 uuid = QUuid::fromString (j.get<QString> ());
44namespace zrythm::utils::serialization
47static constexpr auto kFormatMajorKey =
"formatMajor"sv;
48static constexpr auto kFormatMinorKey =
"formatMinor"sv;
49static constexpr auto kDocumentTypeKey =
"documentType"sv;
50static constexpr auto kVariantIndexKey =
"index"sv;
51static constexpr auto kVariantValueKey =
"value"sv;
63template <StdVariant Variant, ObjectBuilder BuilderT>
65variant_from_json_with_builder (
66 const nlohmann::json &j,
68 const BuilderT &builder)
71 j.at (zrythm::utils::serialization::kVariantIndexKey).get<
int> ();
72 auto creator = [&]<
size_t... I> (std::index_sequence<I...>) {
75 auto create_type_if_current_index = [&]<
size_t N> () {
76 using Type = std::variant_alternative_t<N, Variant>;
77 using StrippedType = std::remove_pointer_t<Type>;
80 auto object_ptr = builder.template build<StrippedType> ();
81 if constexpr (std::is_pointer_v<Type>)
83 j.at (zrythm::utils::serialization::kVariantValueKey)
84 .get_to (*object_ptr);
85 result = object_ptr.release ();
87 else if constexpr (std::is_copy_constructible_v<Type>)
89 j.at (zrythm::utils::serialization::kVariantValueKey)
90 .get_to (*object_ptr);
93 else if constexpr (is_derived_from_template_v<QObjectUniquePtr, Type>)
95 Type t = std::move (*object_ptr);
96 j.at (zrythm::utils::serialization::kVariantValueKey).get_to (*t);
97 result = std::move (t);
101 DEBUG_TEMPLATE_PARAM (Type)
104 "Only variant of pointers or copy-constructible types is currently supported");
109 (create_type_if_current_index.template operator()<I> (), ...);
114 var = creator (std::make_index_sequence<std::variant_size_v<Variant>>{});
122template <
typename T>
struct adl_serializer<T *>
124 static void to_json (json &j,
const T * ptr)
136template <
typename... Args>
struct adl_serializer<std::variant<Args...>>
138 static void to_json (json &j, std::variant<Args...>
const &v)
142 j[zrythm::utils::serialization::kVariantIndexKey] = v.index ();
143 j[zrythm::utils::serialization::kVariantValueKey] =
144 std::forward<decltype (value)> (value);
151template <
typename T>
struct adl_serializer<std::unique_ptr<T>>
153 static void to_json (json &json_value,
const std::unique_ptr<T> &ptr)
161 json_value =
nullptr;
164 static void from_json (
const json &json_value, std::unique_ptr<T> &ptr)
165 requires std::is_default_constructible_v<T>
167 ptr = std::make_unique<T> ();
168 json_value.get_to (*ptr);
173template <
typename T>
struct adl_serializer<std::shared_ptr<T>>
175 static void to_json (json &json_value,
const std::shared_ptr<T> &ptr)
183 json_value =
nullptr;
186 static void from_json (
const json &json_value, std::shared_ptr<T> &ptr)
187 requires std::is_default_constructible_v<T>
189 ptr = std::make_shared<T> ();
190 json_value.get_to (*ptr);
195template <
typename T>
struct adl_serializer<zrythm::utils::QObjectUniquePtr<T>>
206 json_value =
nullptr;
211 requires std::is_default_constructible_v<T>
214 json_value.get_to (*ptr);
219template <StrongTypedef T>
struct adl_serializer<T>
221 static void to_json (json &json_value,
const T &strong_type)
223 json_value = type_safe::get (strong_type);
225 static void from_json (
const json &json_value, T &strong_type)
227 json_value.get_to (type_safe::get (strong_type));
231template <
typename Key,
typename T>
232struct adl_serializer<boost::unordered::concurrent_flat_map<Key, T>>
234 using ConcurrentHashMap = boost::unordered::concurrent_flat_map<Key, T>;
236 static void to_json (json &j,
const ConcurrentHashMap &map)
238 std::map<Key, T> temp;
239 map.visit_all ([&temp] (
const auto &kv) {
240 temp.emplace (kv.first, kv.second);
245 static void from_json (
const json &j, ConcurrentHashMap &map)
247 auto temp = j.get<std::map<Key, T>> ();
249 for (
const auto &kv : temp)
251 map.emplace (kv.first, kv.second);
257template <
typename Unit,
typename Rep>
258struct adl_serializer<au::Quantity<Unit, Rep>>
260 static void to_json (json &j,
const au::Quantity<Unit, Rep> &quantity)
262 j = quantity.in (Unit{});
265 static void from_json (
const json &j, au::Quantity<Unit, Rep> &quantity)
268 j.get_to (raw_value);
269 quantity = au::QuantityMaker<Unit>{}(raw_value);
A unique pointer for QObject objects that also works with QObject-based ownership.
Base class for exceptions in Zrythm.