1 | const lodash = require('lodash');
|
2 | const { assert, format } = require('../util');
|
3 | const namedTuple = require('../util/namedTuple');
|
4 | const BaseCoder = require('./BaseCoder');
|
5 | const { pack, unpack } = require('./util');
|
6 |
|
7 | class TupleCoder extends BaseCoder {
|
8 | static from({ type, name, components }, abiCoder) {
|
9 | if (type !== 'tuple') {
|
10 | return undefined;
|
11 | }
|
12 | return new this({ name, coders: components.map(abiCoder) });
|
13 | }
|
14 |
|
15 | constructor({ name, coders }) {
|
16 | super({ name });
|
17 | this.type = `(${coders.map(coder => coder.type).join(',')})`;
|
18 | this.size = coders.length;
|
19 | this.coders = coders;
|
20 | this.dynamic = lodash.some(coders, coder => coder.dynamic);
|
21 | this.names = coders.map((coder, index) => coder.name || `${index}`);
|
22 | this.NamedTuple = namedTuple(...this.names);
|
23 | }
|
24 |
|
25 | |
26 |
|
27 |
|
28 |
|
29 | encode(array) {
|
30 | if (lodash.isPlainObject(array)) {
|
31 | array = this.NamedTuple.fromObject(array);
|
32 | }
|
33 |
|
34 | assert(Array.isArray(array), {
|
35 | message: 'unexpected type',
|
36 | expect: 'array',
|
37 | got: typeof array,
|
38 | coder: this,
|
39 | });
|
40 |
|
41 | assert(array.length === this.size, {
|
42 | message: 'length not match',
|
43 | expect: this.size,
|
44 | got: array.length,
|
45 | coder: this,
|
46 | });
|
47 |
|
48 | return pack(this.coders, array);
|
49 | }
|
50 |
|
51 | |
52 |
|
53 |
|
54 |
|
55 | decode(stream) {
|
56 | const array = unpack(this.coders, stream);
|
57 | return new this.NamedTuple(...array);
|
58 | }
|
59 |
|
60 | encodeIndex(value) {
|
61 | try {
|
62 | return format.hex64(value);
|
63 | } catch (e) {
|
64 | throw new Error('not supported encode tuple to index');
|
65 | }
|
66 | }
|
67 |
|
68 | decodeIndex(hex) {
|
69 | return hex;
|
70 | }
|
71 | }
|
72 |
|
73 | module.exports = TupleCoder;
|