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.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 ++ ["<function body>"])
(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 ++ ["<function body>"])
(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;
};
}