about summary refs log tree commit diff
path: root/lib/systems
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2023-05-14 22:28:31 +0200
committerRobert Hensing <robert@roberthensing.nl>2023-06-13 10:17:02 +0200
commit18c7f6237f92ef5ef9d7cf106ec2ffb72af336fc (patch)
treecfa1110a901732a7b19d19c59a230858418959f6 /lib/systems
parent3a86958c974bc3a03c32ab33ecfc0ec9498c7869 (diff)
lib.systems.{equals,toLosslessStringMaybe}: init
Diffstat (limited to 'lib/systems')
-rw-r--r--lib/systems/default.nix33
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/systems/default.nix b/lib/systems/default.nix
index f4784c61c6752..abaad19a3e1dc 100644
--- a/lib/systems/default.nix
+++ b/lib/systems/default.nix
@@ -9,6 +9,39 @@ rec {
   examples = import ./examples.nix { inherit lib; };
   architectures = import ./architectures.nix { inherit lib; };
 
+  /*
+    Elaborated systems contain functions, which means that they don't satisfy
+    `==` for a lack of reflexivity.
+
+    They might *appear* to satisfy `==` reflexivity when the same exact value is
+    compared to itself, because object identity is used as an "optimization";
+    compare the value with a reconstruction of itself, e.g. with `f == a: f a`,
+    or perhaps calling `elaborate` twice, and one will see reflexivity fail as described.
+
+    Hence a custom equality test.
+
+    Note that this does not canonicalize the systems, so you'll want to make sure
+    both arguments have been `elaborate`-d.
+  */
+  equals =
+    let uncomparable = { canExecute = null; emulator = null; emulatorAvailable = null; isCompatible = null; };
+    in a: b: a // uncomparable == b // uncomparable;
+
+  /*
+    Try to convert an elaborated system back to a simple string. If not possible,
+    return null. So we have the property:
+
+        sys: _valid_ sys ->
+          sys == elaborate (toLosslessStringMaybe sys)
+
+    NOTE: This property is not guaranteed when `sys` was elaborated by a different
+          version of Nixpkgs.
+  */
+  toLosslessStringMaybe = sys:
+    if lib.isString sys then sys
+    else if equals sys (elaborate sys.system) then sys.system
+    else null;
+
   /* List of all Nix system doubles the nixpkgs flake will expose the package set
      for. All systems listed here must be supported by nixpkgs as `localSystem`.