-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Thanks to upstream nixpkgs, this is just a shorter name for their `recursiveUpdate` lib function. Important and common enough to warrant inclusion, since there is no other "out of the box" method to merge sets recursively without destructive operations in pure Nix.
- Loading branch information
Showing
3 changed files
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/** | ||
A recursive variant of the update operator ‘//’. The recursion | ||
stops when one of the attribute values is not an attribute set, | ||
in which case the right hand side value takes precedence over the | ||
left hand side value. | ||
# Inputs | ||
`lhs` | ||
: Left attribute set of the merge. | ||
`rhs` | ||
: Right attribute set of the merge. | ||
# Type | ||
``` | ||
merge :: AttrSet -> AttrSet -> AttrSet | ||
``` | ||
# Examples | ||
:::{.example} | ||
## `lib.attrsets.merge` usage example | ||
```nix | ||
merge { | ||
boot.loader.grub.enable = true; | ||
boot.loader.grub.device = "/dev/hda"; | ||
} { | ||
boot.loader.grub.device = ""; | ||
} | ||
returns: { | ||
boot.loader.grub.enable = true; | ||
boot.loader.grub.device = ""; | ||
} | ||
``` | ||
::: | ||
*/ | ||
lhs: rhs: | ||
mod.mergeUntil ( | ||
path: lhs: rhs: | ||
!(std.isAttrs lhs && std.isAttrs rhs) | ||
) lhs rhs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/** | ||
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. | ||
# 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. | ||
`lhs` | ||
: Left attribute set of the merge. | ||
`rhs` | ||
: Right attribute set of the merge. | ||
# Type | ||
``` | ||
mergeUntil :: ( [ String ] -> AttrSet -> AttrSet -> Bool ) -> AttrSet -> AttrSet -> AttrSet | ||
``` | ||
# Examples | ||
:::{.example} | ||
## `lib.attrsets.mergeUntil` usage example | ||
```nix | ||
mergeUntil (path: l: r: path == ["foo"]) { | ||
# first attribute set | ||
foo.bar = 1; | ||
foo.baz = 2; | ||
bar = 3; | ||
} { | ||
#second attribute set | ||
foo.bar = 1; | ||
foo.quz = 2; | ||
baz = 4; | ||
} | ||
=> { | ||
foo.bar = 1; # 'foo.*' from the second set | ||
foo.quz = 2; # | ||
bar = 3; # 'bar' from the first set | ||
baz = 4; # 'baz' from the second set | ||
} | ||
``` | ||
::: | ||
*/ | ||
|
||
pred: lhs: rhs: | ||
let | ||
f = | ||
attrPath: | ||
std.zipAttrsWith ( | ||
n: values: | ||
let | ||
here = attrPath ++ [ n ]; | ||
in | ||
if std.length values == 1 || pred here (std.elemAt values 1) (std.head values) then | ||
std.head values | ||
else | ||
f here values | ||
); | ||
in | ||
f [ ] [ | ||
rhs | ||
lhs | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
{ | ||
Cond = mod.cond; | ||
FilterMap = mod.filterMap; | ||
Merge = mod.merge; | ||
} |