// Copyright (C) 2018 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once #include "languageserverprotocol_global.h" #include #include #include #include #include #include #include namespace LanguageServerProtocol { LANGUAGESERVERPROTOCOL_EXPORT Q_DECLARE_LOGGING_CATEGORY(conversionLog) template T fromJsonValue(const QJsonValue &value) { if (conversionLog().isDebugEnabled() && !value.isObject()) qCDebug(conversionLog) << "Expected Object in json value but got: " << value; T result(value.toObject()); if (conversionLog().isDebugEnabled() && !result.isValid()) qCDebug(conversionLog) << typeid(result).name() << " is not valid: " << result; return result; } template<> LANGUAGESERVERPROTOCOL_EXPORT QString fromJsonValue(const QJsonValue &value); template<> LANGUAGESERVERPROTOCOL_EXPORT int fromJsonValue(const QJsonValue &value); template<> LANGUAGESERVERPROTOCOL_EXPORT double fromJsonValue(const QJsonValue &value); template<> LANGUAGESERVERPROTOCOL_EXPORT bool fromJsonValue(const QJsonValue &value); template<> LANGUAGESERVERPROTOCOL_EXPORT QJsonObject fromJsonValue(const QJsonValue &value); template<> LANGUAGESERVERPROTOCOL_EXPORT QJsonArray fromJsonValue(const QJsonValue &value); template<> LANGUAGESERVERPROTOCOL_EXPORT QJsonValue fromJsonValue(const QJsonValue &value); template class LanguageClientArray : public std::variant, std::nullptr_t> { public: using std::variant, std::nullptr_t>::variant; using std::variant, std::nullptr_t>::operator=; LanguageClientArray() {} explicit LanguageClientArray(const QList &list) { *this = list; } explicit LanguageClientArray(const QJsonValue &value) { if (value.isArray()) { QList values; values.reserve(value.toArray().count()); for (auto arrayValue : value.toArray()) values << fromJsonValue(arrayValue); *this = values; } else { *this = nullptr; } } QJsonValue toJson() const { if (const auto list = std::get_if>(this)) { QJsonArray array; for (const T &value : *list) array.append(QJsonValue(value)); return array; } return QJsonValue(); } QList toList() const { QTC_ASSERT(std::holds_alternative>(*this), return {}); return std::get>(*this); } bool isNull() const { return std::holds_alternative(*this); } }; template class LanguageClientValue : public std::variant { public: using std::variant::operator=; LanguageClientValue() : std::variant(nullptr) { } LanguageClientValue(const T &value) : std::variant(value) { } LanguageClientValue(const QJsonValue &value) { if (!QTC_GUARD(!value.isUndefined()) || value.isNull()) *this = nullptr; else *this = fromJsonValue(value); } operator const QJsonValue() const { if (auto val = std::get_if(this)) return QJsonValue(*val); return QJsonValue(); } T value(const T &defaultValue = T()) const { QTC_ASSERT(std::holds_alternative(*this), return defaultValue); return std::get(*this); } template LanguageClientValue transform() { QTC_ASSERT(!std::holds_alternative(*this), return LanguageClientValue()); return Type(std::get(*this)); } bool isNull() const { return std::holds_alternative(*this); } }; template QJsonArray enumArrayToJsonArray(const QList &values) { QJsonArray array; for (T value : values) array.append(static_cast(value)); return array; } template QList jsonArrayToList(const QJsonArray &array) { QList list; for (const QJsonValue &val : array) list << fromJsonValue(val); return list; } } // namespace LanguageServerProtocol