diff --git a/lib/attrsets.nix b/lib/attrsets.nix index bf6c90bf1be6..52bc131ef40f 100644 --- a/lib/attrsets.nix +++ b/lib/attrsets.nix @@ -34,12 +34,20 @@ rec { default: # The nested attribute set to select values from set: - let attr = head attrPath; + let + lenAttrPath = length attrPath; + attrByPath' = n: s: ( + if n == lenAttrPath then s + else ( + let + attr = elemAt attrPath n; + in + if s ? ${attr} then attrByPath' (n + 1) s.${attr} + else default + ) + ); in - if attrPath == [] then set - else if set ? ${attr} - then attrByPath (tail attrPath) default set.${attr} - else default; + attrByPath' 0 set; /* Return if an attribute from nested attribute set exists. @@ -58,13 +66,19 @@ rec { attrPath: # The nested attribute set to check e: - let attr = head attrPath; + let + lenAttrPath = length attrPath; + hasAttrByPath' = n: s: ( + n == lenAttrPath || ( + let + attr = elemAt attrPath n; + in + if s ? ${attr} then hasAttrByPath' (n + 1) s.${attr} + else false + ) + ); in - if attrPath == [] then true - else if e ? ${attr} - then hasAttrByPath (tail attrPath) e.${attr} - else false; - + hasAttrByPath' 0 e; /* Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`.