summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2022-01-24 01:07:32 +0100
committerRobert Hensing <robert@roberthensing.nl>2022-01-24 16:14:55 +0100
commitba3e91ed43c05a4a0984a6faa948949612fd113c (patch)
treed749b14475b3a7e735f23d8d876fcd30532c99b4 /lib
parentccb85a53b6a496984073227fd8c4d4c58889f421 (diff)
downloadnixpkgs-ba3e91ed43c05a4a0984a6faa948949612fd113c.tar
nixpkgs-ba3e91ed43c05a4a0984a6faa948949612fd113c.tar.gz
nixpkgs-ba3e91ed43c05a4a0984a6faa948949612fd113c.tar.bz2
nixpkgs-ba3e91ed43c05a4a0984a6faa948949612fd113c.tar.lz
nixpkgs-ba3e91ed43c05a4a0984a6faa948949612fd113c.tar.xz
nixpkgs-ba3e91ed43c05a4a0984a6faa948949612fd113c.tar.zst
nixpkgs-ba3e91ed43c05a4a0984a6faa948949612fd113c.zip
lib.types: Add unique like uniq, but custom errors
Couldn't extend types.uniq and it had a silly name anyway.
Now we can have better error messages.
Diffstat (limited to 'lib')
-rw-r--r--lib/default.nix5
-rw-r--r--lib/options.nix6
-rw-r--r--lib/types.nix15
3 files changed, 23 insertions, 3 deletions
diff --git a/lib/default.nix b/lib/default.nix
index 2dfe62e82a8..26842253880 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -122,8 +122,9 @@ let
       mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
       mkAliasOptionModule mkDerivedConfig doRename;
     inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions
-      mergeDefaultOption mergeOneOption mergeEqualOption getValues
-      getFiles optionAttrSetToDocList optionAttrSetToDocList'
+      mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption
+      getValues getFiles
+      optionAttrSetToDocList optionAttrSetToDocList'
       scrubOptionValue literalExpression literalExample literalDocBook
       showOption showFiles unknownModule mkOption;
     inherit (self.types) isType setType defaultTypeMerge defaultFunctor
diff --git a/lib/options.nix b/lib/options.nix
index 53001a3113f..44ec335545c 100644
--- a/lib/options.nix
+++ b/lib/options.nix
@@ -134,6 +134,12 @@ rec {
       throw "The unique option `${showOption loc}' is defined multiple times. Definition values:${showDefs defs}"
     else (head defs).value;
 
+  mergeUniqueOption = { message }: loc: defs:
+    if length defs == 1
+    then (head defs).value
+    else assert length defs > 1;
+      throw "The option `${showOption loc}' is defined multiple times.\n${message}\nDefinition values:${showDefs defs}";
+
   /* "Merge" option definitions by checking that they all have the same value. */
   mergeEqualOption = loc: defs:
     if defs == [] then abort "This case should never happen."
diff --git a/lib/types.nix b/lib/types.nix
index cc3ac5fdf6f..f2f9b2bca98 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -32,7 +32,6 @@ let
     last
     length
     tail
-    unique
     ;
   inherit (lib.attrsets)
     attrNames
@@ -48,6 +47,7 @@ let
     mergeDefaultOption
     mergeEqualOption
     mergeOneOption
+    mergeUniqueOption
     showFiles
     showOption
     ;
@@ -470,6 +470,18 @@ rec {
       nestedTypes.elemType = elemType;
     };
 
+    unique = { message }: type: mkOptionType rec {
+      name = "unique";
+      inherit (type) description check;
+      merge = mergeUniqueOption { inherit message; };
+      emptyValue = type.emptyValue;
+      getSubOptions = type.getSubOptions;
+      getSubModules = type.getSubModules;
+      substSubModules = m: uniq (type.substSubModules m);
+      functor = (defaultFunctor name) // { wrapped = type; };
+      nestedTypes.elemType = type;
+    };
+
     # Null or value of ...
     nullOr = elemType: mkOptionType rec {
       name = "nullOr";
@@ -599,6 +611,7 @@ rec {
     # A value from a set of allowed ones.
     enum = values:
       let
+        inherit (lib.lists) unique;
         show = v:
                if builtins.isString v then ''"${v}"''
           else if builtins.isInt v then builtins.toString v