How do I represent a sum type of submodules in the NixOS module system

I’m trying to put together a NixOS module for Glance, and one of the types in their configuration is a list of widgets that can be one of the multiple pre-defined ones. I know how to write individual types.submodule for each of the widgets, but I’m struggling with encoding the notion of “this option is a list and the valid types are one of these widgets”.

Here is what I have so far: msfjarvis/dotfiles

This is the currently incorrect part that I’m trying to fix.

2 Likes

I can’t quite remember how types fold, and I’m not home to test how they do, but I believe it should be lib.types.listOf lib.types.oneOf [ rssWidgetType videosWidgetType hackerNewsWidgetType ].

2 Likes

That doesn’t seem to work, this is the error I get with that change:

       error: attempt to call something which is not a function but a set: { _type = "option-type"; check = «primop isList»; deprecationMessage = null; description = «thunk»; descriptionClass = "composite"; emptyValue = «thunk»; functor = «thunk»; getSubModules = «thunk»; getSubOptions = «thunk»; merge = «thunk»; «4 attributes elided» }
       at /nix/store/nczwf2d2ch60rq6dyjzn2295l3dmlz6d-py37r8q7kd15zs0kijnmgycbkfg62hqf-source/modules/nixos/glance/default.nix:96:16:
           95|       widgets = mkOption {
           96|         type = types.listOf types.oneOf [
             |                ^
           97|           rssWidgetType

ah, parenthesis are needed cause of type folding indeed. lib.types.listOf (lib.types.oneOf [ rssWidgetType videosWidgetType hackerNewsWidgetType ])

2 Likes

The only issue I can forsee is that once you have the first type passed in the array any other types will fail due to type eval. See Lazy evaluation of types of `listOf oneOf` causes option missing errors when inner types are submodules · Issue #158503 · NixOS/nixpkgs · GitHub, I’m unsure if this was ever fixed.

Oh I feel silly for not trying parentheses. Thanks for the link to the bug as well!

Glad I could be of help