#include "versionnumberconverter_p.h" #include "exception.h" #include "cborserializer.h" #include using namespace QtJsonSerializer; using namespace QtJsonSerializer::TypeConverters; Q_LOGGING_CATEGORY(QtJsonSerializer::TypeConverters::logVersionConverter, "qt.jsonserializer.converter.versionnumber") bool VersionNumberConverter::canConvert(int metaTypeId) const { return metaTypeId == qMetaTypeId(); } QList VersionNumberConverter::allowedCborTags(int metaTypeId) const { Q_UNUSED(metaTypeId) return {static_cast(CborSerializer::VersionNumber)}; } QList VersionNumberConverter::allowedCborTypes(int metaTypeId, QCborTag tag) const { Q_UNUSED(metaTypeId) Q_UNUSED(tag) return {QCborValue::Array, QCborValue::String}; } int VersionNumberConverter::guessType(QCborTag tag, QCborValue::Type dataType) const { if (tag == static_cast(CborSerializer::VersionNumber) && allowedCborTypes(QMetaType::UnknownType, tag).contains(dataType)) return qMetaTypeId(); else return QMetaType::UnknownType; } QCborValue VersionNumberConverter::serialize(int propertyType, const QVariant &value) const { Q_UNUSED(propertyType) const auto version = value.value(); if (helper()->getProperty("versionAsString").toBool()) return {static_cast(CborSerializer::VersionNumber), version.toString()}; else { QCborArray array; for (const auto segment : version.segments()) array.append(segment); return {static_cast(CborSerializer::VersionNumber), array}; } } QVariant VersionNumberConverter::deserializeCbor(int propertyType, const QCborValue &value, QObject *parent) const { Q_UNUSED(propertyType) Q_UNUSED(parent) const auto cValue = (value.isTag() ? value.taggedValue() : value); if (cValue.type() == QCborValue::Array) { const auto cArray = cValue.toArray(); QVector segments; segments.reserve(static_cast(cArray.size())); auto i = 0; for (const auto cElem : cArray) { if (!cElem.isInteger()) { throw DeserializationException{"Segment at position " + QByteArray::number(i) + " is not an integer - a version number must be integers only!"}; } segments.append(static_cast(cElem.toInteger())); ++i; } return QVariant::fromValue(QVersionNumber{std::move(segments)}); } else if (cValue.type() == QCborValue::String) { const auto strValue = cValue.toString(); if (!strValue.isEmpty()) { int suffixIndex = -1; const auto version = QVersionNumber::fromString(strValue, &suffixIndex); if (version.isNull()) throw DeserializationException("Invalid version number, no segments found"); if (suffixIndex < strValue.size()) qCWarning(logVersionConverter) << "Parsed QVersionNumber with suffix - suffixes are discarded!"; return QVariant::fromValue(version); } else return QVariant::fromValue(QVersionNumber{}); } else throw DeserializationException{"Invalid type id"}; }