Function readIniLike

Read ini-like file entries via the set of callbacks. Callbacks can be null, but basic format validation is still run in this case.

void readIniLike(IniLikeReader) (
  IniLikeReader reader,
  scope void delegate(string) onLeadingComment = null,
  scope ActionOnGroup delegate(string) onGroup = null,
  scope void delegate(string, string, string) onKeyValue = null,
  scope void delegate(string, string) onCommentInGroup = null,
  string fileName = null
);

Parameters

NameDescription
reader IniLikeReader object as returned by iniLikeRangeReader or similar function.
onLeadingComment Delegate to call after leading comment (i.e. the one before any group) is read. The parameter is either comment of empty line.
onGroup Delegate to call after group header is read. The parameter is group name (without brackets). Must return ActionOnGroup. Providing the null callback is equal to providing the callback that always returns ActionOnGroup.skip.
onKeyValue Delegate to call after key-value entry is read and parsed. Parameters are key, value and the current group name. It's recommended to throw inilike.exceptions.IniLikeEntryException from this function in case if the key-value pair is invalid.
onCommentInGroup Delegate to call after comment or empty line is read inside group section. The first parameter is either comment or empty line. The second parameter is the current group name.
fileName Optional file name parameter to use in thrown exceptions.

Throws

IniLikeReadException if error occured while parsing. Any exception thrown by callbacks will be transformed to IniLikeReadException.

Example

string contents =
`# Comment
[ToSkip]
KeyInSkippedGroup=Value
[ToProceed]
KeyInNormalGroup=Value2
# Comment2
[ToStopAfter]
KeyInStopAfterGroup=Value3
# Comment3
[NeverGetThere]
KeyNeverGetThere=Value4
# Comment4`;
auto onLeadingComment = delegate void(string line) {
    assert(line == "# Comment");
};
auto onGroup = delegate ActionOnGroup(string groupName) {
    if (groupName == "ToSkip") {
        return ActionOnGroup.skip;
    } else if (groupName == "ToStopAfter") {
        return ActionOnGroup.stopAfter;
    } else {
        return ActionOnGroup.proceed;
    }
};
auto onKeyValue = delegate void(string key, string value, string groupName) {
    assert((groupName == "ToProceed" && key == "KeyInNormalGroup" && value == "Value2") ||
        (groupName == "ToStopAfter" && key == "KeyInStopAfterGroup" && value == "Value3"));
};
auto onCommentInGroup = delegate void(string line, string groupName) {
    assert((groupName == "ToProceed" && line == "# Comment2") || (groupName == "ToStopAfter" && line == "# Comment3"));
};
readIniLike(iniLikeStringReader(contents), onLeadingComment, onGroup, onKeyValue, onCommentInGroup);
readIniLike(iniLikeStringReader(contents));

import std.exception : assertThrown;
contents =
`Not a comment
[Group name]
Key=Value`;
assertThrown!IniLikeReadException(readIniLike(iniLikeStringReader(contents)));