summaryrefslogtreecommitdiff
path: root/lib/generators.nix
diff options
context:
space:
mode:
Diffstat (limited to 'lib/generators.nix')
-rw-r--r--lib/generators.nix604
1 files changed, 356 insertions, 248 deletions
diff --git a/lib/generators.nix b/lib/generators.nix
index eb8d76626e71..9f9fb834ca07 100644
--- a/lib/generators.nix
+++ b/lib/generators.nix
@@ -35,7 +35,7 @@ let
filter
flatten
foldl
- functionArgs # Note: not the builtin; considers `__functor` in attrsets.
+ functionArgs # Note: not the builtin; considers `__functor` in attrsets.
gvariant
hasInfix
head
@@ -45,7 +45,7 @@ let
isBool
isDerivation
isFloat
- isFunction # Note: not the builtin; considers `__functor` in attrsets.
+ isFunction # Note: not the builtin; considers `__functor` in attrsets.
isInt
isList
isPath
@@ -74,7 +74,8 @@ let
;
## -- HELPER FUNCTIONS & DEFAULTS --
-in rec {
+in
+rec {
/**
Convert a value to a sensible default string representation.
The builtin `toString` function has some strange defaults,
@@ -88,32 +89,44 @@ in rec {
`v`
: 2\. Function argument
*/
- mkValueStringDefault = {}: v:
- let err = t: v: abort
- ("generators.mkValueStringDefault: " +
- "${t} not supported: ${toPretty {} v}");
- in if isInt v then toString v
+ mkValueStringDefault =
+ { }:
+ v:
+ let
+ err = t: v: abort ("generators.mkValueStringDefault: " + "${t} not supported: ${toPretty { } v}");
+ in
+ if isInt v then
+ toString v
# convert derivations to store paths
- else if isDerivation v then toString v
+ else if isDerivation v then
+ toString v
# we default to not quoting strings
- else if isString v then v
+ else if isString v then
+ v
# isString returns "1", which is not a good default
- else if true == v then "true"
+ else if true == v then
+ "true"
# here it returns to "", which is even less of a good default
- else if false == v then "false"
- else if null == v then "null"
+ else if false == v then
+ "false"
+ else if null == v then
+ "null"
# if you have lists you probably want to replace this
- else if isList v then err "lists" v
+ else if isList v then
+ err "lists" v
# same as for lists, might want to replace
- else if isAttrs v then err "attrsets" v
+ else if isAttrs v then
+ err "attrsets" v
# functions can’t be printed of course
- else if isFunction v then err "functions" v
+ else if isFunction v then
+ err "functions" v
# Floats currently can't be converted to precise strings,
# condition warning on nix version once this isn't a problem anymore
# See https://github.com/NixOS/nix/pull/3480
- else if isFloat v then floatToString v
- else err "this value is" (toString v);
-
+ else if isFloat v then
+ floatToString v
+ else
+ err "this value is" (toString v);
/**
Generate a line of key k and value v, separated by
@@ -145,15 +158,15 @@ in rec {
: 4\. Function argument
*/
- mkKeyValueDefault = {
- mkValueString ? mkValueStringDefault {}
- }: sep: k: v:
- "${escape [sep] k}${sep}${mkValueString v}";
-
+ mkKeyValueDefault =
+ {
+ mkValueString ? mkValueStringDefault { },
+ }:
+ sep: k: v:
+ "${escape [ sep ] k}${sep}${mkValueString v}";
## -- FILE FORMAT GENERATORS --
-
/**
Generate a key-value-style config file from an attrset.
@@ -169,19 +182,22 @@ in rec {
: indent (optional, default: `""`)
: Initial indentation level
-
*/
- toKeyValue = {
- mkKeyValue ? mkKeyValueDefault {} "=",
- listsAsDuplicateKeys ? false,
- indent ? ""
- }:
- let mkLine = k: v: indent + mkKeyValue k v + "\n";
- mkLines = if listsAsDuplicateKeys
- then k: v: map (mkLine k) (if isList v then v else [v])
- else k: v: [ (mkLine k v) ];
- in attrs: concatStrings (concatLists (mapAttrsToList mkLines attrs));
-
+ toKeyValue =
+ {
+ mkKeyValue ? mkKeyValueDefault { } "=",
+ listsAsDuplicateKeys ? false,
+ indent ? "",
+ }:
+ let
+ mkLine = k: v: indent + mkKeyValue k v + "\n";
+ mkLines =
+ if listsAsDuplicateKeys then
+ k: v: map (mkLine k) (if isList v then v else [ v ])
+ else
+ k: v: [ (mkLine k v) ];
+ in
+ attrs: concatStrings (concatLists (mapAttrsToList mkLines attrs));
/**
Generate an INI-style config file from an
@@ -225,22 +241,27 @@ in rec {
:::
*/
- toINI = {
- mkSectionName ? (name: escape [ "[" "]" ] name),
- mkKeyValue ? mkKeyValueDefault {} "=",
- listsAsDuplicateKeys ? false
- }: attrsOfAttrs:
+ toINI =
+ {
+ mkSectionName ? (name: escape [ "[" "]" ] name),
+ mkKeyValue ? mkKeyValueDefault { } "=",
+ listsAsDuplicateKeys ? false,
+ }:
+ attrsOfAttrs:
let
- # map function to string for each key val
- mapAttrsToStringsSep = sep: mapFn: attrs:
- concatStringsSep sep
- (mapAttrsToList mapFn attrs);
- mkSection = sectName: sectValues: ''
+ # map function to string for each key val
+ mapAttrsToStringsSep =
+ sep: mapFn: attrs:
+ concatStringsSep sep (mapAttrsToList mapFn attrs);
+ mkSection =
+ sectName: sectValues:
+ ''
[${mkSectionName sectName}]
- '' + toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } sectValues;
+ ''
+ + toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } sectValues;
in
- # map input to ini sections
- mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
+ # map input to ini sections
+ mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
/**
Generate an INI-style config file from an attrset
@@ -303,15 +324,22 @@ in rec {
`generators.toINI` directly, which only takes
the part in `sections`.
*/
- toINIWithGlobalSection = {
- mkSectionName ? (name: escape [ "[" "]" ] name),
- mkKeyValue ? mkKeyValueDefault {} "=",
- listsAsDuplicateKeys ? false
- }: { globalSection, sections ? {} }:
- ( if globalSection == {}
- then ""
- else (toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } globalSection)
- + "\n")
+ toINIWithGlobalSection =
+ {
+ mkSectionName ? (name: escape [ "[" "]" ] name),
+ mkKeyValue ? mkKeyValueDefault { } "=",
+ listsAsDuplicateKeys ? false,
+ }:
+ {
+ globalSection,
+ sections ? { },
+ }:
+ (
+ if globalSection == { } then
+ ""
+ else
+ (toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } globalSection) + "\n"
+ )
+ (toINI { inherit mkSectionName mkKeyValue listsAsDuplicateKeys; } sections);
/**
@@ -349,50 +377,57 @@ in rec {
: Key-value pairs to be converted to a git-config file.
See: https://git-scm.com/docs/git-config#_variables for possible values.
-
*/
- toGitINI = attrs:
+ toGitINI =
+ attrs:
let
- mkSectionName = name:
+ mkSectionName =
+ name:
let
containsQuote = hasInfix ''"'' name;
sections = splitString "." name;
section = head sections;
subsections = tail sections;
subsection = concatStringsSep "." subsections;
- in if containsQuote || subsections == [ ] then
- name
- else
- ''${section} "${subsection}"'';
+ in
+ if containsQuote || subsections == [ ] then name else ''${section} "${subsection}"'';
- mkValueString = v:
+ mkValueString =
+ v:
let
- escapedV = ''
- "${
- replaceStrings [ "\n" " " ''"'' "\\" ] [ "\\n" "\\t" ''\"'' "\\\\" ] v
- }"'';
- in mkValueStringDefault { } (if isString v then escapedV else v);
+ escapedV = ''"${replaceStrings [ "\n" " " ''"'' "\\" ] [ "\\n" "\\t" ''\"'' "\\\\" ] v}"'';
+ in
+ mkValueStringDefault { } (if isString v then escapedV else v);
# generation for multiple ini values
- mkKeyValue = k: v:
- let mkKeyValue = mkKeyValueDefault { inherit mkValueString; } " = " k;
- in concatStringsSep "\n" (map (kv: "\t" + mkKeyValue kv) (toList v));
+ mkKeyValue =
+ k: v:
+ let
+ mkKeyValue = mkKeyValueDefault { inherit mkValueString; } " = " k;
+ in
+ concatStringsSep "\n" (map (kv: "\t" + mkKeyValue kv) (toList v));
# converts { a.b.c = 5; } to { "a.b".c = 5; } for toINI
- gitFlattenAttrs = let
- recurse = path: value:
- if isAttrs value && !isDerivation value then
- mapAttrsToList (name: value: recurse ([ name ] ++ path) value) value
- else if length path > 1 then {
- ${concatStringsSep "." (reverseList (tail path))}.${head path} = value;
- } else {
- ${head path} = value;
- };
- in attrs: foldl recursiveUpdate { } (flatten (recurse [ ] attrs));
+ gitFlattenAttrs =
+ let
+ recurse =
+ path: value:
+ if isAttrs value && !isDerivation value then
+ mapAttrsToList (name: value: recurse ([ name ] ++ path) value) value
+ else if length path > 1 then
+ {
+ ${concatStringsSep "." (reverseList (tail path))}.${head path} = value;
+ }
+ else
+ {
+ ${head path} = value;
+ };
+ in
+ attrs: foldl recursiveUpdate { } (flatten (recurse [ ] attrs));
toINI_ = toINI { inherit mkKeyValue mkSectionName; };
in
- toINI_ (gitFlattenAttrs attrs);
+ toINI_ (gitFlattenAttrs attrs);
/**
mkKeyValueDefault wrapper that handles dconf INI quirks.
@@ -427,35 +462,39 @@ in rec {
withRecursion =
{
depthLimit,
- throwOnDepthLimit ? true
+ throwOnDepthLimit ? true,
}:
- assert isInt depthLimit;
- let
- specialAttrs = [
- "__functor"
- "__functionArgs"
- "__toString"
- "__pretty"
- ];
- stepIntoAttr = evalNext: name:
- if elem name specialAttrs
- then id
- else evalNext;
- transform = depth:
- if depthLimit != null && depth > depthLimit then
- if throwOnDepthLimit
- then throw "Exceeded maximum eval-depth limit of ${toString depthLimit} while trying to evaluate with `generators.withRecursion'!"
- else const "<unevaluated>"
- else id;
- mapAny = depth: v:
- let
- evalNext = x: mapAny (depth + 1) (transform (depth + 1) x);
- in
- if isAttrs v then mapAttrs (stepIntoAttr evalNext) v
- else if isList v then map evalNext v
- else transform (depth + 1) v;
- in
- mapAny 0;
+ assert isInt depthLimit;
+ let
+ specialAttrs = [
+ "__functor"
+ "__functionArgs"
+ "__toString"
+ "__pretty"
+ ];
+ stepIntoAttr = evalNext: name: if elem name specialAttrs then id else evalNext;
+ transform =
+ depth:
+ if depthLimit != null && depth > depthLimit then
+ if throwOnDepthLimit then
+ throw "Exceeded maximum eval-depth limit of ${toString depthLimit} while trying to evaluate with `generators.withRecursion'!"
+ else
+ const "<unevaluated>"
+ else
+ id;
+ mapAny =
+ depth: v:
+ let
+ evalNext = x: mapAny (depth + 1) (transform (depth + 1) x);
+ in
+ if isAttrs v then
+ mapAttrs (stepIntoAttr evalNext) v
+ else if isList v then
+ map evalNext v
+ else
+ transform (depth + 1) v;
+ in
+ mapAny 0;
/**
Pretty print a value, akin to `builtins.trace`.
@@ -481,68 +520,96 @@ in rec {
Value
: The value to be pretty printed
*/
- toPretty = {
- allowPrettyValues ? false,
- multiline ? true,
- indent ? ""
- }:
+ toPretty =
+ {
+ allowPrettyValues ? false,
+ multiline ? true,
+ indent ? "",
+ }:
let
- go = indent: v:
- let introSpace = if multiline then "\n${indent} " else " ";
- outroSpace = if multiline then "\n${indent}" else " ";
- in if isInt v then toString v
- # toString loses precision on floats, so we use toJSON instead. This isn't perfect
- # as the resulting string may not parse back as a float (e.g. 42, 1e-06), but for
- # pretty-printing purposes this is acceptable.
- else if isFloat v then builtins.toJSON v
- else if isString v then
- let
- lines = filter (v: ! isList v) (split "\n" v);
- escapeSingleline = escape [ "\\" "\"" "\${" ];
- escapeMultiline = replaceStrings [ "\${" "''" ] [ "''\${" "'''" ];
- singlelineResult = "\"" + concatStringsSep "\\n" (map escapeSingleline lines) + "\"";
- multilineResult = let
- escapedLines = map escapeMultiline lines;
- # The last line gets a special treatment: if it's empty, '' is on its own line at the "outer"
- # indentation level. Otherwise, '' is appended to the last line.
- lastLine = last escapedLines;
- in "''" + introSpace + concatStringsSep introSpace (init escapedLines)
- + (if lastLine == "" then outroSpace else introSpace + lastLine) + "''";
- in
- if multiline && length lines > 1 then multilineResult else singlelineResult
- else if true == v then "true"
- else if false == v then "false"
- else if null == v then "null"
- else if isPath v then toString v
- else if isList v then
- if v == [] then "[ ]"
- else "[" + introSpace
- + concatMapStringsSep introSpace (go (indent + " ")) v
- + outroSpace + "]"
- else if isFunction v then
- let fna = functionArgs v;
- showFnas = concatStringsSep ", " (mapAttrsToList
- (name: hasDefVal: if hasDefVal then name + "?" else name)
- fna);
- in if fna == {} then "<function>"
- else "<function, args: {${showFnas}}>"
- else if isAttrs v then
- # apply pretty values if allowed
- if allowPrettyValues && v ? __pretty && v ? val
- then v.__pretty v.val
- else if v == {} then "{ }"
- else if v ? type && v.type == "derivation" then
- "<derivation ${v.name or "???"}>"
- else "{" + introSpace
- + concatStringsSep introSpace (mapAttrsToList
- (name: value:
+ go =
+ indent: v:
+ let
+ introSpace = if multiline then "\n${indent} " else " ";
+ outroSpace = if multiline then "\n${indent}" else " ";
+ in
+ if isInt v then
+ toString v
+ # toString loses precision on floats, so we use toJSON instead. This isn't perfect
+ # as the resulting string may not parse back as a float (e.g. 42, 1e-06), but for
+ # pretty-printing purposes this is acceptable.
+ else if isFloat v then
+ builtins.toJSON v
+ else if isString v then
+ let
+ lines = filter (v: !isList v) (split "\n" v);
+ escapeSingleline = escape [
+ "\\"
+ "\""
+ "\${"
+ ];
+ escapeMultiline = replaceStrings [ "\${" "''" ] [ "''\${" "'''" ];
+ singlelineResult = "\"" + concatStringsSep "\\n" (map escapeSingleline lines) + "\"";
+ multilineResult =
+ let
+ escapedLines = map escapeMultiline lines;
+ # The last line gets a special treatment: if it's empty, '' is on its own line at the "outer"
+ # indentation level. Otherwise, '' is appended to the last line.
+ lastLine = last escapedLines;
+ in
+ "''"
+ + introSpace
+ + concatStringsSep introSpace (init escapedLines)
+ + (if lastLine == "" then outroSpace else introSpace + lastLine)
+ + "''";
+ in
+ if multiline && length lines > 1 then multilineResult else singlelineResult
+ else if true == v then
+ "true"
+ else if false == v then
+ "false"
+ else if null == v then
+ "null"
+ else if isPath v then
+ toString v
+ else if isList v then
+ if v == [ ] then
+ "[ ]"
+ else
+ "[" + introSpace + concatMapStringsSep introSpace (go (indent + " ")) v + outroSpace + "]"
+ else if isFunction v then
+ let
+ fna = functionArgs v;
+ showFnas = concatStringsSep ", " (
+ mapAttrsToList (name: hasDefVal: if hasDefVal then name + "?" else name) fna
+ );
+ in
+ if fna == { } then "<function>" else "<function, args: {${showFnas}}>"
+ else if isAttrs v then
+ # apply pretty values if allowed
+ if allowPrettyValues && v ? __pretty && v ? val then
+ v.__pretty v.val
+ else if v == { } then
+ "{ }"
+ else if v ? type && v.type == "derivation" then
+ "<derivation ${v.name or "???"}>"
+ else
+ "{"
+ + introSpace
+ + concatStringsSep introSpace (
+ mapAttrsToList (
+ name: value:
"${escapeNixIdentifier name} = ${
- addErrorContext "while evaluating an attribute `${name}`"
- (go (indent + " ") value)
- };") v)
- + outroSpace + "}"
- else abort "generators.toPretty: should never happen (v = ${v})";
- in go indent;
+ addErrorContext "while evaluating an attribute `${name}`" (go (indent + " ") value)
+ };"
+ ) v
+ )
+ + outroSpace
+ + "}"
+ else
+ abort "generators.toPretty: should never happen (v = ${v})";
+ in
+ go indent;
/**
Translate a simple Nix expression to [Plist notation](https://en.wikipedia.org/wiki/Property_list).
@@ -557,61 +624,90 @@ in rec {
Value
: The value to be converted to Plist
*/
- toPlist = {
- escape ? false
- }: v: let
- expr = ind: x:
- if x == null then "" else
- if isBool x then bool ind x else
- if isInt x then int ind x else
- if isString x then str ind x else
- if isList x then list ind x else
- if isAttrs x then attrs ind x else
- if isPath x then str ind (toString x) else
- if isFloat x then float ind x else
- abort "generators.toPlist: should never happen (v = ${v})";
+ toPlist =
+ {
+ escape ? false,
+ }:
+ v:
+ let
+ expr =
+ ind: x:
+ if x == null then
+ ""
+ else if isBool x then
+ bool ind x
+ else if isInt x then
+ int ind x
+ else if isString x then
+ str ind x
+ else if isList x then
+ list ind x
+ else if isAttrs x then
+ attrs ind x
+ else if isPath x then
+ str ind (toString x)
+ else if isFloat x then
+ float ind x
+ else
+ abort "generators.toPlist: should never happen (v = ${v})";
- literal = ind: x: ind + x;
+ literal = ind: x: ind + x;
- maybeEscapeXML = if escape then escapeXML else x: x;
+ maybeEscapeXML = if escape then escapeXML else x: x;
- bool = ind: x: literal ind (if x then "<true/>" else "<false/>");
- int = ind: x: literal ind "<integer>${toString x}</integer>";
- str = ind: x: literal ind "<string>${maybeEscapeXML x}</string>";
- key = ind: x: literal ind "<key>${maybeEscapeXML x}</key>";
- float = ind: x: literal ind "<real>${toString x}</real>";
+ bool = ind: x: literal ind (if x then "<true/>" else "<false/>");
+ int = ind: x: literal ind "<integer>${toString x}</integer>";
+ str = ind: x: literal ind "<string>${maybeEscapeXML x}</string>";
+ key = ind: x: literal ind "<key>${maybeEscapeXML x}</key>";
+ float = ind: x: literal ind "<real>${toString x}</real>";
- indent = ind: expr "\t${ind}";
+ indent = ind: expr "\t${ind}";
- item = ind: concatMapStringsSep "\n" (indent ind);
+ item = ind: concatMapStringsSep "\n" (indent ind);
- list = ind: x: concatStringsSep "\n" [
- (literal ind "<array>")
- (item ind x)
- (literal ind "</array>")
- ];
+ list =
+ ind: x:
+ concatStringsSep "\n" [
+ (literal ind "<array>")
+ (item ind x)
+ (literal ind "</array>")
+ ];
- attrs = ind: x: concatStringsSep "\n" [
- (literal ind "<dict>")
- (attr ind x)
- (literal ind "</dict>")
- ];
+ attrs =
+ ind: x:
+ concatStringsSep "\n" [
+ (literal ind "<dict>")
+ (attr ind x)
+ (literal ind "</dict>")
+ ];
- attr = let attrFilter = name: value: name != "_module" && value != null;
- in ind: x: concatStringsSep "\n" (flatten (mapAttrsToList
- (name: value: optionals (attrFilter name value) [
- (key "\t${ind}" name)
- (expr "\t${ind}" value)
- ]) x));
+ attr =
+ let
+ attrFilter = name: value: name != "_module" && value != null;
+ in
+ ind: x:
+ concatStringsSep "\n" (
+ flatten (
+ mapAttrsToList (
+ name: value:
+ optionals (attrFilter name value) [
+ (key "\t${ind}" name)
+ (expr "\t${ind}" value)
+ ]
+ ) x
+ )
+ );
- in
- # TODO: As discussed in #356502, deprecated functionality should be removed sometime after 25.11.
- lib.warnIf (!escape && lib.oldestSupportedReleaseIsAtLeast 2505) "Using `lib.generators.toPlist` without `escape = true` is deprecated" ''
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
- <plist version="1.0">
- ${expr "" v}
- </plist>'';
+ in
+ # TODO: As discussed in #356502, deprecated functionality should be removed sometime after 25.11.
+ lib.warnIf (!escape && lib.oldestSupportedReleaseIsAtLeast 2505)
+ "Using `lib.generators.toPlist` without `escape = true` is deprecated"
+ ''
+ <?xml version="1.0" encoding="UTF-8"?>
+ <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+ <plist version="1.0">
+ ${expr "" v}
+ </plist>'';
/**
Translate a simple Nix expression to Dhall notation.
@@ -629,13 +725,14 @@ in rec {
: The value to be converted to Dhall
*/
- toDhall = { }@args: v:
- let concatItems = concatStringsSep ", ";
- in if isAttrs v then
- "{ ${
- concatItems (mapAttrsToList
- (key: value: "${key} = ${toDhall args value}") v)
- } }"
+ toDhall =
+ { }@args:
+ v:
+ let
+ concatItems = concatStringsSep ", ";
+ in
+ if isAttrs v then
+ "{ ${concatItems (mapAttrsToList (key: value: "${key} = ${toDhall args value}") v)} }"
else if isList v then
"[ ${concatItems (map (toDhall args) v)} ]"
else if isInt v then
@@ -663,7 +760,6 @@ in rec {
Regardless of multiline parameter there is no trailing newline.
-
# Inputs
Structured function argument
@@ -711,11 +807,13 @@ in rec {
:::
*/
- toLua = {
- multiline ? true,
- indent ? "",
- asBindings ? false,
- }@args: v:
+ toLua =
+ {
+ multiline ? true,
+ indent ? "",
+ asBindings ? false,
+ }@args:
+ v:
let
innerIndent = "${indent} ";
introSpace = if multiline then "\n${innerIndent}" else " ";
@@ -725,13 +823,16 @@ in rec {
asBindings = false;
};
concatItems = concatStringsSep ",${introSpace}";
- isLuaInline = { _type ? null, ... }: _type == "lua-inline";
+ isLuaInline =
+ {
+ _type ? null,
+ ...
+ }:
+ _type == "lua-inline";
generatedBindings =
- assert assertMsg (badVarNames == []) "Bad Lua var names: ${toPretty {} badVarNames}";
- concatStrings (
- mapAttrsToList (key: value: "${indent}${key} = ${toLua innerArgs value}\n") v
- );
+ assert assertMsg (badVarNames == [ ]) "Bad Lua var names: ${toPretty { } badVarNames}";
+ concatStrings (mapAttrsToList (key: value: "${indent}${key} = ${toLua innerArgs value}\n") v);
# https://en.wikibooks.org/wiki/Lua_Programming/variable#Variable_names
matchVarName = match "[[:alpha:]_][[:alnum:]_]*(\\.[[:alpha:]_][[:alnum:]_]*)*";
@@ -746,8 +847,12 @@ in rec {
else if isPath v || isDerivation v then
toJSON "${v}"
else if isList v then
- (if v == [ ] then "{}" else
- "{${introSpace}${concatItems (map (value: "${toLua innerArgs value}") v)}${outroSpace}}")
+ (
+ if v == [ ] then
+ "{}"
+ else
+ "{${introSpace}${concatItems (map (value: "${toLua innerArgs value}") v)}${outroSpace}}"
+ )
else if isAttrs v then
(
if isLuaInline v then
@@ -755,9 +860,9 @@ in rec {
else if v == { } then
"{}"
else
- "{${introSpace}${concatItems (
- mapAttrsToList (key: value: "[${toJSON key}] = ${toLua innerArgs value}") v
- )}${outroSpace}}"
+ "{${introSpace}${
+ concatItems (mapAttrsToList (key: value: "[${toJSON key}] = ${toLua innerArgs value}") v)
+ }${outroSpace}}"
)
else
abort "generators.toLua: type ${typeOf v} is unsupported";
@@ -765,7 +870,6 @@ in rec {
/**
Mark string as Lua expression to be inlined when processed by toLua.
-
# Inputs
`expr`
@@ -778,8 +882,12 @@ in rec {
mkLuaInline :: String -> AttrSet
```
*/
- mkLuaInline = expr: { _type = "lua-inline"; inherit expr; };
-} // {
+ mkLuaInline = expr: {
+ _type = "lua-inline";
+ inherit expr;
+ };
+}
+// {
/**
Generates JSON from an arbitrary (non-function) value.
For more information see the documentation of the builtin.
@@ -794,7 +902,7 @@ in rec {
: The value to be converted to JSON
*/
- toJSON = {}: lib.strings.toJSON;
+ toJSON = { }: lib.strings.toJSON;
/**
YAML has been a strict superset of JSON since 1.2, so we
@@ -812,5 +920,5 @@ in rec {
: The value to be converted to YAML
*/
- toYAML = {}: lib.strings.toJSON;
+ toYAML = { }: lib.strings.toJSON;
}