diff options
author | Silvan Mosberger <contact@infinisil.com> | 2023-10-10 19:49:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-10 19:49:17 +0200 |
commit | 5323fbf70331f8a7c47f1b4f49841cf74507f77f (patch) | |
tree | 633d4a4f8d2f36148370d73e413e05dc2ccbe23b | |
parent | 26858d744cc49f58cf15c2ba22a7b2d251d3fb55 (diff) | |
parent | d70633f91cb27d9314940d3a6e9385f89bf7f007 (diff) | |
download | nixlib-5323fbf70331f8a7c47f1b4f49841cf74507f77f.tar nixlib-5323fbf70331f8a7c47f1b4f49841cf74507f77f.tar.gz nixlib-5323fbf70331f8a7c47f1b4f49841cf74507f77f.tar.bz2 nixlib-5323fbf70331f8a7c47f1b4f49841cf74507f77f.tar.lz nixlib-5323fbf70331f8a7c47f1b4f49841cf74507f77f.tar.xz nixlib-5323fbf70331f8a7c47f1b4f49841cf74507f77f.tar.zst nixlib-5323fbf70331f8a7c47f1b4f49841cf74507f77f.zip |
Merge pull request #254452 from flyingcircusio/lib-attrsToList
lib.attrsets.attrsToList: add function
-rw-r--r-- | lib/attrsets.nix | 30 | ||||
-rw-r--r-- | lib/default.nix | 4 | ||||
-rw-r--r-- | lib/tests/misc.nix | 24 |
3 files changed, 56 insertions, 2 deletions
diff --git a/lib/attrsets.nix b/lib/attrsets.nix index b8960cf73f20..b0460ab139e8 100644 --- a/lib/attrsets.nix +++ b/lib/attrsets.nix @@ -542,6 +542,36 @@ rec { attrs: map (name: f name attrs.${name}) (attrNames attrs); + /* + Deconstruct an attrset to a list of name-value pairs as expected by [`builtins.listToAttrs`](https://nixos.org/manual/nix/stable/language/builtins.html#builtins-listToAttrs). + Each element of the resulting list is an attribute set with these attributes: + - `name` (string): The name of the attribute + - `value` (any): The value of the attribute + + The following is always true: + ```nix + builtins.listToAttrs (attrsToList attrs) == attrs + ``` + + :::{.warning} + The opposite is not always true. In general expect that + ```nix + attrsToList (builtins.listToAttrs list) != list + ``` + + This is because the `listToAttrs` removes duplicate names and doesn't preserve the order of the list. + ::: + + Example: + attrsToList { foo = 1; bar = "asdf"; } + => [ { name = "bar"; value = "asdf"; } { name = "foo"; value = 1; } ] + + Type: + attrsToList :: AttrSet -> [ { name :: String; value :: Any; } ] + + */ + attrsToList = mapAttrsToList nameValuePair; + /* Like `mapAttrs`, except that it recursively applies itself to the *leaf* attributes of a potentially-nested attribute set: diff --git a/lib/default.nix b/lib/default.nix index 169f013191b8..fe737a125e68 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -81,8 +81,8 @@ let inherit (self.attrsets) attrByPath hasAttrByPath setAttrByPath getAttrFromPath attrVals attrValues getAttrs catAttrs filterAttrs filterAttrsRecursive foldlAttrs foldAttrs collect nameValuePair mapAttrs - mapAttrs' mapAttrsToList concatMapAttrs mapAttrsRecursive mapAttrsRecursiveCond - genAttrs isDerivation toDerivation optionalAttrs + mapAttrs' mapAttrsToList attrsToList concatMapAttrs mapAttrsRecursive + mapAttrsRecursiveCond genAttrs isDerivation toDerivation optionalAttrs zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil recursiveUpdate matchAttrs overrideExisting showAttrPath getOutput getBin getLib getDev getMan chooseDevOutputs zipWithNames zip diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index ec306acbb765..6527c31e49c2 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -20,6 +20,10 @@ let expr = (builtins.tryEval (builtins.seq expr "didn't throw")); expected = { success = false; value = false; }; }; + testingEval = expr: { + expr = (builtins.tryEval expr).success; + expected = true; + }; testingDeepThrow = expr: testingThrow (builtins.deepSeq expr expr); testSanitizeDerivationName = { name, expected }: @@ -816,6 +820,26 @@ runTests { expected = { a = 1; b = 2; }; }; + testListAttrsReverse = let + exampleAttrs = {foo=1; bar="asdf"; baz = [1 3 3 7]; fnord=null;}; + exampleSingletonList = [{name="foo"; value=1;}]; + in { + expr = { + isReverseToListToAttrs = builtins.listToAttrs (attrsToList exampleAttrs) == exampleAttrs; + isReverseToAttrsToList = attrsToList (builtins.listToAttrs exampleSingletonList) == exampleSingletonList; + testDuplicatePruningBehaviour = attrsToList (builtins.listToAttrs [{name="a"; value=2;} {name="a"; value=1;}]); + }; + expected = { + isReverseToAttrsToList = true; + isReverseToListToAttrs = true; + testDuplicatePruningBehaviour = [{name="a"; value=2;}]; + }; + }; + + testAttrsToListsCanDealWithFunctions = testingEval ( + attrsToList { someFunc= a: a + 1;} + ); + # GENERATORS # these tests assume attributes are converted to lists # in alphabetical order |