summary refs log tree commit diff
path: root/pkgs/pkgs-lib/formats/libconfig/default.nix
blob: 7433a72853533fe9df009a7965a71e477ba31cdb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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;
        };
  };
}