diff options
Diffstat (limited to 'users/sterni/nix/flow')
-rw-r--r-- | users/sterni/nix/flow/default.nix | 54 | ||||
-rw-r--r-- | users/sterni/nix/flow/tests/default.nix | 49 |
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 + ] |