mirror of https://github.com/adamdruppe/arsd.git
Implement function `parseIniMergedAA`
This commit is contained in:
parent
c300956cf7
commit
c38b37cce9
116
ini.d
116
ini.d
|
@ -703,6 +703,7 @@ private enum OperatingMode operatingMode(string) = (is(string == char[]))
|
|||
* [IniFilteredParser]
|
||||
* [parseIniDocument]
|
||||
* [parseIniAA]
|
||||
* [parseIniMergedAA]
|
||||
)
|
||||
+/
|
||||
struct IniParser(
|
||||
|
@ -1366,6 +1367,7 @@ struct IniParser(
|
|||
* [IniParser]
|
||||
* [parseIniDocument]
|
||||
* [parseIniAA]
|
||||
* [parseIniMergedAA]
|
||||
)
|
||||
+/
|
||||
struct IniFilteredParser(
|
||||
|
@ -2203,7 +2205,10 @@ struct IniDocument(string) if (isCompatibleString!string) {
|
|||
Parses an INI string into a document ("DOM").
|
||||
|
||||
See_also:
|
||||
[parseIniAA]
|
||||
$(LIST
|
||||
* [parseIniAA]
|
||||
* [parseIniMergedAA]
|
||||
)
|
||||
+/
|
||||
IniDocument!string parseIniDocument(IniDialect dialect = IniDialect.defaults, string)(string rawIni) @safe pure nothrow
|
||||
if (isCompatibleString!string) {
|
||||
|
@ -2359,7 +2364,10 @@ company = "Digital Mars"
|
|||
)
|
||||
|
||||
See_also:
|
||||
[parseIniDocument]
|
||||
$(LIST
|
||||
* [parseIniMergedAA]
|
||||
* [parseIniDocument]
|
||||
)
|
||||
+/
|
||||
string[immutable(char)[]][immutable(char)[]] parseIniAA(
|
||||
IniDialect dialect = IniDialect.defaults,
|
||||
|
@ -2590,6 +2598,110 @@ key = merged and overwritten
|
|||
assert(aa["2"]["key"] == "overwritten");
|
||||
}
|
||||
|
||||
/++
|
||||
Parses an INI string into a section-less associate array.
|
||||
All sections are merged.
|
||||
|
||||
$(LIST
|
||||
* Section names are discarded.
|
||||
* Duplicate keys cause values to get overwritten.
|
||||
)
|
||||
|
||||
See_also:
|
||||
$(LIST
|
||||
* [parseIniAA]
|
||||
* [parseIniDocument]
|
||||
)
|
||||
+/
|
||||
string[immutable(char)[]] parseIniMergedAA(
|
||||
IniDialect dialect = IniDialect.defaults,
|
||||
string,
|
||||
)(
|
||||
string rawIni,
|
||||
) @safe pure nothrow {
|
||||
static if (is(string == immutable(char)[])) {
|
||||
immutable(char)[] toString(string key) => key;
|
||||
} else {
|
||||
immutable(char)[] toString(string key) => key.idup;
|
||||
}
|
||||
|
||||
auto parser = IniParser!(dialect, string)(rawIni);
|
||||
|
||||
string[immutable(char)[]] section;
|
||||
|
||||
string keyName = null;
|
||||
string value = null;
|
||||
|
||||
void commitKeyValuePair(string nextKey) {
|
||||
if (keyName !is null) {
|
||||
section[toString(keyName)] = value;
|
||||
}
|
||||
|
||||
keyName = nextKey;
|
||||
value = null;
|
||||
}
|
||||
|
||||
void setValue(string nextValue) {
|
||||
value = nextValue;
|
||||
}
|
||||
|
||||
while (!parser.skipIrrelevant()) {
|
||||
switch (parser.front.type) with (TokenType) {
|
||||
|
||||
case key:
|
||||
commitKeyValuePair(parser.front.data);
|
||||
break;
|
||||
|
||||
case value:
|
||||
setValue(parser.front.data);
|
||||
break;
|
||||
|
||||
case sectionHeader:
|
||||
// nothing to do
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false, "Unexpected parsing error."); // TODO
|
||||
}
|
||||
|
||||
parser.popFront();
|
||||
}
|
||||
|
||||
commitKeyValuePair(null);
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
///
|
||||
@safe unittest {
|
||||
static immutable demoData = `
|
||||
key0 = value0
|
||||
|
||||
[1]
|
||||
key1 = value1
|
||||
key2 = other value
|
||||
|
||||
[2]
|
||||
key1 = value2
|
||||
key3 = yet another value`;
|
||||
|
||||
// Parse INI file into an associative array with merged sections.
|
||||
string[string] aa = parseIniMergedAA(demoData);
|
||||
|
||||
// As sections were merged, entries sharing the same key got overridden.
|
||||
// Hence, there are only four entries left.
|
||||
assert(aa.length == 4);
|
||||
|
||||
// The "key1" entry of the first section got overruled
|
||||
// by the "key1" entry of the second section that came later.
|
||||
assert(aa["key1"] == "value2");
|
||||
|
||||
// Entries with unique keys got through unaffected.
|
||||
assert(aa["key0"] == "value0");
|
||||
assert(aa["key2"] == "other value");
|
||||
assert(aa["key3"] == "yet another value");
|
||||
}
|
||||
|
||||
private void stringifyIniString(string, OutputRange)(string data, OutputRange output) {
|
||||
if (data is null) {
|
||||
output.put("\"\"");
|
||||
|
|
Loading…
Reference in New Issue