about summary refs log tree commit diff
path: root/pkgs/pkgs-lib/formats.nix
diff options
context:
space:
mode:
authorAaron Andersen <aaron@fosslib.net>2022-07-01 00:11:34 +0200
committerGitHub <noreply@github.com>2022-07-01 00:11:34 +0200
commit1cab3622065a8c0a05707e66949ace02c1aee41a (patch)
treef963b1730fc255911be4abacce2d769235004e2a /pkgs/pkgs-lib/formats.nix
parent6d91af447511045056eb2936f66c943b34774e0f (diff)
parent0d2842a4353f55eb2fc79ec7ad6490c1f5a2b88e (diff)
Merge pull request #178365 from fgaz/lib.formats.keyValue
lib.formats.keyValue: init
Diffstat (limited to 'pkgs/pkgs-lib/formats.nix')
-rw-r--r--pkgs/pkgs-lib/formats.nix49
1 files changed, 49 insertions, 0 deletions
diff --git a/pkgs/pkgs-lib/formats.nix b/pkgs/pkgs-lib/formats.nix
index cdcbd3663422a..13aada3681f7c 100644
--- a/pkgs/pkgs-lib/formats.nix
+++ b/pkgs/pkgs-lib/formats.nix
@@ -135,6 +135,55 @@ rec {
 
   };
 
+  keyValue = {
+    # Represents lists as duplicate keys
+    listsAsDuplicateKeys ? false,
+    # Alternative to listsAsDuplicateKeys, converts list to non-list
+    # listToValue :: [Atom] -> Atom
+    listToValue ? null,
+    ...
+    }@args:
+    assert !listsAsDuplicateKeys || listToValue == null;
+    {
+
+    type = with lib.types; let
+
+      singleAtom = nullOr (oneOf [
+        bool
+        int
+        float
+        str
+      ]) // {
+        description = "atom (null, bool, int, float or string)";
+      };
+
+      atom =
+        if listsAsDuplicateKeys then
+          coercedTo singleAtom lib.singleton (listOf singleAtom) // {
+            description = singleAtom.description + " or a list of them for duplicate keys";
+          }
+        else if listToValue != null then
+          coercedTo singleAtom lib.singleton (nonEmptyListOf singleAtom) // {
+            description = singleAtom.description + " or a non-empty list of them";
+          }
+        else
+          singleAtom;
+
+    in attrsOf atom;
+
+    generate = name: value:
+      let
+        transformedValue =
+          if listToValue != null
+          then
+            lib.mapAttrs (key: val:
+              if lib.isList val then listToValue val else val
+            ) value
+          else value;
+      in pkgs.writeText name (lib.generators.toKeyValue (removeAttrs args ["listToValue"]) transformedValue);
+
+  };
+
   gitIni = { listsAsDuplicateKeys ? false, ... }@args: {
 
     type = with lib.types; let