about summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorAdam Joseph <adam@westernsemico.com>2023-08-21 14:38:53 -0700
committerAdam Joseph <54836058+amjoseph-nixpkgs@users.noreply.github.com>2023-11-05 00:55:16 +0000
commit8c0416ef364f5d5dea9d5694aadc0014bb95c1ca (patch)
tree4ca59313b6c6a38b7f83263e028b517b478de419 /lib
parent91805738371940d2a11fb3bec684634e64ab4c4a (diff)
lib.systems.inspect: add patternLogicalAnd
Diffstat (limited to 'lib')
-rw-r--r--lib/systems/inspect.nix26
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/systems/inspect.nix b/lib/systems/inspect.nix
index 022e459c3945a..073df78797c72 100644
--- a/lib/systems/inspect.nix
+++ b/lib/systems/inspect.nix
@@ -100,6 +100,32 @@ rec {
     ];
   };
 
+  # given two patterns, return a pattern which is their logical AND.
+  # Since a pattern is a list-of-disjuncts, this needs to
+  patternLogicalAnd = pat1_: pat2_:
+    let
+      # patterns can be either a list or a (bare) singleton; turn
+      # them into singletons for uniform handling
+      pat1 = lib.toList pat1_;
+      pat2 = lib.toList pat2_;
+    in
+      lib.concatMap (attr1:
+        map (attr2:
+          lib.recursiveUpdateUntil
+            (path: subattr1: subattr2:
+              if (builtins.intersectAttrs subattr1 subattr2) == {} || subattr1 == subattr2
+              then true
+              else throw ''
+                pattern conflict at path ${toString path}:
+                  ${builtins.toJSON subattr1}
+                  ${builtins.toJSON subattr2}
+                '')
+            attr1
+            attr2
+            )
+          pat2)
+        pat1;
+
   matchAnyAttrs = patterns:
     if builtins.isList patterns then attrs: any (pattern: matchAttrs pattern attrs) patterns
     else matchAttrs patterns;