[libcalamares] Add nested (dotted) key lookup for GS
This commit is contained in:
parent
3f4d2c8040
commit
8a095504c4
@ -190,4 +190,55 @@ GlobalStorage::loadYaml( const QString& filename )
|
||||
return false;
|
||||
}
|
||||
|
||||
///@brief Implementation for recursively looking up dotted selector parts.
|
||||
static QVariant
|
||||
lookup( const QStringList& nestedKey, int index, const QVariant& v, bool& ok )
|
||||
{
|
||||
if ( !v.canConvert< QVariantMap >() )
|
||||
{
|
||||
// Mismatch: we're still looking for keys, but v is not a submap
|
||||
ok = false;
|
||||
return {};
|
||||
}
|
||||
if ( index >= nestedKey.length() )
|
||||
{
|
||||
cError() << "Recursion error looking at index" << index << "of" << nestedKey;
|
||||
ok = false;
|
||||
return {};
|
||||
}
|
||||
|
||||
const QVariantMap map = v.toMap();
|
||||
const QString& key = nestedKey.at( index );
|
||||
if ( index == nestedKey.length() - 1 )
|
||||
{
|
||||
ok = map.contains( key );
|
||||
return ok ? map.value( key ) : QVariant();
|
||||
}
|
||||
else
|
||||
{
|
||||
return lookup( nestedKey, index + 1, map.value( key ), ok );
|
||||
}
|
||||
}
|
||||
|
||||
QVariant
|
||||
lookup( const GlobalStorage* storage, const QString& nestedKey, bool& ok )
|
||||
{
|
||||
ok = false;
|
||||
if ( !storage )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if ( nestedKey.contains( '.' ) )
|
||||
{
|
||||
QStringList steps = nestedKey.split( '.' );
|
||||
return lookup( steps, 1, storage->value( steps.first() ), ok );
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = storage->contains( nestedKey );
|
||||
return ok ? storage->value( nestedKey ) : QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Calamares
|
||||
|
@ -167,6 +167,26 @@ private:
|
||||
mutable QMutex m_mutex;
|
||||
};
|
||||
|
||||
|
||||
/** @brief Gets a value from the store
|
||||
*
|
||||
* When @p nestedKey contains no '.' characters, equivalent
|
||||
* to `gs->value(nestedKey)`. Otherwise recursively looks up
|
||||
* the '.'-separated parts of @p nestedKey in successive sub-maps
|
||||
* of the store, returning the value in the innermost one.
|
||||
*
|
||||
* Example: `lookup(gs, "branding.name")` finds the value of the
|
||||
* 'name' key in the 'branding' submap of the store.
|
||||
*
|
||||
* Sets @p ok to @c true if a value was found. Returns the value
|
||||
* as a variant. If no value is found (e.g. the key is missing
|
||||
* or some prefix submap is missing) sets @p ok to @c false
|
||||
* and returns an invalid QVariant.
|
||||
*
|
||||
* @see GlobalStorage::value
|
||||
*/
|
||||
DLLEXPORT QVariant lookup( const GlobalStorage* gs, const QString& nestedKey, bool& ok );
|
||||
|
||||
} // namespace Calamares
|
||||
|
||||
#endif // CALAMARES_GLOBALSTORAGE_H
|
||||
|
@ -32,6 +32,7 @@ private Q_SLOTS:
|
||||
void testGSLoadSave();
|
||||
void testGSLoadSave2();
|
||||
void testGSLoadSaveYAMLStringList();
|
||||
void testGSNestedLookup();
|
||||
|
||||
void testInstanceKey();
|
||||
void testInstanceDescription();
|
||||
@ -177,6 +178,38 @@ TestLibCalamares::testGSLoadSaveYAMLStringList()
|
||||
QCOMPARE( gs2.value( "dwarfs" ).toString(), QStringLiteral( "<QStringList>" ) ); // .. they're gone
|
||||
}
|
||||
|
||||
void
|
||||
TestLibCalamares::testGSNestedLookup()
|
||||
{
|
||||
Logger::setupLogLevel( Logger::LOGDEBUG );
|
||||
|
||||
const QString filename( BUILD_AS_TEST "/testdata/yaml-list.conf" );
|
||||
QVERIFY2( QFile::exists( filename ), qPrintable( filename ) );
|
||||
|
||||
Calamares::GlobalStorage gs2;
|
||||
QVERIFY( gs2.loadYaml( filename ) );
|
||||
|
||||
bool ok = false;
|
||||
const auto v0 = Calamares::lookup( &gs2, "horse.colors.neck", ok );
|
||||
QVERIFY( ok );
|
||||
QVERIFY( v0.canConvert< QString >() );
|
||||
QCOMPARE( v0.toString(), QStringLiteral( "roan" ) );
|
||||
const auto v1 = Calamares::lookup( &gs2, "horse.colors.nose", ok );
|
||||
QVERIFY( !ok );
|
||||
QVERIFY( !v1.isValid() );
|
||||
const auto v2 = Calamares::lookup( &gs2, "cow.colors.nose", ok );
|
||||
QVERIFY( !ok );
|
||||
QVERIFY( !v2.isValid() );
|
||||
const auto v3 = Calamares::lookup( &gs2, "dwarfs", ok );
|
||||
QVERIFY( ok );
|
||||
QVERIFY( v3.canConvert< QVariantList >() ); // because it's a list-valued thing
|
||||
const auto v4 = Calamares::lookup( &gs2, "dwarfs.sleepy", ok );
|
||||
QVERIFY( !ok ); // Sleepy is a value in the list of dwarfs, not a key
|
||||
const auto v5 = Calamares::lookup( &gs2, "derp", ok );
|
||||
QVERIFY( ok );
|
||||
QCOMPARE( v5.toInt(), 17 );
|
||||
}
|
||||
|
||||
void
|
||||
TestLibCalamares::testInstanceKey()
|
||||
{
|
||||
|
6
src/libcalamares/testdata/yaml-list.conf
vendored
6
src/libcalamares/testdata/yaml-list.conf
vendored
@ -9,3 +9,9 @@
|
||||
- "sleepy"
|
||||
- "sneezy"
|
||||
- "doc"
|
||||
horse:
|
||||
hoofs: 4
|
||||
colors:
|
||||
mane: black
|
||||
neck: roan
|
||||
tail: white
|
||||
|
Loading…
Reference in New Issue
Block a user