fix: dconfig can't support embed complex data type

using recursion to parse QDBusArgument.

Log:
Influence: none
This commit is contained in:
Ye ShanShan 2022-03-22 17:05:09 +08:00 committed by mike
parent 6cb60700f1
commit b6d3462745
3 changed files with 81 additions and 8 deletions

View File

@ -295,10 +295,8 @@ public:
return config->keyList();
}
virtual QVariant value(const QString &key, const QVariant &fallback) const override
static QVariant decodeQDBusArgument(const QVariant &v)
{
const QDBusVariant &dv = config->value(key);
const QVariant &v = dv.variant();
if (v.canConvert<QDBusArgument>()) {
// we use QJsonValue to resolve all data type in DConfigInfo class, so it's type is equal QJsonValue::Type,
// now we parse Map and Array type to QVariant explicitly.
@ -307,20 +305,35 @@ public:
case QDBusArgument::MapType: {
QVariantMap list;
complexType >> list;
return list;
QVariantMap res;
for (auto iter = list.begin(); iter != list.end(); iter++) {
res[iter.key()] = decodeQDBusArgument(iter.value());
}
return res;
}
case QDBusArgument::ArrayType: {
QVariantList list;
complexType >> list;
return list;
QVariantList res;
res.reserve(list.size());
for (const auto &item : qAsConst(list)) {
res << decodeQDBusArgument(item);
}
return res;
}
default:
qCWarning(cfLog, "Can't parse the type, it maybe need user to do it, "
"key: %s, and QDBusArgument::ElementType: %d.", qPrintable(key), complexType.currentType());
qWarning("Can't parse the type, it maybe need user to do it, "
"QDBusArgument::ElementType: %d.", complexType.currentType());
}
}
return v;
}
return v.isValid() ? v : fallback;
virtual QVariant value(const QString &key, const QVariant &fallback) const override
{
const QDBusVariant &dv = config->value(key);
const QVariant &v = dv.variant();
return v.isValid() ? decodeQDBusArgument(v) : fallback;
}
virtual void setValue(const QString &key, const QVariant &value) override

View File

@ -48,6 +48,22 @@
"permissions": "readwrite",
"visibility": "public"
},
"array_map": {
"value": [{"key1": "value1", "key2": "value2"}],
"serial": 0,
"flags": ["global"],
"name": "array value type",
"permissions": "readwrite",
"visibility": "public"
},
"array_map_struct": {
"value": [{"key1": {"field1": "value1"}, "key2": "value2"}],
"serial": 0,
"flags": ["global"],
"name": "array value type",
"permissions": "readwrite",
"visibility": "public"
},
"map": {
"value": {"key1": "value1", "key2": "value2"},
"serial": 0,
@ -55,6 +71,22 @@
"name": "array value type",
"permissions": "readwrite",
"visibility": "public"
},
"map_array": {
"value": {"key1": ["value1"], "key2": ["value2"]},
"serial": 0,
"flags": ["global"],
"name": "array value type",
"permissions": "readwrite",
"visibility": "public"
},
"struct": {
"value": {"key1": "value1", "key2": "value2"},
"serial": 0,
"flags": ["global"],
"name": "array value type",
"permissions": "readwrite",
"visibility": "public"
}
}
}

View File

@ -142,6 +142,21 @@ TEST_F(ut_DConfigFile, setValueTypeCheck) {
ASSERT_FALSE(config.setValue("array", "value1", "test", userCache.get()));
ASSERT_EQ(config.value("array", userCache.get()).type(), type);
}
{
const auto type = config.value("array_map", userCache.get()).type();
QVariantList array;
QVariantMap map1;
map1["key1"] = "value1";
map1["key2"] = "value2";
array.append(map1);
ASSERT_EQ(config.value("array_map", userCache.get()).toList(), array);
ASSERT_TRUE(config.setValue("array_map", QVariantList(), "test", userCache.get()));
ASSERT_TRUE(config.setValue("array_map", array, "test", userCache.get()));
ASSERT_TRUE(config.setValue("array_map", QJsonDocument::fromJson("[]").toVariant(), "test", userCache.get()));
ASSERT_FALSE(config.setValue("array_map", "", "test", userCache.get()));
ASSERT_FALSE(config.setValue("array_map", "value1", "test", userCache.get()));
ASSERT_EQ(config.value("array_map", userCache.get()).type(), type);
}
{
const auto type = config.value("map", userCache.get()).type();
QVariantMap map;
@ -154,6 +169,19 @@ TEST_F(ut_DConfigFile, setValueTypeCheck) {
ASSERT_FALSE(config.setValue("map", "key1", "test", userCache.get()));
ASSERT_EQ(config.value("map", userCache.get()).type(), type);
}
{
const auto type = config.value("map_array", userCache.get()).type();
QVariantMap map;
map.insert("key1", QStringList{"value1"});
map.insert("key2", QStringList{"value2"});
ASSERT_EQ(config.value("map_array", userCache.get()).toMap(), map);
ASSERT_TRUE(config.setValue("map_array", QVariantMap(), "test", userCache.get()));
ASSERT_TRUE(config.setValue("map_array", map, "test", userCache.get()));
ASSERT_TRUE(config.setValue("map_array", QJsonDocument::fromJson("{}").toVariant(), "test", userCache.get()));
ASSERT_FALSE(config.setValue("map_array", "", "test", userCache.get()));
ASSERT_FALSE(config.setValue("map_array", "value1", "test", userCache.get()));
ASSERT_EQ(config.value("map_array", userCache.get()).type(), type);
}
}
TEST_F(ut_DConfigFile, fileIODevice) {