···
substSubModules = m: nonEmptyListOf (elemType.substSubModules m);
585
-
attrsOf = elemType: mkOptionType rec {
587
-
description = "attribute set of ${optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType}";
588
-
descriptionClass = "composite";
591
-
mapAttrs (n: v: v.value) (filterAttrs (n: v: v ? value) (zipAttrsWith (name: defs:
592
-
(mergeDefinitions (loc ++ [name]) elemType defs).optionalValue
594
-
# Push down position info.
595
-
(map (def: mapAttrs (n: v: { inherit (def) file; value = v; }) def.value) defs)));
596
-
emptyValue = { value = {}; };
597
-
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name>"]);
598
-
getSubModules = elemType.getSubModules;
599
-
substSubModules = m: attrsOf (elemType.substSubModules m);
600
-
functor = (defaultFunctor name) // { wrapped = elemType; };
601
-
nestedTypes.elemType = elemType;
585
+
attrsOf = elemType: attrsWith { inherit elemType; };
# A version of attrsOf that's lazy in its values at the expense of
# conditional definitions not working properly. E.g. defining a value with
# `foo.attr = mkIf false 10`, then `foo ? attr == true`, whereas with
# attrsOf it would correctly be `false`. Accessing `foo.attr` would throw an
# error that it's not defined. Use only if conditional definitions don't make sense.
609
-
lazyAttrsOf = elemType: mkOptionType rec {
610
-
name = "lazyAttrsOf";
611
-
description = "lazy attribute set of ${optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType}";
592
+
lazyAttrsOf = elemType: attrsWith { inherit elemType; lazy = true; };
594
+
# base type for lazyAttrsOf and attrsOf
600
+
typeName = if lazy then "lazyAttrsOf" else "attrsOf";
601
+
# Push down position info.
602
+
pushPositions = map (def: mapAttrs (n: v: { inherit (def) file; value = v; }) def.value);
606
+
description = (if lazy then "lazy attribute set" else "attribute set") + " of ${optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType}";
descriptionClass = "composite";
615
-
zipAttrsWith (name: defs:
616
-
let merged = mergeDefinitions (loc ++ [name]) elemType defs;
617
-
# mergedValue will trigger an appropriate error when accessed
618
-
in merged.optionalValue.value or elemType.emptyValue.value or merged.mergedValue
620
-
# Push down position info.
621
-
(map (def: mapAttrs (n: v: { inherit (def) file; value = v; }) def.value) defs);
609
+
merge = if lazy then (
610
+
# Lazy merge Function
612
+
zipAttrsWith (name: defs:
613
+
let merged = mergeDefinitions (loc ++ [name]) elemType defs;
614
+
# mergedValue will trigger an appropriate error when accessed
615
+
in merged.optionalValue.value or elemType.emptyValue.value or merged.mergedValue
617
+
# Push down position info.
618
+
(pushPositions defs)
620
+
# Non-lazy merge Function
622
+
mapAttrs (n: v: v.value) (filterAttrs (n: v: v ? value) (zipAttrsWith (name: defs:
623
+
(mergeDefinitions (loc ++ [name]) elemType (defs)).optionalValue
625
+
# Push down position info.
626
+
(pushPositions defs)))
emptyValue = { value = {}; };
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name>"]);
getSubModules = elemType.getSubModules;
625
-
substSubModules = m: lazyAttrsOf (elemType.substSubModules m);
626
-
functor = (defaultFunctor name) // { wrapped = elemType; };
631
+
substSubModules = m: attrsWith { elemType = elemType.substSubModules m; inherit lazy; };
632
+
functor = defaultFunctor "attrsWith" // {
633
+
wrapped = elemType;
635
+
# Important!: Add new function attributes here in case of future changes
636
+
inherit elemType lazy;
640
+
elemType = lhs.elemType.typeMerge rhs.elemType.functor;
642
+
if lhs.lazy == rhs.lazy then
647
+
if elemType == null || lazy == null then
651
+
inherit elemType lazy;
nestedTypes.elemType = elemType;