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!

Reply via email to