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";
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.
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";
Please check String interpolation - Nix Reference Manual on the details, which was added since my last post here. Feel free to ask questions if that leaves something unclear and I can improve that page.
For a more specific error message you could use throw in the fallback case:
.${value} or (aka attribute selection) binds stronger than throw "..." (aka function application), see Operators - Nix Reference Manual (also written by @fricklerhandwerk), so this needs some parenthesis:
attrs.${value} or (throw "not supported: ${value}")
No, that’s not possible. As opposed to paths and attribute names, which are interchangeable with strings (literally: { "foo" = 1; } is legal), function names are symbols.