All files / ethers.js/src.ts/abi/coders tuple.ts

57.35% Statements 39/68
100% Branches 6/6
80% Functions 4/5
57.35% Lines 39/68

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 701x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5629x 5629x 5629x 5629x 5629x 5629x 11845x 11845x 5629x 5629x 5629x 5629x 5629x 5629x 5629x 5629x                                                           5629x 5629x 4051x 4051x 4051x 5629x 5629x 4174x 4174x 5629x    
import { defineProperties } from "../../utils/properties.js";
 
import { Typed } from "../typed.js";
import { Coder } from "./abstract-coder.js";
 
import { pack, unpack } from "./array.js";
 
import type { Reader, Writer } from "./abstract-coder.js";
 
/**
 *  @_ignore
 */
export class TupleCoder extends Coder {
    readonly coders!: ReadonlyArray<Coder>;
 
    constructor(coders: Array<Coder>, localName: string) {
        let dynamic = false;
        const types: Array<string> = [];
        coders.forEach((coder) => {
            if (coder.dynamic) { dynamic = true; }
            types.push(coder.type);
        });
        const type = ("tuple(" + types.join(",") + ")");
 
        super("tuple", type, localName, dynamic);
        defineProperties<TupleCoder>(this, { coders: Object.freeze(coders.slice()) });
    }
 
    defaultValue(): any {
        const values: any = [ ];
        this.coders.forEach((coder) => {
            values.push(coder.defaultValue());
        });

        // We only output named properties for uniquely named coders
        const uniqueNames = this.coders.reduce((accum, coder) => {
            const name = coder.localName;
            if (name) {
                if (!accum[name]) { accum[name] = 0; }
                accum[name]++;
            }
            return accum;
        }, <{ [ name: string ]: number }>{ });

        // Add named values
        this.coders.forEach((coder: Coder, index: number) => {
            let name = coder.localName;
            if (!name || uniqueNames[name] !== 1) { return; }

            if (name === "length") { name = "_length"; }

            if (values[name] != null) { return; }

            values[name] = values[index];
        });

        return Object.freeze(values);
    }
 
    encode(writer: Writer, _value: Array<any> | { [ name: string ]: any } | Typed): number {
        const value = Typed.dereference(_value, "tuple");
        return pack(writer, this.coders, value);
    }
 
    decode(reader: Reader): any {
        return unpack(reader, this.coders);
    }
}