qtjsonserializer_helpertypes.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. #ifndef QTJSONSERIALIZER_HELPERTYPES_H
  2. #define QTJSONSERIALIZER_HELPERTYPES_H
  3. #include <QtCore/qglobal.h>
  4. #include <QtCore/qobject.h>
  5. #include <QtCore/qlist.h>
  6. #include <QtCore/qvector.h>
  7. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  8. #include <QtCore/qlinkedlist.h>
  9. #endif
  10. #include <QtCore/qstack.h>
  11. #include <QtCore/qqueue.h>
  12. #include <QtCore/qset.h>
  13. #include <QtCore/qmap.h>
  14. #include <QtCore/qhash.h>
  15. #include <QtCore/qvariant.h>
  16. #include <QtCore/qsharedpointer.h>
  17. #include <QtCore/qpointer.h>
  18. #include <QtCore/qjsonvalue.h>
  19. #include <QtCore/qjsonobject.h>
  20. #include <QtCore/qjsonarray.h>
  21. #include <QtCore/qcborvalue.h>
  22. #include <QtCore/qcbormap.h>
  23. #include <QtCore/qcborarray.h>
  24. #include <type_traits>
  25. #include <tuple>
  26. #include <optional>
  27. #include <variant>
  28. namespace QtJsonSerializer::__private {
  29. template <class T, class Enable = void>
  30. struct gadget_helper
  31. {
  32. static constexpr bool value = false;
  33. static inline QJsonValue convert(const QJsonValue &jsonValue) {
  34. return jsonValue;
  35. }
  36. };
  37. template <class T>
  38. struct gadget_helper<T, typename T::QtGadgetHelper>
  39. {
  40. static constexpr bool value = true;
  41. static inline QJsonObject convert(const QJsonValue &jsonValue) {
  42. return jsonValue.toObject();
  43. }
  44. };
  45. template <typename T>
  46. struct is_serializable : public std::negation<std::is_pointer<T>> {};
  47. template <typename T>
  48. struct is_serializable<T*> : public std::disjunction<std::is_base_of<QObject, T>, gadget_helper<T>> {};
  49. template <typename T>
  50. struct is_serializable<QSharedPointer<T>> : public std::is_base_of<QObject, T> {};
  51. template <typename T>
  52. struct is_serializable<QPointer<T>> : public std::is_base_of<QObject, T> {};
  53. template <typename T>
  54. struct is_serializable<QList<T>> : public is_serializable<T> {};
  55. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  56. template <typename T>
  57. struct is_serializable<QVector<T>> : public is_serializable<T> {};
  58. #endif
  59. #if !defined(QT_NO_LINKED_LIST) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
  60. template <typename T>
  61. struct is_serializable<QLinkedList<T>> : public is_serializable<T> {};
  62. #endif
  63. template <typename T>
  64. struct is_serializable<QStack<T>> : public is_serializable<T> {};
  65. template <typename T>
  66. struct is_serializable<QQueue<T>> : public is_serializable<T> {};
  67. template <typename TKey, typename TValue>
  68. struct is_serializable<QMap<TKey, TValue>> : public std::conjunction<is_serializable<TKey>, is_serializable<TValue>> {};
  69. template <typename TKey, typename TValue>
  70. struct is_serializable<QMultiMap<TKey, TValue>> : public std::conjunction<is_serializable<TKey>, is_serializable<TValue>> {};
  71. template <typename TKey, typename TValue>
  72. struct is_serializable<QHash<TKey, TValue>> : public std::conjunction<is_serializable<TKey>, is_serializable<TValue>> {};
  73. template <typename TKey, typename TValue>
  74. struct is_serializable<QMultiHash<TKey, TValue>> : public std::conjunction<is_serializable<TKey>, is_serializable<TValue>> {};
  75. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  76. template <typename T1, typename T2>
  77. struct is_serializable<QPair<T1, T2>> : public std::conjunction<is_serializable<T1>, is_serializable<T2>> {};
  78. #endif
  79. template <typename T1, typename T2>
  80. struct is_serializable<std::pair<T1, T2>> : public std::conjunction<is_serializable<T1>, is_serializable<T2>> {};
  81. template <typename... TArgs>
  82. struct is_serializable<std::tuple<TArgs...>> : public std::conjunction<is_serializable<TArgs>...> {};
  83. template <typename T>
  84. struct is_serializable<std::optional<T>> : public is_serializable<T> {};
  85. template <typename... TArgs>
  86. struct is_serializable<std::variant<TArgs...>> : public std::conjunction<is_serializable<TArgs>...> {};
  87. template <typename T>
  88. struct json_type_raw : public std::conditional<gadget_helper<T>::value, QJsonObject, QJsonValue> {};
  89. template <typename T>
  90. struct json_type : public json_type_raw<T> {
  91. static_assert(is_serializable<T>::value, "Type T must be serializable to be used in a generic expression");
  92. static inline typename json_type_raw<T>::type convert(const QJsonValue &jsonValue) {
  93. return gadget_helper<T>::convert(jsonValue);
  94. }
  95. };
  96. template <typename T>
  97. struct json_type<T*> {
  98. static_assert(is_serializable<T*>::value, "Only QObject deriving classes or gadget pointers can be serialized as pointer");
  99. using type = QJsonObject;
  100. using cborType = QCborMap;
  101. static inline type convert(const QJsonValue &jsonValue) {
  102. return jsonValue.toObject();
  103. }
  104. };
  105. template <typename T>
  106. struct json_type<QSharedPointer<T>> {
  107. static_assert(is_serializable<QSharedPointer<T>>::value, "Only QObject deriving classes can be serialized as shared pointer");
  108. using type = QJsonObject;
  109. using cborType = QCborMap;
  110. static inline type convert(const QJsonValue &jsonValue) {
  111. return jsonValue.toObject();
  112. }
  113. };
  114. template <typename T>
  115. struct json_type<QPointer<T>> {
  116. static_assert(is_serializable<QPointer<T>>::value, "Only QObject deriving classes can be serialized as QPointer");
  117. using type = QJsonObject;
  118. using cborType = QCborMap;
  119. static inline type convert(const QJsonValue &jsonValue) {
  120. return jsonValue.toObject();
  121. }
  122. };
  123. template <typename T>
  124. struct json_type<QList<T>> {
  125. static_assert(is_serializable<QList<T>>::value, "The value type of a QList must be serializable for it to also be serializable");
  126. using type = QJsonArray;
  127. using cborType = QCborArray;
  128. static inline type convert(const QJsonValue &jsonValue) {
  129. return jsonValue.toArray();
  130. }
  131. };
  132. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  133. template <typename T>
  134. struct json_type<QVector<T>> {
  135. static_assert(is_serializable<QVector<T>>::value, "The value type of a QVector must be serializable for it to also be serializable");
  136. using type = QJsonArray;
  137. using cborType = QCborArray;
  138. static inline type convert(const QJsonValue &jsonValue) {
  139. return jsonValue.toArray();
  140. }
  141. };
  142. #endif
  143. #if !defined(QT_NO_LINKED_LIST) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
  144. template <typename T>
  145. struct json_type<QLinkedList<T>> {
  146. static_assert(is_serializable<QLinkedList<T>>::value, "The value type of a QLinkedList must be serializable for it to also be serializable");
  147. using type = QJsonArray;
  148. using cborType = QCborArray;
  149. static inline type convert(const QJsonValue &jsonValue) {
  150. return jsonValue.toArray();
  151. }
  152. };
  153. #endif
  154. template <typename T>
  155. struct json_type<QStack<T>> {
  156. static_assert(is_serializable<QStack<T>>::value, "The value type of a QStack must be serializable for it to also be serializable");
  157. using type = QJsonArray;
  158. using cborType = QCborArray;
  159. static inline type convert(const QJsonValue &jsonValue) {
  160. return jsonValue.toArray();
  161. }
  162. };
  163. template <typename T>
  164. struct json_type<QQueue<T>> {
  165. static_assert(is_serializable<QQueue<T>>::value, "The value type of a QQueue must be serializable for it to also be serializable");
  166. using type = QJsonArray;
  167. using cborType = QCborArray;
  168. static inline type convert(const QJsonValue &jsonValue) {
  169. return jsonValue.toArray();
  170. }
  171. };
  172. template <typename TKey, typename TValue>
  173. struct json_type<QMap<TKey, TValue>> {
  174. static_assert(is_serializable<QMap<TKey, TValue>>::value, "The key and value types of a QMap must be serializable for it to also be serializable");
  175. using type = QJsonObject;
  176. using cborType = QCborMap;
  177. static inline type convert(const QJsonValue &jsonValue) {
  178. return jsonValue.toObject();
  179. }
  180. };
  181. template <typename TKey, typename TValue>
  182. struct json_type<QMultiMap<TKey, TValue>> {
  183. static_assert(is_serializable<QMultiMap<TKey, TValue>>::value, "The key and value types of a QMultiMap must be serializable for it to also be serializable");
  184. using type = QJsonObject;
  185. using cborType = QCborMap;
  186. static inline type convert(const QJsonValue &jsonValue) {
  187. return jsonValue.toObject();
  188. }
  189. };
  190. template <typename TKey, typename TValue>
  191. struct json_type<QHash<TKey, TValue>> {
  192. static_assert(is_serializable<QHash<TKey, TValue>>::value, "The key and value types of a QHash must be serializable for it to also be serializable");
  193. using type = QJsonObject;
  194. using cborType = QCborMap;
  195. static inline type convert(const QJsonValue &jsonValue) {
  196. return jsonValue.toObject();
  197. }
  198. };
  199. template <typename TKey, typename TValue>
  200. struct json_type<QMultiHash<TKey, TValue>> {
  201. static_assert(is_serializable<QMultiHash<TKey, TValue>>::value, "The key and value types of a QMultiHash must be serializable for it to also be serializable");
  202. using type = QJsonObject;
  203. using cborType = QCborMap;
  204. static inline type convert(const QJsonValue &jsonValue) {
  205. return jsonValue.toObject();
  206. }
  207. };
  208. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  209. template <typename T1, typename T2>
  210. struct json_type<QPair<T1, T2>> {
  211. static_assert(is_serializable<QPair<T1, T2>>::value, "All elements of a QPair must be serializable for it to also be serializable");
  212. using type = QJsonArray;
  213. using cborType = QCborArray;
  214. static inline type convert(const QJsonValue &jsonValue) {
  215. return jsonValue.toArray();
  216. }
  217. };
  218. #endif
  219. template <typename T1, typename T2>
  220. struct json_type<std::pair<T1, T2>> {
  221. static_assert(is_serializable<std::pair<T1, T2>>::value, "All elements of a std::pair must be serializable for it to also be serializable");
  222. using type = QJsonArray;
  223. using cborType = QCborArray;
  224. static inline type convert(const QJsonValue &jsonValue) {
  225. return jsonValue.toArray();
  226. }
  227. };
  228. template <typename... TArgs>
  229. struct json_type<std::tuple<TArgs...>> {
  230. static_assert(is_serializable<std::tuple<TArgs...>>::value, "All elements of a std::tuple must be serializable for it to also be serializable");
  231. using type = QJsonArray;
  232. using cborType = QCborArray;
  233. static inline type convert(const QJsonValue &jsonValue) {
  234. return jsonValue.toArray();
  235. }
  236. };
  237. template <typename... TArgs>
  238. struct json_type<std::variant<TArgs...>> {
  239. static_assert(is_serializable<std::variant<TArgs...>>::value, "All elements of a std::variant must be serializable for it to also be serializable");
  240. using type = QJsonArray;
  241. using cborType = QCborArray;
  242. static inline type convert(const QJsonValue &jsonValue) {
  243. return jsonValue.toArray();
  244. }
  245. };
  246. template <typename T>
  247. struct variant_helper {
  248. static inline QVariant toVariant(const T &data) {
  249. return QVariant::fromValue<T>(data);
  250. }
  251. static inline T fromVariant(const QVariant &data) {
  252. return data.template value<T>();
  253. }
  254. };
  255. template <>
  256. struct variant_helper<QVariant> {
  257. static inline QVariant toVariant(const QVariant &data) {
  258. return data;
  259. }
  260. static inline QVariant fromVariant(const QVariant &data) {
  261. return data;
  262. }
  263. };
  264. }
  265. #endif // QTJSONSERIALIZER_HELPERTYPES_H