From ae21d13b230dd1944fd03af5ce3f4883dc17f2a0 Mon Sep 17 00:00:00 2001 From: Jaco Date: Thu, 12 Aug 2021 18:32:25 +0300 Subject: [PATCH] Use base interfaces for base Codec (#3870) --- packages/types/src/codec/AbstractArray.ts | 2 +- packages/types/src/codec/BTreeSet.ts | 6 ++--- packages/types/src/codec/Date.ts | 4 +-- packages/types/src/codec/Map.ts | 10 ++++---- packages/types/src/codec/Result.ts | 4 +-- packages/types/src/codec/Set.ts | 14 +++++----- packages/types/src/codec/Struct.ts | 12 +++------ packages/types/src/codec/Tuple.ts | 2 +- packages/types/src/types/detect.ts | 4 +-- packages/types/src/types/interfaces.ts | 31 ++++++++++++++++++----- 10 files changed, 51 insertions(+), 38 deletions(-) diff --git a/packages/types/src/codec/AbstractArray.ts b/packages/types/src/codec/AbstractArray.ts index 7b06074a4a..75a0ea9f01 100644 --- a/packages/types/src/codec/AbstractArray.ts +++ b/packages/types/src/codec/AbstractArray.ts @@ -15,7 +15,7 @@ import { compareArray } from './utils/compareArray'; * specific encoding/decoding on top of the base type. * @noInheritDoc */ -export abstract class AbstractArray extends Array implements IVec { +export abstract class AbstractArray extends Array implements IVec { public readonly registry: Registry; public createdAtHash?: Hash; diff --git a/packages/types/src/codec/BTreeSet.ts b/packages/types/src/codec/BTreeSet.ts index 914653bd49..756645bf9e 100644 --- a/packages/types/src/codec/BTreeSet.ts +++ b/packages/types/src/codec/BTreeSet.ts @@ -11,7 +11,7 @@ import { compareSet, decodeU8a, sortSet, typeToConstructor } from './utils'; const l = logger('BTreeSet'); /** @internal */ -function decodeSetFromU8a (registry: Registry, ValClass: Constructor, u8a: Uint8Array): Set { +function decodeSetFromU8a (registry: Registry, ValClass: Constructor, u8a: Uint8Array): Set { const output = new Set(); const [offset, length] = compactFromU8a(u8a); const types = []; @@ -30,7 +30,7 @@ function decodeSetFromU8a (registry: Registry, ValClass } /** @internal */ -function decodeSetFromSet (registry: Registry, ValClass: Constructor, value: Set | string[]): Set { +function decodeSetFromSet (registry: Registry, ValClass: Constructor, value: Set | string[]): Set { const output = new Set(); value.forEach((val: any) => { @@ -60,7 +60,7 @@ function decodeSetFromSet (registry: Registry, ValClass * @param jsonSet * @internal */ -function decodeSet (registry: Registry, valType: Constructor | string, value?: Uint8Array | string | string[] | Set): Set { +function decodeSet (registry: Registry, valType: Constructor | string, value?: Uint8Array | string | string[] | Set): Set { if (!value) { return new Set(); } diff --git a/packages/types/src/codec/Date.ts b/packages/types/src/codec/Date.ts index 616825ddab..44f1ca8328 100644 --- a/packages/types/src/codec/Date.ts +++ b/packages/types/src/codec/Date.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { CodecHash, Hash } from '../interfaces/runtime'; -import type { AnyNumber, Codec, Registry } from '../types'; +import type { AnyNumber, INumber, Registry } from '../types'; import type { UIntBitLength } from './types'; import { BN, bnToBn, bnToHex, bnToU8a, isString, isU8a, u8aToBn } from '@polkadot/util'; @@ -33,7 +33,7 @@ function decodeDate (value: CodecDate | Date | AnyNumber): Date { * and has all the methods available that are applicable to any `Date` * @noInheritDoc */ -export class CodecDate extends Date implements Codec { +export class CodecDate extends Date implements INumber { public readonly registry: Registry; public createdAtHash?: Hash; diff --git a/packages/types/src/codec/Map.ts b/packages/types/src/codec/Map.ts index a1c4424b04..1d24f97ad7 100644 --- a/packages/types/src/codec/Map.ts +++ b/packages/types/src/codec/Map.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { CodecHash, Hash } from '../interfaces/runtime'; -import type { AnyJson, Codec, Constructor, Registry } from '../types'; +import type { AnyJson, Codec, Constructor, IMap, Registry } from '../types'; import { compactFromU8a, compactToU8a, isHex, isObject, isU8a, logger, stringify, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util'; @@ -14,7 +14,7 @@ import { compareMap, decodeU8a, sortMap, typeToConstructor } from './utils'; const l = logger('Map'); /** @internal */ -function decodeMapFromU8a (registry: Registry, KeyClass: Constructor, ValClass: Constructor, u8a: Uint8Array): Map { +function decodeMapFromU8a (registry: Registry, KeyClass: Constructor, ValClass: Constructor, u8a: Uint8Array): Map { const output = new Map(); const [offset, length] = compactFromU8a(u8a); const types = []; @@ -33,7 +33,7 @@ function decodeMapFromU8a (reg } /** @internal */ -function decodeMapFromMap (registry: Registry, KeyClass: Constructor, ValClass: Constructor, value: Map): Map { +function decodeMapFromMap (registry: Registry, KeyClass: Constructor, ValClass: Constructor, value: Map): Map { const output = new Map(); value.forEach((val: any, key: any) => { @@ -75,7 +75,7 @@ function decodeMapFromMap (reg * @param jsonMap * @internal */ -function decodeMap (registry: Registry, keyType: Constructor | string, valType: Constructor | string, value?: Uint8Array | string | Map): Map { +function decodeMap (registry: Registry, keyType: Constructor | string, valType: Constructor | string, value?: Uint8Array | string | Map): Map { const KeyClass = typeToConstructor(registry, keyType); const ValClass = typeToConstructor(registry, valType); @@ -92,7 +92,7 @@ function decodeMap (registry: throw new Error('Map: cannot decode type'); } -export class CodecMap extends Map implements Codec { +export class CodecMap extends Map implements IMap { public readonly registry: Registry; public createdAtHash?: Hash; diff --git a/packages/types/src/codec/Result.ts b/packages/types/src/codec/Result.ts index 2ba5ff0ace..1f2214edcb 100644 --- a/packages/types/src/codec/Result.ts +++ b/packages/types/src/codec/Result.ts @@ -1,7 +1,7 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Codec, Constructor, Registry } from '../types'; +import type { Codec, Constructor, IResult, Registry } from '../types'; import { assert } from '@polkadot/util'; @@ -12,7 +12,7 @@ import { Enum } from './Enum'; * @description * A Result maps to the Rust Result type, that can either wrap a success or error value */ -export class Result extends Enum { +export class Result extends Enum implements IResult { constructor (registry: Registry, Ok: Constructor | string, Err: Constructor | string, value?: unknown) { // NOTE This is order-dependent, Ok (with index 0) needs to be first // eslint-disable-next-line sort-keys diff --git a/packages/types/src/codec/Set.ts b/packages/types/src/codec/Set.ts index 24b798c63b..4b1f9ee7f7 100644 --- a/packages/types/src/codec/Set.ts +++ b/packages/types/src/codec/Set.ts @@ -18,25 +18,25 @@ function encodeSet (setValues: SetValues, value: string[]): BN { /** @internal */ function decodeSetArray (setValues: SetValues, value: string[]): string[] { - return value.reduce((result, key): string[] => { + return value.reduce((result, key): string[] => { assert(!isUndefined(setValues[key]), () => `Set: Invalid key '${key}' passed to Set, allowed ${Object.keys(setValues).join(', ')}`); result.push(key); return result; - }, [] as string[]); + }, []); } /** @internal */ function decodeSetNumber (setValues: SetValues, _value: BN | number): string[] { const bn = bnToBn(_value); - const result = Object.keys(setValues).reduce((result, key): string[] => { + const result = Object.keys(setValues).reduce((result, key): string[] => { if (bn.and(bnToBn(setValues[key])).eq(bnToBn(setValues[key]))) { result.push(key); } return result; - }, [] as string[]); + }, []); const computed = encodeSet(setValues, result); @@ -74,7 +74,6 @@ function decodeSet (setValues: SetValues, value: string[] | Set | Uint8A * An Set is an array of string values, represented an an encoded type by * a bitwise representation of the values. */ -// FIXME This is a prime candidate to extend the JavaScript built-in Set export class CodecSet extends Set implements ISet { public readonly registry: Registry; @@ -98,13 +97,12 @@ export class CodecSet extends Set implements ISet { super(registry, values, value as undefined, bitLength); Object.keys(values).forEach((_key): void => { - const name = stringUpperFirst(stringCamelCase(_key)); - const iskey = `is${name}`; + const iskey = `is${stringUpperFirst(stringCamelCase(_key))}`; isUndefined(this[iskey as keyof this]) && Object.defineProperty(this, iskey, { enumerable: true, - get: (): boolean => this.strings.includes(_key) + get: () => this.strings.includes(_key) }); }); } diff --git a/packages/types/src/codec/Struct.ts b/packages/types/src/codec/Struct.ts index 448bf9d045..ef80e3c95d 100644 --- a/packages/types/src/codec/Struct.ts +++ b/packages/types/src/codec/Struct.ts @@ -147,9 +147,7 @@ export class Struct< // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment constructor (registry: Registry, Types: S, value: V | Map | unknown[] | string = {} as V, jsonMap: Map = new Map()) { - super(Object.entries( - decodeStruct(registry, mapToTypeMap(registry, Types), value, jsonMap) - ) as [keyof S, Codec][]); + super(Object.entries(decodeStruct(registry, mapToTypeMap(registry, Types), value, jsonMap))); this.registry = registry; this.#jsonMap = jsonMap; @@ -181,7 +179,7 @@ export class Struct< } /** - * @description The available keys for this enum + * @description The available keys for this struct */ public get defKeys (): string[] { return Object.keys(this.#Types); @@ -207,7 +205,7 @@ export class Struct< */ public get Type (): E { return (Object - .entries(this.#Types) as [keyof S, Constructor][]) + .entries(this.#Types)) .reduce((result: E, [key, Type]): E => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access (result as any)[key] = new Type(this.registry).toRawType(); @@ -301,9 +299,7 @@ export class Struct< * @description Returns the base runtime type name for this instance */ public toRawType (): string { - return stringify( - Struct.typesToMap(this.registry, this.#Types) - ); + return stringify(Struct.typesToMap(this.registry, this.#Types)); } /** diff --git a/packages/types/src/codec/Tuple.ts b/packages/types/src/codec/Tuple.ts index 3915064b4c..f980bc3ee0 100644 --- a/packages/types/src/codec/Tuple.ts +++ b/packages/types/src/codec/Tuple.ts @@ -54,7 +54,7 @@ export class Tuple extends AbstractArray implements ITuple { constructor (registry: Registry, Types: TupleTypes, value?: AnyTuple) { const Clazzes = Array.isArray(Types) - ? Types.map((type): Constructor => typeToConstructor(registry, type)) + ? Types.map((t) => typeToConstructor(registry, t)) : mapToTypeMap(registry, Types); super(registry, ...decodeTuple(registry, Clazzes, value)); diff --git a/packages/types/src/types/detect.ts b/packages/types/src/types/detect.ts index c1bbde832d..86ee448bbc 100644 --- a/packages/types/src/types/detect.ts +++ b/packages/types/src/types/detect.ts @@ -4,7 +4,7 @@ import type { Compact, Option, Raw, Vec, VecFixed } from '../codec'; import type { Bytes, Null } from '../primitive'; import type { Codec, Constructor } from './codec'; -import type { ICompact, IEnum, INumber, IOption, ISet, IStruct, ITuple, IU8a, IVec } from './interfaces'; +import type { ICompact, IEnum, IMap, IMethod, INumber, IOption, IResult, ISet, IStruct, ITuple, IU8a, IVec } from './interfaces'; import type { InterfaceTypes } from './registry'; export type DetectCodec = @@ -12,7 +12,7 @@ export type DetectCodec = // it does work (as evident with checkTypes) and is problematic the other way around K extends keyof InterfaceTypes ? InterfaceTypes[K] - : T extends ICompact | IEnum | INumber | IOption | ISet | IStruct | ITuple | IU8a | IVec + : T extends ICompact | IEnum | IMap | IMethod | INumber | IOption | IResult | ISet | IStruct | ITuple | IU8a | IVec ? T : __ExtractCodec<__ToCodecs<__Tokenize<__Sanitize>[0]>>; diff --git a/packages/types/src/types/interfaces.ts b/packages/types/src/types/interfaces.ts index 79be8ffb14..b915535e53 100644 --- a/packages/types/src/types/interfaces.ts +++ b/packages/types/src/types/interfaces.ts @@ -15,6 +15,8 @@ export interface ICompact extends Codec { } export interface IEnum extends Codec { + readonly defIndexes: number[]; + readonly defKeys: string[]; readonly index: number; readonly isBasic: boolean readonly type: string; @@ -23,6 +25,8 @@ export interface IEnum extends Codec { toNumber (): number; } +export interface IMap extends Map, Codec {} + export interface INumber extends Codec { bitLength (): number; toBigInt (): bigint; @@ -40,24 +44,39 @@ export interface IOption extends Codec { unwrapOrDefault (): T; } -export interface ISet extends Set, Codec { +export interface IResult extends IEnum { + readonly asErr: E; + readonly asOk: O; + readonly isErr: boolean; + readonly isOk: boolean; +} + +export interface ISet extends Set, Codec { readonly strings: string[]; readonly valueEncoded: BN; } -export interface IStruct extends Map, Codec {} +export interface IStruct extends Map, Codec { + readonly defKeys: string[]; -// A type alias for [Type1, Type2] & Codec, representing a tuple (Type1, Type2) -// FIXME Implement this generic on Tuple.ts itself. -export type ITuple = S & Codec; + getAtIndex (index: number): Codec + toArray (): Codec[]; +} + +export type ITuple = T & Codec; export interface IU8a extends Uint8Array, Codec { + readonly isAscii: boolean; + bitLength (): number; toHuman (isExtended?: boolean): any; toJSON (): any; + toUtf8 (): string; } -export interface IVec extends Array, Codec {} +export interface IVec extends Array, Codec { + toArray (): T[]; +} export interface IKeyringPair { readonly address: string;