diff --git a/include/core/converter.h b/include/core/converter.h index 198dea4d..3833e0d6 100644 --- a/include/core/converter.h +++ b/include/core/converter.h @@ -68,9 +68,17 @@ struct DefaultConverter { static T fromJson(const QJsonValue& json, QStringList* errors = nullptr) { const QVariant v = json.toVariant(); if (!v.canConvert()) { - if (errors) errors->append(QString("Can't convert from type '%1'").arg(v.typeName())); - // Failed conversion will return a default-constructed object below + if (errors) errors->append(QString("Can't convert from JSON to type '%1'").arg(v.typeName())); + } else { + // 'canConvert' is only true if a conversion between types is theoretically possible, + // not necessarily if this value can be converted. e.g. "2" can be converted to int (2), + // but "hello world" cannot be converted to int and becomes 0. + T value; + bool ok = QMetaType::convert(v.metaType(), v.constData(), QMetaType::fromType(), &value); + if (ok) return value; + else if (errors) errors->append(QString("Failed to convert JSON value to type '%1'").arg(v.typeName())); } + // For failed conversion, return a default constructed value. return v.value(); } diff --git a/include/core/fieldmanager.h b/include/core/fieldmanager.h index ed2fcccd..2689a083 100644 --- a/include/core/fieldmanager.h +++ b/include/core/fieldmanager.h @@ -23,6 +23,13 @@ // QList options = {"hello","hi there"}; // FieldInterface* fi = makeFieldInterface(&someField, options); // fi->set(QJsonValue("5")); // someField is now "hello" (defaults to first element), error messages returned +// +// If a type or value is given that cannot be converted to the destination type, the field remains unchanged. +// int someField = 0; +// int min = 1, max = 4; +// FieldInterface* fi = makeFieldInterface(&someField, min, max); +// fi->set(QJsonValue()); // Cannot convert type. someField is still 0, error messages returned +// fi->set(QJsonValue("hi there")); // Cannot convert value. someField is still 0, error messages returned // Base class lets us use the interface without any type information. class FieldInterface {