mirror of https://github.com/adamdruppe/arsd.git
Add function to parse INI into an AA
This commit is contained in:
parent
c5406b1634
commit
7d13f7cf22
103
ini.d
103
ini.d
|
@ -77,6 +77,7 @@ private enum LocationState {
|
||||||
See_also:
|
See_also:
|
||||||
$(LIST
|
$(LIST
|
||||||
* [parseIniDocument]
|
* [parseIniDocument]
|
||||||
|
* [parseIniAA]
|
||||||
)
|
)
|
||||||
+/
|
+/
|
||||||
struct IniParser(
|
struct IniParser(
|
||||||
|
@ -666,6 +667,9 @@ struct IniDocument(string) if (isCompatibleString!string) {
|
||||||
|
|
||||||
/++
|
/++
|
||||||
Parses an INI string into a document ("DOM").
|
Parses an INI string into a document ("DOM").
|
||||||
|
|
||||||
|
See_also:
|
||||||
|
[parseIniAA]
|
||||||
+/
|
+/
|
||||||
IniDocument!string parseIniDocument(IniDialect dialect = IniDialect.defaults, string)(string rawIni) @safe pure nothrow
|
IniDocument!string parseIniDocument(IniDialect dialect = IniDialect.defaults, string)(string rawIni) @safe pure nothrow
|
||||||
if (isCompatibleString!string) {
|
if (isCompatibleString!string) {
|
||||||
|
@ -719,7 +723,7 @@ if (isCompatibleString!string) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false, "Unexpected parsing error.");
|
assert(false, "Unexpected parsing error."); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.popFront();
|
parser.popFront();
|
||||||
|
@ -748,7 +752,7 @@ name = Walter Bright
|
||||||
company = "Digital Mars"
|
company = "Digital Mars"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Parse the document
|
// Parse the document.
|
||||||
auto doc = parseIniDocument(iniString);
|
auto doc = parseIniDocument(iniString);
|
||||||
|
|
||||||
version (none) // exclude from docs
|
version (none) // exclude from docs
|
||||||
|
@ -795,3 +799,98 @@ company = "Digital Mars"
|
||||||
// is mutable
|
// is mutable
|
||||||
static assert(is(typeof(doc.sections[0].items[0].value) == char[]));
|
static assert(is(typeof(doc.sections[0].items[0].value) == char[]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/++
|
||||||
|
Parses an INI string into an associate array.
|
||||||
|
|
||||||
|
See_also:
|
||||||
|
[parseIniDocument]
|
||||||
|
+/
|
||||||
|
string[string][string] parseIniAA(IniDialect dialect = IniDialect.defaults, string)(string rawIni) @safe pure nothrow {
|
||||||
|
// TODO: duplicate handling
|
||||||
|
auto parser = IniParser!(dialect, string)(rawIni);
|
||||||
|
|
||||||
|
string[string][string] document;
|
||||||
|
string[string] section;
|
||||||
|
|
||||||
|
string sectionName = null;
|
||||||
|
string keyName = null;
|
||||||
|
|
||||||
|
void commitSection() {
|
||||||
|
sectionName = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!parser.skipIrrelevant()) {
|
||||||
|
switch (parser.front.type) with (TokenType) {
|
||||||
|
|
||||||
|
case key:
|
||||||
|
keyName = parser.front.data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case value:
|
||||||
|
section[keyName] = parser.front.data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sectionHeader:
|
||||||
|
if ((sectionName !is null) || (section.length > 0)) {
|
||||||
|
document[sectionName] = section;
|
||||||
|
section = null;
|
||||||
|
}
|
||||||
|
sectionName = parser.front.data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(false, "Unexpected parsing error."); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.popFront();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sectionName !is null) || (section.length > 0)) {
|
||||||
|
document[sectionName] = section;
|
||||||
|
}
|
||||||
|
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
@safe unittest {
|
||||||
|
// INI document
|
||||||
|
static immutable string demoData = `; This is a comment.
|
||||||
|
|
||||||
|
Oachkatzlschwoaf = Seriously, try pronouncing this :P
|
||||||
|
|
||||||
|
[Section #1]
|
||||||
|
foo = bar
|
||||||
|
d = rocks
|
||||||
|
|
||||||
|
; Another comment
|
||||||
|
|
||||||
|
[Section No.2]
|
||||||
|
name = Walter Bright
|
||||||
|
company = "Digital Mars"
|
||||||
|
website = <https://digitalmars.com/>
|
||||||
|
;email = "noreply@example.org"
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Parse the document into an associative array.
|
||||||
|
auto aa = parseIniAA(demoData);
|
||||||
|
|
||||||
|
assert(aa.length == 3);
|
||||||
|
|
||||||
|
assert(aa[null].length == 1);
|
||||||
|
assert(aa[null]["Oachkatzlschwoaf"] == "Seriously, try pronouncing this :P");
|
||||||
|
|
||||||
|
assert(aa["Section #1"].length == 2);
|
||||||
|
assert(aa["Section #1"]["foo"] == "bar");
|
||||||
|
assert(aa["Section #1"]["d"] == "rocks");
|
||||||
|
|
||||||
|
string[string] section2 = aa["Section No.2"];
|
||||||
|
assert(section2.length == 3);
|
||||||
|
assert(section2["name"] == "Walter Bright");
|
||||||
|
assert(section2["company"] == "Digital Mars");
|
||||||
|
assert(section2["website"] == "<https://digitalmars.com/>");
|
||||||
|
|
||||||
|
// "email" is commented out
|
||||||
|
assert(!("email" in section2));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue