Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Nix coding pattern: merging two conditional lists created with mkIf

When given two lists each of which are conditional on basis of mkIf, how to merge those two lists (akin to mkMerge for sets)?
I have run into the following pattern several times now and I cannot seem to find documentation explaining how to idiomatically solve this.

Say you’re starting out with this snippet:

someConfigValue = mkIf (cfg.condition1) [ "some value 1" ];

Then you add another conditional value:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

someConfigValue = [
  (mkIf (cfg.condition1) [ "some value 1" ])
  (mkIf (cfg.condition2) [ "some value 2" ])
];

In the specific case at hand (trying to pass this to systemd.services.<name>.LoadCredential) I get the following error since the internal representation of the two mkIf values are sets:

error: cannot coerce a set to a string

Using mkMerge does not seem to work either (since it takes a list of sets and merges those sets).
I could replace the mkIfs with optionals and then concatenate the lists using ++, but that’s dumping all the module logic, so I’m not sure whether that’s the right choice here.

>Solution :

Ordinarily, I would use optionals for something like this.

If you really want to make it mergable, I think you can instead put whateverService.serviceConfig.LoadCredentials = [ "cred 1" ]; on one side of a merge and whateverService.serviceConfig.LoadCredentials = [ "cred 2" ]; on the other side, and the standard merging logic will put them in the same list.

This more or less results in just pushing someConfigValue in one level:

config = mkMerge [
  (mkIf (cfg.condition1) { someConfigValue = [ "some value 1" ]; })
  (mkIf (cfg.condition2) { someConfigValue = [ "some value 2" ]; })
];

Which is more or less how I tend to see mkIf used: It predicates whole sections of config at the top level, rather than individual values inside of config. Individual values tend to use things like optionals or optionalString.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading