UNPKG

1.81 kBJavaScriptView Raw
1const lodash = require('lodash');
2const { assert, format } = require('../util');
3const namedTuple = require('../util/namedTuple');
4const BaseCoder = require('./BaseCoder');
5const { pack, unpack } = require('./util');
6
7class 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 * @param array {array}
27 * @return {Buffer}
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 * @param stream {HexStream}
53 * @return {NamedTuple}
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
73module.exports = TupleCoder;