Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -890,4 +890,22 @@ rec {
nothing = tuple2 xs [];
just = n: splitAt n xs;
};

/* toTuple :: [a] -> tuple

Convert a list to a tuple. Supports lists of length 0-10.
Throws an error for lists longer than 10 elements.

> list.toTuple [1 2 3]
{ _0 = 1; _1 = 2; _2 = 3; }
> list.toTuple []
{ }
*/
toTuple = xs: let
len = length xs;
in
if len > 10 then
throw "toTuple: list length (${builtins.toString len}) exceeds maximum tuple size (10)"
else
builtins.listToAttrs (imap (i: x: { name = "_${builtins.toString i}"; value = x; }) xs);
}
1 change: 1 addition & 0 deletions test/sections/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
serde = import ./serde.nix;
set = import ./set.nix;
string = import ./string.nix;
tuple = import ./tuple.nix;
}
9 changes: 9 additions & 0 deletions test/sections/list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -305,4 +305,13 @@ section "std.list" {

break = assertEqual (tuple2 [ 2 4 6 ] [ 9 10 11 12 14 ])
(list.break num.odd [ 2 4 6 9 10 11 12 14 ]);

toTuple = string.unlines [
(assertEqual tuple.tuple0 (list.toTuple []))
(assertEqual (tuple.tuple1 1) (list.toTuple [1]))
(assertEqual (tuple.tuple2 1 2) (list.toTuple [1 2]))
(assertEqual (tuple.tuple3 "a" "b" "c") (list.toTuple ["a" "b" "c"]))
(assertEqual (tuple.tuple5 1 2 3 4 5) (list.toTuple [1 2 3 4 5]))
(assertEqual false (builtins.tryEval (list.toTuple [1 2 3 4 5 6 7 8 9 10 11])).success)
];
}
29 changes: 29 additions & 0 deletions test/sections/tuple.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
with { std = import ./../../default.nix; };
with std;

with (import ./../framework.nix);

section "std.tuple" {
toAttrset = string.unlines [
(assertEqual { x = 10; y = 20; } (tuple.toAttrset ["x" "y"] (tuple.tuple2 10 20)))
(assertEqual { a = 1; b = 2; c = 3; } (tuple.toAttrset ["a" "b" "c"] (tuple.tuple3 1 2 3)))
(assertEqual { foo = "hello"; } (tuple.toAttrset ["foo"] (tuple.tuple1 "hello")))
(assertEqual { } (tuple.toAttrset [ ] (tuple.tuple0)))
(assertEqual false (builtins.tryEval (tuple.toAttrset ["x" "y" "z"] (tuple.tuple2 10 20))).success)
(assertEqual false (builtins.tryEval (tuple.toAttrset ["x"] (tuple.tuple2 10 20))).success)
];

toPair = string.unlines [
(assertEqual { name = "x"; value = 10; } (tuple.toPair (tuple.tuple2 "x" 10)))
(assertEqual { name = "foo"; value = "bar"; } (tuple.toPair (tuple.tuple2 "foo" "bar")))
];

toList = string.unlines [
(assertEqual [] (tuple.toList tuple.tuple0))
(assertEqual [1] (tuple.toList (tuple.tuple1 1)))
(assertEqual [1 2] (tuple.toList (tuple.tuple2 1 2)))
(assertEqual [1 2 3] (tuple.toList (tuple.tuple3 1 2 3)))
(assertEqual ["a" "b" "c" "d"] (tuple.toList (tuple.tuple4 "a" "b" "c" "d")))
(assertEqual false (builtins.tryEval (tuple.toList { _0 = 1; _1 = 2; _2 = 3; _3 = 4; _4 = 5; _5 = 6; _6 = 7; _7 = 8; _8 = 9; _9 = 10; _10 = 11; })).success)
];
}
42 changes: 42 additions & 0 deletions tuple.nix
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
with rec {
list = import ./list.nix;
};

{
tuple0 = { };
tuple1 = _0: { inherit _0; };
Expand Down Expand Up @@ -39,4 +43,42 @@
Converts a 2-tuple to the argument required by e.g. `builtins.listToAttrs`
*/
toPair = { _0, _1 }: { name = _0; value = _1; };

/* toAttrset :: [string] -> tuple -> set

Converts a tuple to an attribute set using the given keys list.
The length of the keys list must match the tuple length.

> toAttrset ["x" "y"] (tuple2 10 20)
{ x = 10; y = 20; }
*/
toAttrset =
keysList: tuple: let
tupleLength = builtins.length (builtins.attrNames tuple);
keysLength = builtins.length keysList;
in
if keysLength != tupleLength then
throw "toAttrset: keysList length (${builtins.toString keysLength}) must equal tuple length (${builtins.toString tupleLength})"
else let
mapToKv = index: key: { name = key; value = tuple."_${builtins.toString index}"; };
listOfAttrs = list.imap mapToKv keysList;
in
builtins.listToAttrs listOfAttrs;

/* toList :: tuple -> [a]

Convert a tuple to a list. Supports tuples of size 0-10.

> tuple.toList (tuple2 1 2)
[1 2]
> tuple.toList tuple0
[]
*/
toList = tuple: let
tupleLength = builtins.length (builtins.attrNames tuple);
in
if tupleLength > 10 then
throw "toList: tuple size (${builtins.toString tupleLength}) exceeds maximum supported size (10)"
else
builtins.map (i: tuple."_${builtins.toString i}") (list.range 0 (tupleLength - 1));
}