From dc7589b2585f70dab3964c8edc9d1780178a1a22 Mon Sep 17 00:00:00 2001 From: diniamo Date: Tue, 9 Jul 2024 00:49:15 +0200 Subject: [PATCH] lib/types(custom): clarify anythingConcatLists code --- lib/types/custom.nix | 65 ++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/lib/types/custom.nix b/lib/types/custom.nix index e9973bfa..f4065155 100644 --- a/lib/types/custom.nix +++ b/lib/types/custom.nix @@ -2,12 +2,12 @@ inherit (lib) isStringLike showOption showFiles getFiles mergeOneOption mergeEqualOption; inherit (lib.types) anything attrsOf; inherit (lib.nvim.types) anythingConcatLists; - inherit (builtins) isAttrs foldl' head concatLists; + inherit (builtins) typeOf isAttrs any head concatLists; in { + # HACK: Does this break anything in our case? # A modified version of the nixpkgs anything type that concatenates lists # This isn't the default because the order in which the lists are concatenated depends on the order in which the modules are imported, # which makes it non-deterministic - # HACK: Does this break anything in our case? anythingConcatLists = anything // { @@ -15,40 +15,39 @@ in { getType = value: if isAttrs value && isStringLike value then "stringCoercibleSet" - else builtins.typeOf value; + else typeOf value; - # Returns the common type of all definitions, throws an error if they - # don't have the same type + # Throw an error if not all defs have the same type + checkType = getType (head defs).value; commonType = - foldl' ( - type: def: - if getType def.value == type - then type - else throw "The option `${showOption loc}' has conflicting option types in ${showFiles (getFiles defs)}" - ) (getType (head defs).value) - defs; + if any (def: getType def.value != checkType) defs + then throw "The option `${showOption loc}' has conflicting option types in ${showFiles (getFiles defs)}" + else checkType; - mergeFunction = - { - # Recursively merge attribute sets - set = (attrsOf anythingConcatLists).merge; - # Overridden behavior for lists - list = _: defs: concatLists (map (e: e.value) defs); - # This is the type of packages, only accept a single definition - stringCoercibleSet = mergeOneOption; - lambda = loc: defs: arg: - anythingConcatLists.merge - (loc ++ [""]) - (map (def: { - inherit (def) file; - value = def.value arg; - }) - defs); - # Otherwise fall back to only allowing all equal definitions - } - .${commonType} - or mergeEqualOption; + mergeFunctions = { + # Recursively merge attribute sets + set = (attrsOf anythingConcatLists).merge; + + # Overridden behavior for lists, that concatenates lists + list = _: defs: concatLists (map (e: e.value) defs); + + # This means it's a package, only accept a single definition + stringCoercibleSet = mergeOneOption; + + # This works by passing the argument to the functions, + # and merging their returns values instead + lambda = loc: defs: arg: + anythingConcatLists.merge + (loc ++ [""]) + (map (def: { + inherit (def) file; + value = def.value arg; + }) + defs); + }; in - mergeFunction loc defs; + # Merge the defs with the correct function from above, if available + # otherwise only allow equal values + (mergeFunctions.${commonType} or mergeEqualOption) loc defs; }; }