Skip to content

Commit

Permalink
lib/types: init taggedSubmodules
Browse files Browse the repository at this point in the history
  • Loading branch information
Lassulus committed Sep 12, 2023
1 parent 7163f12 commit eb312d4
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
17 changes: 17 additions & 0 deletions lib/types.nix
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,23 @@ rec {
in mergedOption.type;
};

# A type that is one of several submodules, similiar to types.oneOf but is usable inside attrsOf or listOf
# submodules need an option with a type str which is used to find the corresponding type
taggedSubmodules =
{ types
, specialArgs ? {}
}: mkOptionType rec {
name = "taggedSubmodules";
description = "one of ${concatStringsSep "," (attrNames types)}";
check = x: if x ? type then types.${x.type}.check x else throw "No type option set in:\n${lib.generators.toPretty {} x}";
merge = loc: foldl'
(res: def: types.${def.value.type}.merge loc [
(lib.recursiveUpdate { value._module.args = specialArgs; } def)
])
{ };
nestedTypes = types;
};

submoduleWith =
{ modules
, specialArgs ? {}
Expand Down
51 changes: 51 additions & 0 deletions nixos/doc/manual/development/option-types.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,57 @@ Submodules are detailed in [Submodule](#section-option-types-submodule).
options. This is equivalent to
`types.submoduleWith { modules = toList o; shorthandOnlyDefinesConfig = true; }`.

`types.taggedSubmodules` { *`types`*, *`specialArgs`* ? {} }

: Like `types.oneOf`, but takes an attrsSet of submodule in types. Those need to have a type option
which is used to find the correct submodule.

::: {#ex-tagged-submodules .example}
### Tagged submodules
```nix
let
submoduleA = submodule {
options = {
type = mkOption {
type = str;
};
foo = mkOption {
type = int;
};
};
};
submoduleB = submodule {
options = {
type = mkOption {
type = str;
};
bar = mkOption {
type = int;
};
};
};
in
options.mod = mkOption {
type = attrsOf (taggedSubmodule {
types = {
a = submoduleA;
b = submoduleB;
};
});
};
config.mod = {
someA = {
type = "a";
foo = 123;
};
someB = {
type = "b";
foo = 456;
};
};
```
:::

`types.submoduleWith` { *`modules`*, *`specialArgs`* ? {}, *`shorthandOnlyDefinesConfig`* ? false }

: Like `types.submodule`, but more flexible and with better defaults.
Expand Down

0 comments on commit eb312d4

Please sign in to comment.