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 5641x 5641x 5641x 5641x 5641x 5641x 11857x 11857x 5641x 5641x 5641x 5641x 5641x 5641x 5641x 5641x                                                           5641x 5641x 4053x 4053x 4053x 5641x 5641x 4184x 4184x 5641x    
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);
    }
}