about summary refs log tree commit diff
path: root/pkgs/pkgs-lib/formats.nix
diff options
context:
space:
mode:
authorFrancesco Gazzetta <fgaz@fgaz.me>2021-12-14 22:38:28 +0100
committerFrancesco Gazzetta <fgaz@fgaz.me>2022-06-18 21:11:14 +0200
commit3ff9245301a38b3e2cd344e3296e724b9dc95e40 (patch)
treecaa825c40cf518cece771297ecac16f9c78358cb /pkgs/pkgs-lib/formats.nix
parent6616de389ed55fba6eeba60377fc04732d5a207c (diff)
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 fc52128a7e999..e67a9b6d2935c 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