diff options
Diffstat (limited to 'lib/types.nix')
-rw-r--r-- | lib/types.nix | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/lib/types.nix b/lib/types.nix index 7cfd8e606d73..dec9d82d6088 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -22,18 +22,18 @@ rec { # name (name of the type) # check (check the config value) # merge (default merge function) - # docPath (path concatenated to the option name contained in the option set) + # getSubOptions (returns sub-options for manual generation) isOptionType = isType "option-type"; mkOptionType = { name , check ? (x: true) , merge ? mergeDefaultOption , merge' ? args: merge - , docPath ? lib.id + , getSubOptions ? prefix: {} }: { _type = "option-type"; - inherit name check merge merge' docPath; + inherit name check merge merge' getSubOptions; }; @@ -99,14 +99,14 @@ rec { name = "list of ${elemType.name}s"; check = value: isList value && all elemType.check value; merge = defs: map (def: elemType.merge [def]) (concatLists defs); - docPath = path: elemType.docPath (path + ".*"); + getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*"]); }; attrsOf = elemType: mkOptionType { name = "attribute set of ${elemType.name}s"; check = x: isAttrs x && all elemType.check (lib.attrValues x); merge = lib.zipAttrsWith (name: elemType.merge' { inherit name; }); - docPath = path: elemType.docPath (path + ".<name>"); + getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name>"]); }; # List or attribute set of ... @@ -129,26 +129,27 @@ rec { else if isAttrs x then attrOnly.check x else false; merge = defs: attrOnly.merge (imap convertIfList defs); - docPath = path: elemType.docPath (path + ".<name?>"); + getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name?>"]); }; uniq = elemType: mkOptionType { - inherit (elemType) name check docPath; + inherit (elemType) name check; merge = list: if length list == 1 then head list else throw "Multiple definitions of ${elemType.name}. Only one is allowed for this option."; + getSubOptions = elemType.getSubOptions; }; none = elemType: mkOptionType { - inherit (elemType) name check docPath; + inherit (elemType) name check; merge = list: throw "No definitions are allowed for this option."; + getSubOptions = elemType.getSubOptions; }; nullOr = elemType: mkOptionType { - inherit (elemType) docPath; name = "null or ${elemType.name}"; check = x: builtins.isNull x || elemType.check x; merge = defs: @@ -156,6 +157,7 @@ rec { else if any isNull defs then throw "Some but not all values are null." else elemType.merge defs; + getSubOptions = elemType.getSubOptions; }; functionTo = elemType: mkOptionType { @@ -163,19 +165,26 @@ rec { check = builtins.isFunction; merge = fns: args: elemType.merge (map (fn: fn args) fns); - }; - - submodule = opts: mkOptionType rec { - name = "submodule"; - check = x: isAttrs x || builtins.isFunction x; - # FIXME: make error messages include the parent attrpath. - merge = merge' {}; - merge' = args: defs: - let - coerce = def: if builtins.isFunction def then def else { config = def; }; - modules = (toList opts) ++ map coerce defs; - in (evalModules modules args).config; - }; + getSubOptions = elemType.getSubOptions; + }; + + submodule = opts: + let opts' = toList opts; in + mkOptionType rec { + name = "submodule"; + check = x: isAttrs x || builtins.isFunction x; + # FIXME: make error messages include the parent attrpath. + merge = merge' {}; + merge' = args: defs: + let + coerce = def: if builtins.isFunction def then def else { config = def; }; + modules = opts' ++ map coerce defs; + in (evalModules modules args).config; + getSubOptions = prefix: (evalModules' prefix opts' + # FIXME: hack to get shit to evaluate. + { name = ""; } + ).options; + }; # Obsolete alternative to configOf. It takes its option # declarations from the ‘options’ attribute of containing option |