Files
KDDockWidgets/src/nlohmann_qt_helpers.h
2022-05-01 02:43:31 +05:00

220 lines
5.2 KiB
C++

/*
This file is part of KDDockWidgets.
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
Author: Waqar Ahmed <waqar.ahmed@kdab.com>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
Contact KDAB at <info@kdab.com> for commercial licensing options.
*/
#ifndef KDAB_NLOHMANN_JSON_QT_HELPERS_H
#define KDAB_NLOHMANN_JSON_QT_HELPERS_H
#include <nlohmann/json.hpp>
#include <QVariantMap>
#include <QDebug>
#include <QRect>
#include <QSize>
QT_BEGIN_NAMESPACE
inline void from_json(const nlohmann::json &j, QString &string)
{
string = QString::fromStdString(j.get<std::string>());
}
inline void to_json(nlohmann::json &j, const QString &s)
{
j = s.toStdString();
}
inline void from_json(const nlohmann::json &j, QStringList &stringList)
{
if (!j.is_null() && !j.is_array()) {
qWarning() << Q_FUNC_INFO << "This is not an array, fix the code";
stringList.clear();
return;
}
stringList.reserve((int)j.size());
for (const auto &v : j) {
stringList.push_back(v.get<QString>());
}
}
inline void to_json(nlohmann::json &j, const QStringList &stringList)
{
for (const auto &s : stringList) {
j.push_back(s);
}
}
inline void to_json(nlohmann::json& j, const QVariantList& list);
inline void from_json(const nlohmann::json& j, QVariantList& list);
inline void to_json(nlohmann::json& j, const QVariantMap& map);
inline void from_json(const nlohmann::json& j, QVariantMap& map);
inline void from_json(const nlohmann::json &j, QVariant& variant)
{
if (j.is_null())
{
variant = QVariant::fromValue(nullptr);
}
else if (j.is_number_unsigned())
{
variant = QVariant::fromValue(j.get<quint64>());
}
else if (j.is_number_integer())
{
variant = QVariant::fromValue(j.get<qint64>());
}
else if (j.is_number_float())
{
variant = QVariant::fromValue(j.get<qreal>());
}
else if (j.is_string())
{
variant = QVariant::fromValue(j.get<QString>());
}
else if (j.is_boolean())
{
variant = QVariant::fromValue(j.get<bool>());
}
else if (j.is_array())
{
QVariantList list;
from_json(j, list);
variant = list;
}
else if (j.is_object())
{
QVariantMap map = j.get<QVariantMap>();
variant = map;
}
}
inline void to_json(nlohmann::json& j, const QVariant& variant)
{
if (!variant.isValid()) {
qWarning() << Q_FUNC_INFO << "Unexpected invalid variant";
return;
}
auto type = static_cast<QMetaType::Type>(variant.userType());
if (type == QMetaType::QVariantList)
{
to_json(j, variant.value<QVariantList>());
}
else if (type == QMetaType::QVariantMap)
{
to_json(j, variant.value<QVariantMap>());
}
else if (type == QMetaType::QString)
{
j = variant.toString().toStdString();
}
else if (type == QMetaType::Double)
{
j = variant.toDouble();
}
else if (type == QMetaType::Bool)
{
j = variant.toBool();
}
else if (type == QMetaType::Int)
{
j = variant.toInt();
}
else if (type == QMetaType::UInt)
{
j = variant.toUInt();
}
else
{
qWarning() << Q_FUNC_INFO << "Unexpected type << " << type << variant.typeName();
j.clear();
}
}
inline void to_json(nlohmann::json& j, const QVariantList& list)
{
j = nlohmann::json::array();
for (auto it = list.cbegin(), end = list.cend(); it != end; ++it) {
j.push_back(*it);
}
}
inline void from_json(const nlohmann::json& j, QVariantList& list)
{
if (!j.is_array()) {
Q_UNUSED(list)
list.clear();
qWarning() << Q_FUNC_INFO << "Unexpected j not an array";
return;
}
list.reserve((int)j.size());
for (const auto &v : j) {
list.push_back(v.get<QVariant>());
}
}
inline void to_json(nlohmann::json& j, const QVariantMap& map)
{
j = nlohmann::json::object();
for (auto it = std::cbegin(map); it != std::cend(map); ++it) {
nlohmann::json json = it.value();
j[it.key().toStdString()] = json;
}
}
inline void from_json(const nlohmann::json& j, QVariantMap& map)
{
for (const auto &v : j.items()) {
map[QString::fromStdString(v.key())] = v.value().get<QVariant>();
}
}
inline void to_json(nlohmann::json& j, const QSize& size)
{
j["width"] = size.width();
j["height"] = size.height();
}
inline void from_json(const nlohmann::json& j, QSize& size)
{
QSize s;
size.setWidth(j.value("width", s.width()));
size.setHeight(j.value("height", s.height()));
}
inline void to_json(nlohmann::json& j, const QRect& rect)
{
j["x"] = rect.x();
j["y"] = rect.y();
j["width"] = rect.width();
j["height"] = rect.height();
}
inline void from_json(const nlohmann::json& j, QRect& rect)
{
QRect r;
rect.setX(j.value("x", r.x()));
rect.setY(j.value("y", r.y()));
rect.setWidth(j.value("width", r.width()));
rect.setHeight(j.value("height", r.height()));
}
QT_END_NAMESPACE
inline QDebug operator<<(QDebug debug, const nlohmann::json &j)
{
QDebugStateSaver s(debug);
debug.nospace() << '\n' << j.dump(4).data() << '\n';
return debug;
}
#endif