Commit f993f8a1 authored by figsoda's avatar figsoda
Browse files

lib/attrsets: add concatMapAttrs

parent 4536ebad
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@

let
  inherit (builtins) head tail length;
  inherit (lib.trivial) id;
  inherit (lib.trivial) flip id mergeAttrs pipe;
  inherit (lib.strings) concatStringsSep concatMapStringsSep escapeNixIdentifier sanitizeDerivationName;
  inherit (lib.lists) foldr foldl' concatMap concatLists elemAt all partition groupBy take foldl;
in
@@ -77,6 +77,25 @@ rec {
    let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
    in attrByPath attrPath (abort errorMsg);

  /* Map each attribute in the given set and merge them into a new attribute set.

     Type:
       concatMapAttrs ::
         (String -> a -> AttrSet)
         -> AttrSet
         -> AttrSet

     Example:
       concatMapAttrs
         (name: value: {
           ${name} = value;
           ${name + value} = value;
         })
         { x = "a"; y = "b"; }
       => { x = "a"; xa = "a"; y = "b"; yb = "b"; }
  */
  concatMapAttrs = f: flip pipe [ (mapAttrs f) attrValues (foldl' mergeAttrs { }) ];


  /* Update or set specific paths of an attribute set.

+1 −1
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ let
    inherit (self.attrsets) attrByPath hasAttrByPath setAttrByPath
      getAttrFromPath attrVals attrValues getAttrs catAttrs filterAttrs
      filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs
      mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
      mapAttrs' mapAttrsToList concatMapAttrs mapAttrsRecursive mapAttrsRecursiveCond
      genAttrs isDerivation toDerivation optionalAttrs
      zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
      recursiveUpdate matchAttrs overrideExisting showAttrPath getOutput getBin
+17 −0
Original line number Diff line number Diff line
@@ -478,6 +478,23 @@ runTests {

# ATTRSETS

  testConcatMapAttrs = {
    expr = concatMapAttrs
      (name: value: {
        ${name} = value;
        ${name + value} = value;
      })
      {
        foo = "bar";
        foobar = "baz";
      };
    expected = {
      foo = "bar";
      foobar = "baz";
      foobarbaz = "baz";
    };
  };

  # code from the example
  testRecursiveUpdateUntil = {
    expr = recursiveUpdateUntil (path: l: r: path == ["foo"]) {