diff options
author | Silvan Mosberger <contact@infinisil.com> | 2023-11-14 05:33:40 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-14 05:33:40 +0100 |
commit | 7eddbf56907e20b14a2996597cfc6619d1c18aed (patch) | |
tree | 96ee3e93207493cbdd2b15d5c871ab85977137b7 /lib | |
parent | 5d6c73222280b7f69109dfa5c9572f4b74c3453c (diff) | |
parent | b3e2c150007b6d54f09a1b209fe66f6d0a1e70a7 (diff) |
Merge pull request #265710 from ShamrockLee/lib-copy-function-args
lib.mirrorFunctionArgs: init
Diffstat (limited to 'lib')
-rw-r--r-- | lib/customisation.nix | 18 | ||||
-rw-r--r-- | lib/default.nix | 2 | ||||
-rw-r--r-- | lib/trivial.nix | 34 |
3 files changed, 45 insertions, 9 deletions
diff --git a/lib/customisation.nix b/lib/customisation.nix index c7d40339d05f5..08fc5db0614de 100644 --- a/lib/customisation.nix +++ b/lib/customisation.nix @@ -76,19 +76,22 @@ rec { Type: makeOverridable :: (AttrSet -> a) -> AttrSet -> a */ - makeOverridable = f: lib.setFunctionArgs - (origArgs: let + makeOverridable = f: + let + # Creates a functor with the same arguments as f + mirrorArgs = lib.mirrorFunctionArgs f; + in + mirrorArgs (origArgs: + let result = f origArgs; - # Creates a functor with the same arguments as f - copyArgs = g: lib.setFunctionArgs g (lib.functionArgs f); # Changes the original arguments with (potentially a function that returns) a set of new attributes overrideWith = newArgs: origArgs // (if lib.isFunction newArgs then newArgs origArgs else newArgs); # Re-call the function but with different arguments - overrideArgs = copyArgs (newArgs: makeOverridable f (overrideWith newArgs)); + overrideArgs = mirrorArgs (newArgs: makeOverridable f (overrideWith newArgs)); # Change the result of the function call by applying g to it - overrideResult = g: makeOverridable (copyArgs (args: g (f args))) origArgs; + overrideResult = g: makeOverridable (mirrorArgs (args: g (f args))) origArgs; in if builtins.isAttrs result then result // { @@ -102,8 +105,7 @@ rec { lib.setFunctionArgs result (lib.functionArgs result) // { override = overrideArgs; } - else result) - (lib.functionArgs f); + else result); /* Call the package function in the file `fn` with the required diff --git a/lib/default.nix b/lib/default.nix index fe737a125e680..0dac50a08caa0 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -74,7 +74,7 @@ let importJSON importTOML warn warnIf warnIfNot throwIf throwIfNot checkListOfEnum info showWarnings nixpkgsVersion version isInOldestRelease mod compare splitByAndCompare - functionArgs setFunctionArgs isFunction toFunction + functionArgs setFunctionArgs isFunction toFunction mirrorFunctionArgs toHexString toBaseDigits inPureEvalMode; inherit (self.fixedPoints) fix fix' converge extends composeExtensions composeManyExtensions makeExtensible makeExtensibleWithCustomName; diff --git a/lib/trivial.nix b/lib/trivial.nix index c23fc6070be46..a89c1aa25b1f7 100644 --- a/lib/trivial.nix +++ b/lib/trivial.nix @@ -449,6 +449,40 @@ rec { (f ? __functor && isFunction (f.__functor f)); /* + `mirrorFunctionArgs f g` creates a new function `g'` with the same behavior as `g` (`g' x == g x`) + but its function arguments mirroring `f` (`lib.functionArgs g' == lib.functionArgs f`). + + Type: + mirrorFunctionArgs :: (a -> b) -> (a -> c) -> (a -> c) + + Example: + addab = {a, b}: a + b + addab { a = 2; b = 4; } + => 6 + lib.functionArgs addab + => { a = false; b = false; } + addab1 = attrs: addab attrs + 1 + addab1 { a = 2; b = 4; } + => 7 + lib.functionArgs addab1 + => { } + addab1' = lib.mirrorFunctionArgs addab addab1 + addab1' { a = 2; b = 4; } + => 7 + lib.functionArgs addab1' + => { a = false; b = false; } + */ + mirrorFunctionArgs = + # Function to provide the argument metadata + f: + let + fArgs = functionArgs f; + in + # Function to set the argument metadata to + g: + setFunctionArgs g fArgs; + + /* Turns any non-callable values into constant functions. Returns callable values as is. |