lib: Add composeManyExtensions

This commit is contained in:
Joe Hermaszewski 2020-11-11 10:36:19 +08:00 committed by Peter Simons
parent bacdeffd80
commit c3b35f21f7
3 changed files with 32 additions and 3 deletions

View file

@ -5,7 +5,7 @@
*/
let
inherit (import ./fixed-points.nix {}) makeExtensible;
inherit (import ./fixed-points.nix { inherit lib; }) makeExtensible;
lib = makeExtensible (self: let
callLibs = file: import file { lib = self; };
@ -69,7 +69,7 @@ let
importJSON importTOML warn info showWarnings nixpkgsVersion version mod compare
splitByAndCompare functionArgs setFunctionArgs isFunction toHexString toBaseDigits;
inherit (self.fixedPoints) fix fix' converge extends composeExtensions
makeExtensible makeExtensibleWithCustomName;
composeManyExtensions makeExtensible makeExtensibleWithCustomName;
inherit (self.attrsets) attrByPath hasAttrByPath setAttrByPath
getAttrFromPath attrVals attrValues getAttrs catAttrs filterAttrs
filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs

View file

@ -1,4 +1,4 @@
{ ... }:
{ lib, ... }:
rec {
# Compute the fixed point of the given function `f`, which is usually an
# attribute set that expects its final, non-recursive representation as an
@ -77,6 +77,15 @@ rec {
super' = super // fApplied;
in fApplied // g self super';
# Compose several extending functions of the type expected by 'extends' into
# one where changes made in preceding functions are made available to
# subsequent ones.
#
# composeManyExtensions : [packageSet -> packageSet -> packageSet] -> packageSet -> packageSet -> packageSet
# ^final ^prev ^overrides ^final ^prev ^overrides
composeManyExtensions =
lib.foldr (x: y: composeExtensions x y) (self: super: {});
# Create an overridable, recursive attribute set. For example:
#
# nix-repl> obj = makeExtensible (self: { })

View file

@ -87,6 +87,26 @@ runTests {
expected = true;
};
testComposeManyExtensions0 = {
expr = let obj = makeExtensible (self: { foo = true; });
emptyComposition = composeManyExtensions [];
composed = obj.extend emptyComposition;
in composed.foo;
expected = true;
};
testComposeManyExtensions =
let f = self: super: { bar = false; baz = true; };
g = self: super: { bar = super.baz or false; };
h = self: super: { qux = super.bar or false; };
obj = makeExtensible (self: { foo = self.qux; });
in {
expr = let composition = composeManyExtensions [f g h];
composed = obj.extend composition;
in composed.foo;
expected = (obj.extend (composeExtensions f (composeExtensions g h))).foo;
};
testBitAnd = {
expr = (bitAnd 3 10);
expected = 2;