summary refs log tree commit diff
path: root/pkgs/lib/attrsets.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/lib/attrsets.nix')
-rw-r--r--pkgs/lib/attrsets.nix31
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