Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 34 additions & 17 deletions lib/attrsets.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1628,26 +1628,43 @@ rec {
binaryMerge 0 (length list);

/**
Does the same as the update operator `//` except that attributes are
merged until the given predicate is verified. The predicate should
accept 3 arguments which are the path to reach the attribute, a part of
the first attribute set and a part of the second attribute set. When
the predicate is satisfied, the value of the first attribute set is
replaced by the value of the second attribute set.
Update `lhs` so that `rhs` wins for any given attribute path that occurs in both.
Unlike the `//` (update) operator, which operates on a single attribute set,
This function views its operands `lhs` and `rhs` as a mapping from attribute *paths*
to values.
The caller-provided function `pred` decides whether any given path is one of the following:
- `true`: a value in the mapping
- `false`: an attribute set whose purpose is to create the nesting structure.
# Inputs
`pred`
: Predicate, taking the path to the current attribute as a list of strings for attribute names, and the two values at that path from the original arguments.
: Predicate function (of type `List String -> Any -> Any -> Bool`)
Inputs:
- `path : List String`: the path to the current attribute as a list of strings for attribute names
- `lhsAtPath : Any`: the value at that path in `lhs`; same as `getAttrFromPath path lhs`
- `rhsAtPath : Any`: the value at that path in `rhs`; same as `getAttrFromPath path rhs`
Output:
- `true`: `path` points to a value in the mapping, and `rhsAtPath` will appear in the return value of `recursiveUpdateUntil`
- `false`: `path` is part of the nesting structure and will be an attrset in the return value of `recursiveUpdateUntil`
`pred` is only called for `path`s that extend prefixes for which `pred` returned `false`.
`lhs`
: Left attribute set of the merge.
: Left attribute set of the update.
`rhs`
: Right attribute set of the merge.
: Right attribute set of the update.
# Type
Expand All @@ -1660,23 +1677,23 @@ rec {
## `lib.attrsets.recursiveUpdateUntil` usage example
```nix
recursiveUpdateUntil (path: l: r: path == ["foo"]) {
# first attribute set
recursiveUpdateUntil (path: lhs: rhs: path == ["foo"]) {
# left attribute set
foo.bar = 1;
foo.baz = 2;
bar = 3;
} {
#second attribute set
# right attribute set
foo.bar = 1;
foo.quz = 2;
baz = 4;
}
=> {
foo.bar = 1; # 'foo.*' from the second set
foo.bar = 1; # 'foo.*' from the 'right' set
foo.quz = 2; #
bar = 3; # 'bar' from the first set
baz = 4; # 'baz' from the second set
bar = 3; # 'bar' from the 'left' set
baz = 4; # 'baz' from the 'right' set
}
```
Expand All @@ -1688,9 +1705,9 @@ rec {
f =
attrPath:
zipAttrsWith (
n: values:
name: values:
let
here = attrPath ++ [ n ];
here = attrPath ++ [ name ];
in
if length values == 1 || pred here (elemAt values 1) (head values) then
head values
Expand Down
Loading