On Wednesday, 28 September 2016 at 09:56:06 UTC, Marc Schütz
wrote:
You could solve the problem as you suggested by moving the
initializations into a constructor, but if your default values
are only ever IPs (i.e., no hostname resolution necessary), you
could also add an additional function that parse them without
calling into the C library, e.g.
struct BindAddress {
// ...
static BindAddress fromIP(string addr) {
// ...
}
}
struct Config {
// ...
BindAddress bindAddress =
BindAddress.fromIP("127.0.0.1");
}
You can try whether InternetAddress.parse() [1] works at
compile time, otherwise you would have to implement it by hand.
[1]
https://dlang.org/phobos/std_socket.html#.InternetAddress.parse
Indeed, getting rid of all static initializations in ConfigParams
did finally work!
Now I'm left with parameters' definitions without default values,
and an ugly constructor taking a long list of initialization
values as arguments and storing them in their respective private
members :/ .
struct ConfigParams {
BindAddresses bindAddresses;
BindPort bindHTTPPort;
BindPort bindHTTPSPort;
PosixPath configFile;
VerbosityLevel verbosityLevel;
this(BindAddresses bindAddresses,
BindPort bindHTTPPort = BindPort(8080),
BindPort bindHTTPSPort = BindPort(4430),
PosixPath configFile = PosixPath("/etc/ras/ras.conf.sdl"),
VerbosityLevel verbosityLevel = VerbosityLevel("quiet")) {
this.bindAddresses = bindAddresses;
this.bindHTTPPort = bindHTTPPort;
this.bindHTTPSPort = bindHTTPSPort;
this.configFile = configFile;
this.verbosityLevel = verbosityLevel;
}
}
Luckily I can set default values in constructor's signature
(except for the very first argument, otherwise I get a
deprecation warning for defaulting all arguments which does not
make sense), so I save some typing when calling it.
Any idea about how to improve this?
In the end everything boils down to not being able to use static
initializations with std.socket.parseAddress and friends. I don't
understand what prevents such function (in turn calling some
OS-level C function) from doing its job at compile time too.
Guess it's a very challanging thing to do at compile-time, or
should I open an issue with the std.socket lib developers?
By the way, out of despair, I also tried to validate addresses
myself using regular expressions but:
1) parsing generic IPv6 addresses is not trivial at all!
2) even skipping IPv6, I get similar compiler errors complaining
again about malloc not being able to compute some value at
compile time, so std.regex also conflicts with static
initializations somehow..
All in all, I can live with the current solution and move on.
Thank you a lot for your support Marc!