JSONRPC: Improve list handling of API list types

This commit is contained in:
Simon Stürz 2025-11-14 22:51:04 +01:00
parent 603ec80f7f
commit a06730336f

View File

@ -237,7 +237,8 @@ void JsonHandler::registerObject(const QMetaObject &metaObject)
// QFlags<Class:Enum>, therefore we need to remove additionally all < > // QFlags<Class:Enum>, therefore we need to remove additionally all < >
typeName = QString("$ref:%1").arg(typeNameRaw.split("::").last().remove('<').remove('>')); typeName = QString("$ref:%1").arg(typeNameRaw.split("::").last().remove('<').remove('>'));
} else if (metaProperty.isFlagType()) { } else if (metaProperty.isFlagType()) {
typeName = QVariantList() << "$ref:" + m_flagsEnums.value(metaProperty.name()); QString flagType = QString(metaProperty.typeName()).split("::").last().remove('<').remove('>');
typeName = QVariantList() << "$ref:" + m_flagsEnums.value(flagType, flagType);
} else if (typeId == QMetaType::QVariantList) { } else if (typeId == QMetaType::QVariantList) {
typeName = QVariantList() << enumValueName(Variant); typeName = QVariantList() << enumValueName(Variant);
} else { } else {
@ -260,7 +261,8 @@ void JsonHandler::registerObject(const QMetaObject &metaObject)
} else if (metaProperty.isEnumType()) { } else if (metaProperty.isEnumType()) {
typeName = QString("$ref:%1").arg(QString(metaProperty.typeName()).split("::").last()); typeName = QString("$ref:%1").arg(QString(metaProperty.typeName()).split("::").last());
} else if (metaProperty.isFlagType()) { } else if (metaProperty.isFlagType()) {
typeName = QVariantList() << "$ref:" + m_flagsEnums.value(metaProperty.name()); QString flagType = QString(metaProperty.typeName()).split("::").last();
typeName = QVariantList() << "$ref:" + m_flagsEnums.value(flagType, flagType);
} else if (metaProperty.type() == QVariant::List) { } else if (metaProperty.type() == QVariant::List) {
typeName = QVariantList() << enumValueName(Variant); typeName = QVariantList() << enumValueName(Variant);
} else { } else {
@ -509,7 +511,7 @@ QVariant JsonHandler::pack(const QMetaObject &metaObject, const void *value) con
// Special treatment for QDateTime (converting to time_t) // Special treatment for QDateTime (converting to time_t)
if (typeId == QMetaType::QDateTime) { if (typeId == QMetaType::QDateTime) {
QDateTime dateTime = propertyValue.toDateTime(); QDateTime dateTime = propertyValue.toDateTime();
if (metaProperty.isUser() && dateTime.toSecsSinceEpoch() == 0) { if (metaProperty.isUser() && (!dateTime.isValid() || dateTime.isNull())) {
continue; continue;
} }
propertyValue = propertyValue.toDateTime().toSecsSinceEpoch(); propertyValue = propertyValue.toDateTime().toSecsSinceEpoch();
@ -536,17 +538,21 @@ QVariant JsonHandler::unpack(const QMetaObject &metaObject, const QVariant &valu
// If it's a list object, loop over count // If it's a list object, loop over count
if (m_listMetaObjects.contains(typeName)) { if (m_listMetaObjects.contains(typeName)) {
QVariantList list;
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) #if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
if (static_cast<QMetaType::Type>(value.typeId()) != QMetaType::QVariantList) { QMetaType::Type valueType = static_cast<QMetaType::Type>(value.typeId());
#else #else
if (static_cast<QMetaType::Type>(value.type()) != QMetaType::QVariantList) { QMetaType::Type valueType = static_cast<QMetaType::Type>(value.type());
#endif #endif
if (!value.isValid() || value.isNull()) {
list = QVariantList();
} else if (valueType == QMetaType::QVariantList || valueType == QMetaType::QStringList) {
list = value.toList();
} else {
qCWarning(dcJsonRpc()) << "Cannot unpack" << typeName << ". Value is not in list format:" << value; qCWarning(dcJsonRpc()) << "Cannot unpack" << typeName << ". Value is not in list format:" << value;
return QVariant(); return QVariant();
} }
QVariantList list = value.toList();
int typeId = QMetaType::type(metaObject.className()); int typeId = QMetaType::type(metaObject.className());
void* ptr = QMetaType::create(typeId); void* ptr = QMetaType::create(typeId);
Q_ASSERT_X(typeId != 0, this->metaObject()->className(), QString("Cannot handle unregistered meta type %1").arg(metaObject.className()).toUtf8()); Q_ASSERT_X(typeId != 0, this->metaObject()->className(), QString("Cannot handle unregistered meta type %1").arg(metaObject.className()).toUtf8());
@ -612,16 +618,36 @@ QVariant JsonHandler::unpack(const QMetaObject &metaObject, const QVariant &valu
intList.append(val.toInt()); intList.append(val.toInt());
} }
metaProperty.writeOnGadget(ptr, QVariant::fromValue(intList)); metaProperty.writeOnGadget(ptr, QVariant::fromValue(intList));
} else if (metaProperty.typeName() == QStringLiteral("QList<QUuid>") } else if (metaProperty.typeName() == QStringLiteral("QList<QUuid>")) {
|| metaProperty.typeName() == QStringLiteral("QList<ThingId>")
|| metaProperty.typeName() == QStringLiteral("QList<EventTypeId>")
|| metaProperty.typeName() == QStringLiteral("QList<StateTypeId>")
|| metaProperty.typeName() == QStringLiteral("QList<ActionTypeId>")) {
QList<QUuid> uuidList; QList<QUuid> uuidList;
foreach (const QVariant &val, variant.toList()) { foreach (const QVariant &val, variant.toList()) {
uuidList.append(val.toUuid()); uuidList.append(val.toUuid());
} }
metaProperty.writeOnGadget(ptr, QVariant::fromValue(uuidList)); metaProperty.writeOnGadget(ptr, QVariant::fromValue(uuidList));
} else if (metaProperty.typeName() == QStringLiteral("QList<ThingId>")) {
QList<ThingId> thingIds;
foreach (const QVariant &val, variant.toList()) {
thingIds.append(ThingId(val.toUuid()));
}
metaProperty.writeOnGadget(ptr, QVariant::fromValue(thingIds));
} else if (metaProperty.typeName() == QStringLiteral("QList<EventTypeId>")) {
QList<EventTypeId> eventTypeIds;
foreach (const QVariant &val, variant.toList()) {
eventTypeIds.append(EventTypeId(val.toUuid()));
}
metaProperty.writeOnGadget(ptr, QVariant::fromValue(eventTypeIds));
} else if (metaProperty.typeName() == QStringLiteral("QList<StateTypeId>")) {
QList<StateTypeId> stateTypeIds;
foreach (const QVariant &val, variant.toList()) {
stateTypeIds.append(StateTypeId(val.toUuid()));
}
metaProperty.writeOnGadget(ptr, QVariant::fromValue(stateTypeIds));
} else if (metaProperty.typeName() == QStringLiteral("QList<ActionTypeId>")) {
QList<ActionTypeId> actionTypeIds;
foreach (const QVariant &val, variant.toList()) {
actionTypeIds.append(ActionTypeId(val.toUuid()));
}
metaProperty.writeOnGadget(ptr, QVariant::fromValue(actionTypeIds));
} }
continue; continue;
} }