110 lines
2.7 KiB
D
110 lines
2.7 KiB
D
module substitution;
|
|
|
|
import std.file : slurp;
|
|
import std.meta : AliasSeq;
|
|
import std.traits : Parameters;
|
|
|
|
version (unittest)
|
|
{
|
|
import unit_threaded;
|
|
}
|
|
|
|
public:
|
|
|
|
/***********************************
|
|
* Loads a substitution dictonary from a file.
|
|
*/
|
|
|
|
void loadSubstitutionFile(alias slurpFun = slurp)(string fileName)
|
|
if (is(Parameters!(slurpFun!(string, string)) == AliasSeq!(string, const char[])))
|
|
{
|
|
import std.algorithm.iteration : each;
|
|
|
|
map = (string[string]).init;
|
|
slurpFun!(string, string)(fileName, `"%s" = "%s"`).each!(pair => map[pair[0]] = pair[1]);
|
|
}
|
|
|
|
///
|
|
@safe unittest
|
|
{
|
|
import std.typecons : Tuple, tuple;
|
|
|
|
static Tuple!(string, string)[] mockSlurpEmpty(Type1, Type2)(string filename, in char[] format)
|
|
{
|
|
return [];
|
|
}
|
|
|
|
loadSubstitutionFile!mockSlurpEmpty("");
|
|
map.length.shouldEqual(0);
|
|
|
|
static Tuple!(string, string)[] mockSlurpEmptyEntry(Type1, Type2)(string filename,
|
|
in char[] format)
|
|
{
|
|
return [tuple("", "")];
|
|
}
|
|
|
|
loadSubstitutionFile!mockSlurpEmptyEntry("");
|
|
"".shouldBeIn(map);
|
|
map.length.shouldEqual(1);
|
|
map[""].shouldEqual("");
|
|
|
|
static Tuple!(string, string)[] mockSlurpSingleEntry(Type1, Type2)(string filename,
|
|
in char[] format)
|
|
{
|
|
return [tuple("foo", "bar")];
|
|
}
|
|
|
|
loadSubstitutionFile!mockSlurpSingleEntry("");
|
|
"foo".shouldBeIn(map);
|
|
map.length.shouldEqual(1);
|
|
map["foo"].shouldEqual("bar");
|
|
|
|
static Tuple!(string, string)[] mockSlurpMultipleEntries(Type1, Type2)(
|
|
string filename, in char[] format)
|
|
{
|
|
return [tuple("", ""), tuple("0", "1"), tuple("Text in", "wird durch diesen ersetzt")];
|
|
}
|
|
|
|
loadSubstitutionFile!mockSlurpMultipleEntries("");
|
|
"".shouldBeIn(map);
|
|
"0".shouldBeIn(map);
|
|
"Text in".shouldBeIn(map);
|
|
map.length.shouldEqual(3);
|
|
map[""].shouldEqual("");
|
|
map["0"].shouldEqual("1");
|
|
map["Text in"].shouldEqual("wird durch diesen ersetzt");
|
|
}
|
|
|
|
/***********************************
|
|
* Substitutes a string with its corresponding replacement, if one is available.
|
|
* Otherwise just returns the original string.
|
|
*/
|
|
|
|
auto substitute(string s) @safe nothrow
|
|
{
|
|
return s in map ? map[s] : s;
|
|
}
|
|
|
|
///
|
|
@safe unittest
|
|
{
|
|
map[""] = "";
|
|
"".substitute.shouldEqual("");
|
|
|
|
map["a"] = "b";
|
|
"a".substitute.shouldEqual("b");
|
|
|
|
map["Regensburg Danziger Freiheit"] = "Danziger Freiheit";
|
|
"Regensburg Danziger Freiheit".substitute.shouldEqual("Danziger Freiheit");
|
|
|
|
map["Regensburg Danziger Freiheit"] = "Anderer Test";
|
|
"Regensburg Danziger Freiheit".substitute.shouldEqual("Anderer Test");
|
|
|
|
"z".substitute.shouldEqual("z");
|
|
|
|
"Regensburg Hauptbahnhof".substitute.shouldEqual("Regensburg Hauptbahnhof");
|
|
}
|
|
|
|
private:
|
|
|
|
string[string] map;
|