lol
1{pkgs, lib}: {
2 # Format for defining configuration of some PHP services, that use "include 'config.php';" approach.
3 format = {finalVariable ? null}: let
4 toPHP = value: {
5 "null" = "null";
6 "bool" = if value then "true" else "false";
7 "int" = toString value;
8 "float" = toString value;
9 "string" = string value;
10 "set" = attrs value;
11 "list" = list value;
12 }
13 .${builtins.typeOf value} or
14 (abort "should never happen: unknown value type ${builtins.typeOf value}");
15
16 # https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.single
17 escapeSingleQuotedString = lib.escape [ "'" "\\" ];
18 string = value: "'${escapeSingleQuotedString value}'";
19
20 listContent = values: lib.concatStringsSep ", " (map toPHP values);
21 list = values: "[" + (listContent values) + "]";
22
23 attrsContent = values: lib.pipe values [
24 (lib.mapAttrsToList (k: v: "${toPHP k} => ${toPHP v}"))
25 (lib.concatStringsSep ", ")
26 ];
27 attrs = set:
28 if set ? _phpType then specialType set
29 else
30 "[" + attrsContent set + "]";
31
32 mixedArray = {list, set}: if list == [] then attrs set else "[${listContent list}, ${attrsContent set}]";
33
34 specialType = {value, _phpType}: {
35 "mixed_array" = mixedArray value;
36 "raw" = value;
37 }.${_phpType};
38
39 type = with lib.types;
40 nullOr (oneOf [
41 bool
42 int
43 float
44 str
45 (attrsOf type)
46 (listOf type)
47 ])
48 // {
49 description = "PHP value";
50 };
51 in {
52
53 inherit type;
54
55 lib = {
56 mkMixedArray = list: set: {_phpType = "mixed_array"; value = { inherit list set;}; };
57 mkRaw = raw: {_phpType = "raw"; value = raw;};
58 };
59
60 generate = name: value: pkgs.writeTextFile {
61 inherit name;
62 text = let
63 # strict_types enabled here to easily debug problems when calling functions of incorrect type using `mkRaw`.
64 phpHeader = "<?php\ndeclare(strict_types=1);\n";
65 in if finalVariable == null then phpHeader + "return ${toPHP value};\n" else phpHeader + "\$${finalVariable} = ${toPHP value};\n";
66 };
67
68 };
69}