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 5600x 5600x 5600x 5600x 5600x 5600x 11809x 11809x 5600x 5600x 5600x 5600x 5600x 5600x 5600x 5600x                                                           5600x 5600x 4041x 4041x 4041x 5600x 5600x 4155x 4155x 5600x    
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);
    }
}