diff options
Diffstat (limited to 'pkgs/lib/attrsets.nix')
-rw-r--r-- | pkgs/lib/attrsets.nix | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/pkgs/lib/attrsets.nix b/pkgs/lib/attrsets.nix index 5e4e9df37110..63448847a150 100644 --- a/pkgs/lib/attrsets.nix +++ b/pkgs/lib/attrsets.nix @@ -5,12 +5,12 @@ with { inherit (import ./trivial.nix) or; inherit (import ./default.nix) fold; inherit (import ./strings.nix) concatStringsSep; - inherit (import ./lists.nix) concatMap; - inherit (import ./misc.nix) eqStrict; + inherit (import ./lists.nix) concatMap concatLists all; + inherit (import ./misc.nix) maybeAttr; }; rec { - inherit (builtins) attrNames listToAttrs hasAttr isAttrs; + inherit (builtins) attrNames listToAttrs hasAttr isAttrs getAttr; /* Return an attribute from nested attribute sets. For instance @@ -33,15 +33,6 @@ rec { nameValuePair (head attrPath) (setAttrByPath (tail attrPath) value) )]; - - /* Backwards compatibility hack: lib.attrByPath used to be called - lib.getAttr, which was confusing given that there was also a - builtins.getAttr. Eventually we'll drop this hack and - lib.getAttr will just be an alias for builtins.getAttr. */ - getAttr = a: b: if isString a - then builtins.getAttr a b - else c: builtins.trace "Deprecated use of lib.getAttr!" (attrByPath a b c); - getAttrFromPath = attrPath: set: let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'"; @@ -75,7 +66,7 @@ rec { catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}] => [1 2] */ - catAttrs = attr: l: fold (s: l: if hasAttr attr s then [(getAttr attr s)] ++ l else l) [] l; + catAttrs = attr: l: concatLists (map (s: if hasAttr attr s then [(getAttr attr s)] else []) l); /* Filter an attribute set by removing all attributes for which the @@ -88,6 +79,16 @@ rec { filterAttrs = pred: set: listToAttrs (fold (n: ys: let v = getAttr n set; in if pred n v then [(nameValuePair n v)] ++ ys else ys) [] (attrNames set)); + /* foldAttrs: apply fold functions to values grouped by key. Eg accumulate values as list: + foldAttrs (n: a: [n] ++ a) [] [{ a = 2; } { a = 3; }] + => { a = [ 2 3 ]; } + */ + foldAttrs = op: nul: list_of_attrs: + fold (n: a: + fold (name: o: + o // (listToAttrs [{inherit name; value = op (getAttr name n) (maybeAttr name nul a); }]) + ) a (attrNames n) + ) {} list_of_attrs; /* Recursively collect sets that verify a given predicate named `pred' from the set `attrs'. The recursion is stopped when the predicate is @@ -301,9 +302,9 @@ rec { matchAttrs = pattern: attrs: fold or false (attrValues (zipAttrsWithNames (attrNames pattern) (n: values: let pat = head values; val = head (tail values); in - if tail values == [] then false + if length values == 1 then false else if isAttrs pat then isAttrs val && matchAttrs head values - else eqStrict pat val + else pat == val ) [pattern attrs])); # override only the attributes that are already present in the old set |