-
Notifications
You must be signed in to change notification settings - Fork 1
/
tuples.test.ts
91 lines (84 loc) · 1.94 KB
/
tuples.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { expect, test } from "vitest";
import { Codec, fields, map, number, tuple } from "../index.js";
test("decoding tuples", () => {
type PointTuple = [number, number];
const data: unknown = [50, 325];
// If you want a quick way to decode the above into `[number, number]`, use `tuple`.
const pointTupleCodec1: Codec<PointTuple> = tuple([number, number]);
expect(pointTupleCodec1.decoder(data)).toMatchInlineSnapshot(`
{
"tag": "Valid",
"value": [
50,
325,
],
}
`);
// If you’d rather produce an object like the following, use `tuple` with `map`.
type Point = {
x: number;
y: number;
};
const pointCodec: Codec<Point> = map(tuple([number, number]), {
decoder: ([x, y]) => ({
x,
y,
}),
encoder: ({ x, y }) => [x, y] as const,
});
expect(pointCodec.decoder(data)).toMatchInlineSnapshot(`
{
"tag": "Valid",
"value": {
"x": 50,
"y": 325,
},
}
`);
expect(pointCodec.encoder({ x: 50, y: 325 })).toMatchInlineSnapshot(`
[
50,
325,
]
`);
// `tuple` works with any number of values. Here’s an example with four values:
expect(tuple([number, number, number, number]).decoder([1, 2, 3, 4]))
.toMatchInlineSnapshot(`
{
"tag": "Valid",
"value": [
1,
2,
3,
4,
],
}
`);
// You can of course decode an object to a tuple as well:
const obj: unknown = { x: 1, y: 2 };
const pointTupleCodec: Codec<PointTuple> = map(
fields({
x: number,
y: number,
}),
{
decoder: ({ x, y }) => [x, y],
encoder: ([x, y]) => ({ x, y }),
},
);
expect(pointTupleCodec.decoder(obj)).toMatchInlineSnapshot(`
{
"tag": "Valid",
"value": [
1,
2,
],
}
`);
expect(pointTupleCodec.encoder([1, 2])).toMatchInlineSnapshot(`
{
"x": 1,
"y": 2,
}
`);
});