In this example, a configuration parser is generated at compile-time.
Let's assume our program has a couple of configuration options,
summarized in a settings
int runs, port;
While writing a parser for this struct, wouldn't be difficult, we would have to
constantly update the parser, whenever we modify the
Hence, we are interested in writing a generic
parse function that can
read arbitrary configuration options. For simplicity,
parse will accept
a very simple format of
key1=value1,key2=value2 configuration options, but the same technique
can be used for any arbitrary configuration format. For many popular
configuration format, of course, readers already exist on the DUB registry.
Let's assume the user has "name=dlang,port=8080" as a configuration string.
We then directly split the configuration options by comma and call
parse with each
individual configuration setting.
After all configuration options have been parsed, the entire configuration
object is printed.
parse is where the real magic happens, but first we split the given configuration option
(e.g. "name=dlang") by "=" into key ("name") and value ("dlang").
The switch statement is executed with the parsed key, but the interesting bit is that
the switch cases have been statically generated.
c.tupleof returns a list of all members
(idx, name) format. The compiler detects that the
c.tupleof is known at compile-time
and will unroll the foreach loop at compile-time.
Conf.tupleof[idx].stringof will yield the individual members of the struct object
and generate a case statement for each member.
Equally, while being in the static loop, the individual members can be accessed by their index:
c.tupleof[idx] and thus we can assign the respective member the parsed value from the given
configuration string. Moreover,
dropOne is necessary, because the splitted range still
points at the key and thus
dropOne.front will return the second element.
to!(typeof(field)) will do the actual parsing of the input string
to the respective type of the member of the configuration struct.
Finally, as the foreach loop is unrolled at compile-time a
break would stop this loop.
However, after a configuration option has been successfully parsed, we don't want to jump
to the next case in the switch statement and thus a labeled break is used to break out the