Case statement (expr.)

Hello Nix people,

I can’t find case statement in Nix lang/libraries and google doesn’t give me anything. Is there a case statement (expression / function)?

Or do I need to write something like this:

environment.etc."just/for/test".text =
  if (x == "a")
  then "hello"
  else
    if (x == "b")
    then "hi"
    else
      if (x == "c")
      then "ciao"
      else abort "x is invalid";

Thank you

The Nix language is very small, there is no case construct. Here is the language reference, see in particular language constructs.

If the value you’re switching over is guaranteed to be a string, you could abuse attribute sets by encoding the outcomes as attributes and use attr.${value} or default for conciseness.

2 Likes

I do what Fricklefthandwerk suggests and it works great!

environment.etc."just/for/test".text = {
  "a" = "hello";
  "b" = "hi";
  "c" = "ciao";
}." ${x}";

The beauty of this is that there’s no need for an explicit abort since a wrong value causes a build failure.

Yes, in my case it’s just a string. I’d prefer to use something like Enum / Symbol / Keyword, but as you correctly pointed out, Nix is simple so I need to use a string.

My assumption was that somebody created a lib / function to solve the ugly if-then-if-… But attr.set is enough! Thank you @fricklerhandwerk and @emmanuelrosa !

btw, if-else chains can look a little better if you put else if on the same line. For cases where x is not a simple string, this can more resemble a case statement

environment.etc."just/for/test".text =
  if x == "a" then
    "hello"
  else if x == "b" then
    "hi"
  else if x == "c" then
    "ciao"
  else
    abort "x is invalid";
4 Likes

Good point. Thank you.