diff options
-rwxr-xr-x | lib/tests/modules.sh | 9 | ||||
-rw-r--r-- | lib/tests/modules/declare-either.nix | 5 | ||||
-rw-r--r-- | lib/tests/modules/declare-oneOf.nix | 9 | ||||
-rw-r--r-- | lib/types.nix | 7 | ||||
-rw-r--r-- | nixos/doc/manual/development/option-types.xml | 12 |
5 files changed, 42 insertions, 0 deletions
diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh index eadaa0521b35..cf344122cf4e 100755 --- a/lib/tests/modules.sh +++ b/lib/tests/modules.sh @@ -71,6 +71,15 @@ checkConfigError 'The option value .* in .* is not of type.*positive integer.*' checkConfigOutput "42" config.value ./declare-int-between-value.nix ./define-value-int-positive.nix checkConfigError 'The option value .* in .* is not of type.*between.*-21 and 43.*inclusive.*' config.value ./declare-int-between-value.nix ./define-value-int-negative.nix +# Check either types +# types.either +checkConfigOutput "42" config.value ./declare-either.nix ./define-value-int-positive.nix +checkConfigOutput "\"24\"" config.value ./declare-either.nix ./define-value-string.nix +# types.oneOf +checkConfigOutput "42" config.value ./declare-oneOf.nix ./define-value-int-positive.nix +checkConfigOutput "[ ]" config.value ./declare-oneOf.nix ./define-value-list.nix +checkConfigOutput "\"24\"" config.value ./declare-oneOf.nix ./define-value-string.nix + # Check mkForce without submodules. set -- config.enable ./declare-enable.nix ./define-enable.nix checkConfigOutput "true" "$@" diff --git a/lib/tests/modules/declare-either.nix b/lib/tests/modules/declare-either.nix new file mode 100644 index 000000000000..5a0fa978a138 --- /dev/null +++ b/lib/tests/modules/declare-either.nix @@ -0,0 +1,5 @@ +{ lib, ... }: { + options.value = lib.mkOption { + type = lib.types.either lib.types.int lib.types.str; + }; +} diff --git a/lib/tests/modules/declare-oneOf.nix b/lib/tests/modules/declare-oneOf.nix new file mode 100644 index 000000000000..df092a14f81e --- /dev/null +++ b/lib/tests/modules/declare-oneOf.nix @@ -0,0 +1,9 @@ +{ lib, ... }: { + options.value = lib.mkOption { + type = lib.types.oneOf [ + lib.types.int + (lib.types.listOf lib.types.int) + lib.types.str + ]; + }; +} diff --git a/lib/types.nix b/lib/types.nix index b225119299da..5612e999177e 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -443,6 +443,13 @@ rec { functor = (defaultFunctor name) // { wrapped = [ t1 t2 ]; }; }; + # Any of the types in the given list + oneOf = ts: + let + head' = if ts == [] then throw "types.oneOf needs to get at least one type in its argument" else head ts; + tail' = tail ts; + in foldl' either head' tail'; + # Either value of type `finalType` or `coercedType`, the latter is # converted to `finalType` using `coerceFunc`. coercedTo = coercedType: coerceFunc: finalType: diff --git a/nixos/doc/manual/development/option-types.xml b/nixos/doc/manual/development/option-types.xml index 069cc36573d8..8fcbb627342b 100644 --- a/nixos/doc/manual/development/option-types.xml +++ b/nixos/doc/manual/development/option-types.xml @@ -348,6 +348,18 @@ </varlistentry> <varlistentry> <term> + <varname>types.oneOf</varname> [ <replaceable>t1</replaceable> <replaceable>t2</replaceable> ... ] + </term> + <listitem> + <para> + Type <replaceable>t1</replaceable> or type <replaceable>t2</replaceable> and so forth, + e.g. <literal>with types; oneOf [ int str bool ]</literal>. Multiple definitions + cannot be merged. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> <varname>types.coercedTo</varname> <replaceable>from</replaceable> <replaceable>f</replaceable> <replaceable>to</replaceable> </term> <listitem> |