about summary refs log tree commit diff
path: root/users/sterni/nix/flow
diff options
context:
space:
mode:
Diffstat (limited to 'users/sterni/nix/flow')
-rw-r--r--users/sterni/nix/flow/default.nix54
-rw-r--r--users/sterni/nix/flow/tests/default.nix49
2 files changed, 103 insertions, 0 deletions
diff --git a/users/sterni/nix/flow/default.nix b/users/sterni/nix/flow/default.nix
new file mode 100644
index 000000000000..838e65bfb20e
--- /dev/null
+++ b/users/sterni/nix/flow/default.nix
@@ -0,0 +1,54 @@
+{ depot, ... }:
+
+let
+
+  inherit (depot.nix)
+    yants
+    ;
+
+  # we must avoid evaluating any of the sublists
+  # as they may contain conditions that throw
+  condition = yants.restrict "condition"
+    (ls: builtins.length ls == 2)
+    (yants.list yants.any);
+
+  /* cond :: [ [ bool any ] ] -> any
+   *
+   * Like the common lisp macro: takes a list
+   * of two elemented lists whose first element
+   * is a boolean. The second element of the
+   * first list that has true as its first
+   * element is returned.
+   *
+   * Example:
+   *
+   * cond [
+   *   [ (builtins.isString true) 12 ]
+   *   [ (3 == 2) 13 ]
+   *   [ true 42 ]
+   * ]
+   *
+   * => 42
+   */
+  cond = conds:
+    if builtins.length conds == 0
+    then builtins.throw "cond: exhausted all conditions"
+    else
+      let
+        c = condition (builtins.head conds);
+      in
+        if builtins.head c
+        then builtins.elemAt c 1
+        else cond (builtins.tail conds);
+
+  # TODO(sterni): condf or magic
+  # like <nixpkgs/pkgs/build-support/coq/extra-lib.nix>
+
+  match = val: matcher: matcher."${val}";
+
+in {
+  inherit
+    cond
+    match
+    ;
+}
diff --git a/users/sterni/nix/flow/tests/default.nix b/users/sterni/nix/flow/tests/default.nix
new file mode 100644
index 000000000000..0bec4a3bd779
--- /dev/null
+++ b/users/sterni/nix/flow/tests/default.nix
@@ -0,0 +1,49 @@
+{ depot, ... }:
+
+let
+
+  inherit (depot.nix.runTestsuite)
+    runTestsuite
+    it
+    assertEq
+    assertThrows
+    ;
+
+  inherit (depot.users.sterni.nix.flow)
+    cond
+    match
+    ;
+
+  dontEval = builtins.throw "this should not get evaluated";
+
+  testCond = it "tests cond" [
+    (assertThrows "malformed cond list"
+      (cond [ [ true 1 2 ] [ false 1 ] ]))
+    (assertEq "last is true" "last"
+      (cond [
+        [ false dontEval]
+        [ false dontEval ]
+        [ true "last" ]
+      ]))
+    (assertEq "first is true" 1
+      (cond [
+        [ true 1 ]
+        [ true dontEval ]
+        [ true dontEval ]
+      ]))
+  ];
+
+  testMatch = it "tests match" [
+    (assertEq "basic match usage" 42
+      (match "answer" {
+        "answer" = 42;
+        "banana" = dontEval;
+        "maleur" = dontEval;
+      }))
+  ];
+
+in
+  runTestsuite "nix.flow" [
+    testCond
+    testMatch
+  ]