summary refs log tree commit diff
path: root/pkgs/pkgs-lib/formats/libconfig/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/pkgs-lib/formats/libconfig/default.nix')
-rw-r--r--pkgs/pkgs-lib/formats/libconfig/default.nix121
1 files changed, 121 insertions, 0 deletions
diff --git a/pkgs/pkgs-lib/formats/libconfig/default.nix b/pkgs/pkgs-lib/formats/libconfig/default.nix
new file mode 100644
index 00000000000..7433a728535
--- /dev/null
+++ b/pkgs/pkgs-lib/formats/libconfig/default.nix
@@ -0,0 +1,121 @@
+{ lib
+, pkgs
+}:
+let
+  inherit (pkgs) buildPackages callPackage;
+  # Implementation notes:
+  #   Libconfig spec: https://hyperrealm.github.io/libconfig/libconfig_manual.html
+  #
+  #   Since libconfig does not allow setting names to start with an underscore,
+  #   this is used as a prefix for both special types and include directives.
+  #
+  #   The difference between 32bit and 64bit values became optional in libconfig
+  #   1.5, so we assume 64bit values for all numbers.
+
+  libconfig-generator = buildPackages.rustPlatform.buildRustPackage {
+    name = "libconfig-generator";
+    version = "0.1.0";
+    src = ./src;
+
+    passthru.updateScript = ./update.sh;
+
+    cargoLock.lockFile = ./src/Cargo.lock;
+  };
+
+  libconfig-validator = buildPackages.runCommandCC "libconfig-validator"
+    {
+      buildInputs = with buildPackages; [ libconfig ];
+    }
+    ''
+      mkdir -p "$out/bin"
+      $CC -lconfig -x c - -o "$out/bin/libconfig-validator" ${./validator.c}
+    '';
+in
+{
+  format = { generator ? libconfig-generator, validator ? libconfig-validator }: {
+    inherit generator;
+
+    type = with lib.types;
+      let
+        valueType = (oneOf [
+          bool
+          int
+          float
+          str
+          path
+          (attrsOf valueType)
+          (listOf valueType)
+        ]) // {
+          description = "libconfig value";
+        };
+      in
+      attrsOf valueType;
+
+    lib = {
+      mkHex = value: {
+        _type = "hex";
+        inherit value;
+      };
+      mkOctal = value: {
+        _type = "octal";
+        inherit value;
+      };
+      mkFloat = value: {
+        _type = "float";
+        inherit value;
+      };
+      mkArray = value: {
+        _type = "array";
+        inherit value;
+      };
+      mkList = value: {
+        _type = "list";
+        inherit value;
+      };
+    };
+
+    generate = name: value:
+      callPackage
+        ({
+          stdenvNoCC
+        , libconfig-generator
+        , libconfig-validator
+        , writeText
+        }: stdenvNoCC.mkDerivation rec {
+          inherit name;
+
+          dontUnpack = true;
+
+          json = builtins.toJSON value;
+          passAsFile = [ "json" ];
+
+          strictDeps = true;
+          nativeBuildInputs = [ libconfig-generator ];
+          buildPhase = ''
+            runHook preBuild
+            libconfig-generator < $jsonPath > output.cfg
+            runHook postBuild
+          '';
+
+          doCheck = true;
+          nativeCheckInputs = [ libconfig-validator ];
+          checkPhase = ''
+            runHook preCheck
+            libconfig-validator output.cfg
+            runHook postCheck
+          '';
+
+          installPhase = ''
+            runHook preInstall
+            mv output.cfg $out
+            runHook postInstall
+          '';
+
+          passthru.json = writeText "${name}.json" json;
+        })
+        {
+          libconfig-generator = generator;
+          libconfig-validator = validator;
+        };
+  };
+}