summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/default.nix2
-rw-r--r--lib/lists.nix13
-rw-r--r--lib/options.nix2
-rwxr-xr-xlib/tests/modules.sh9
-rw-r--r--lib/tests/modules/declare-either.nix5
-rw-r--r--lib/tests/modules/declare-oneOf.nix9
-rw-r--r--lib/types.nix7
7 files changed, 45 insertions, 2 deletions
diff --git a/lib/default.nix b/lib/default.nix
index 3efaaf0f8f9e..18d2dfae1e18 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -71,7 +71,7 @@ let
zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
recursiveUpdate matchAttrs overrideExisting getOutput getBin
getLib getDev chooseDevOutputs zipWithNames zip;
- inherit (lists) singleton foldr fold foldl foldl' imap0 imap1
+ inherit (lists) singleton forEach foldr fold foldl foldl' imap0 imap1
concatMap flatten remove findSingle findFirst any all count
optional optionals toList range partition zipListsWith zipLists
reverseList listDfs toposort sort naturalSort compareLists take
diff --git a/lib/lists.nix b/lib/lists.nix
index 30d87ece6641..e4fcf959b60c 100644
--- a/lib/lists.nix
+++ b/lib/lists.nix
@@ -21,6 +21,19 @@ rec {
*/
singleton = x: [x];
+ /* Apply the function to each element in the list. Same as `map`, but arguments
+ flipped.
+
+ Type: forEach :: [a] -> (a -> b) -> [b]
+
+ Example:
+ forEach [ 1 2 ] (x:
+ toString x
+ )
+ => [ "1" "2" ]
+ */
+ forEach = xs: f: map f xs;
+
/* “right fold” a binary function `op` between successive elements of
`list` with `nul' as the starting value, i.e.,
`foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))`.
diff --git a/lib/options.nix b/lib/options.nix
index d2eae3ae3a98..e5c0631a5437 100644
--- a/lib/options.nix
+++ b/lib/options.nix
@@ -36,7 +36,7 @@ rec {
example ? null,
# String describing the option.
description ? null,
- # Related packages used in the manual (see `genRelatedPackages` in ../nixos/doc/manual/default.nix).
+ # Related packages used in the manual (see `genRelatedPackages` in ../nixos/lib/make-options-doc/default.nix).
relatedPackages ? null,
# Option type, providing type-checking and value merging.
type ? null,
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 e22bcd326c86..9c00656ab918 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: