lib/types(custom): clarify anythingConcatLists code

This commit is contained in:
diniamo 2024-07-09 00:49:15 +02:00
commit dc7589b258

View file

@ -2,12 +2,12 @@
inherit (lib) isStringLike showOption showFiles getFiles mergeOneOption mergeEqualOption; inherit (lib) isStringLike showOption showFiles getFiles mergeOneOption mergeEqualOption;
inherit (lib.types) anything attrsOf; inherit (lib.types) anything attrsOf;
inherit (lib.nvim.types) anythingConcatLists; inherit (lib.nvim.types) anythingConcatLists;
inherit (builtins) isAttrs foldl' head concatLists; inherit (builtins) typeOf isAttrs any head concatLists;
in { in {
# HACK: Does this break anything in our case?
# A modified version of the nixpkgs anything type that concatenates lists # 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, # 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 # which makes it non-deterministic
# HACK: Does this break anything in our case?
anythingConcatLists = anythingConcatLists =
anything anything
// { // {
@ -15,40 +15,39 @@ in {
getType = value: getType = value:
if isAttrs value && isStringLike value if isAttrs value && isStringLike value
then "stringCoercibleSet" then "stringCoercibleSet"
else builtins.typeOf value; else typeOf value;
# Returns the common type of all definitions, throws an error if they # Throw an error if not all defs have the same type
# don't have the same type checkType = getType (head defs).value;
commonType = commonType =
foldl' ( if any (def: getType def.value != checkType) defs
type: def: then throw "The option `${showOption loc}' has conflicting option types in ${showFiles (getFiles defs)}"
if getType def.value == type else checkType;
then type
else throw "The option `${showOption loc}' has conflicting option types in ${showFiles (getFiles defs)}"
) (getType (head defs).value)
defs;
mergeFunction = mergeFunctions = {
{ # Recursively merge attribute sets
# Recursively merge attribute sets set = (attrsOf anythingConcatLists).merge;
set = (attrsOf anythingConcatLists).merge;
# Overridden behavior for lists # Overridden behavior for lists, that concatenates lists
list = _: defs: concatLists (map (e: e.value) defs); list = _: defs: concatLists (map (e: e.value) defs);
# This is the type of packages, only accept a single definition
stringCoercibleSet = mergeOneOption; # This means it's a package, only accept a single definition
lambda = loc: defs: arg: stringCoercibleSet = mergeOneOption;
anythingConcatLists.merge
(loc ++ ["<function body>"]) # This works by passing the argument to the functions,
(map (def: { # and merging their returns values instead
inherit (def) file; lambda = loc: defs: arg:
value = def.value arg; anythingConcatLists.merge
}) (loc ++ ["<function body>"])
defs); (map (def: {
# Otherwise fall back to only allowing all equal definitions inherit (def) file;
} value = def.value arg;
.${commonType} })
or mergeEqualOption; defs);
};
in 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;
}; };
} }