summary refs log tree commit diff
path: root/lib/types.nix
diff options
context:
space:
mode:
authorSilvan Mosberger <contact@infinisil.com>2021-12-08 19:02:29 +0100
committerSilvan Mosberger <contact@infinisil.com>2022-03-01 19:31:00 +0100
commit5cbeddfde486ca5524baeaf3da6e8944075cf463 (patch)
treed529522033bcfdc0272fba08e8e3fe1897dbe4e0 /lib/types.nix
parent891e65b0fa1b7c75c42b5404934307f64828e428 (diff)
downloadnixpkgs-5cbeddfde486ca5524baeaf3da6e8944075cf463.tar
nixpkgs-5cbeddfde486ca5524baeaf3da6e8944075cf463.tar.gz
nixpkgs-5cbeddfde486ca5524baeaf3da6e8944075cf463.tar.bz2
nixpkgs-5cbeddfde486ca5524baeaf3da6e8944075cf463.tar.lz
nixpkgs-5cbeddfde486ca5524baeaf3da6e8944075cf463.tar.xz
nixpkgs-5cbeddfde486ca5524baeaf3da6e8944075cf463.tar.zst
nixpkgs-5cbeddfde486ca5524baeaf3da6e8944075cf463.zip
lib.types: Introduce `types.optionType`
This type correctly merges multiple option types together while also
annotating them with file information. In a future commit this will be
used for `_module.freeformType`
Diffstat (limited to 'lib/types.nix')
-rw-r--r--lib/types.nix31
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/types.nix b/lib/types.nix
index c47a35cd0d6..acc7eac104e 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -61,7 +61,11 @@ let
     boolToString
     ;
 
-  inherit (lib.modules) mergeDefinitions;
+  inherit (lib.modules)
+    mergeDefinitions
+    fixupOptionType
+    mergeOptionDecls
+    ;
   outer_types =
 rec {
   isType = type: x: (x._type or "") == type;
@@ -525,6 +529,31 @@ rec {
       modules = toList modules;
     };
 
+    # The type of a type!
+    optionType = mkOptionType {
+      name = "optionType";
+      description = "optionType";
+      check = value: value._type or null == "option-type";
+      merge = loc: defs:
+        let
+          # Prepares the type definitions for mergeOptionDecls, which
+          # annotates submodules types with file locations
+          optionModules = map ({ value, file }:
+            {
+              _file = file;
+              # There's no way to merge types directly from the module system,
+              # but we can cheat a bit by just declaring an option with the type
+              options = lib.mkOption {
+                type = value;
+              };
+            }
+          ) defs;
+          # Merges all the types into a single one, including submodule merging.
+          # This also propagates file information to all submodules
+          mergedOption = fixupOptionType loc (mergeOptionDecls loc optionModules);
+        in mergedOption.type;
+    };
+
     submoduleWith =
       { modules
       , specialArgs ? {}