Use base interfaces for base Codec (#3870)

This commit is contained in:
Jaco
2021-08-12 17:32:25 +02:00
committed by GitHub
parent b594158275
commit ae21d13b23
10 changed files with 51 additions and 38 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ import { compareArray } from './utils/compareArray';
* specific encoding/decoding on top of the base type.
* @noInheritDoc
*/
export abstract class AbstractArray<T extends Codec> extends Array<T> implements IVec<Codec> {
export abstract class AbstractArray<T extends Codec> extends Array<T> implements IVec<T> {
public readonly registry: Registry;
public createdAtHash?: Hash;
+3 -3
View File
@@ -11,7 +11,7 @@ import { compareSet, decodeU8a, sortSet, typeToConstructor } from './utils';
const l = logger('BTreeSet');
/** @internal */
function decodeSetFromU8a<V extends Codec = Codec> (registry: Registry, ValClass: Constructor<V>, u8a: Uint8Array): Set<V> {
function decodeSetFromU8a<V extends Codec> (registry: Registry, ValClass: Constructor<V>, u8a: Uint8Array): Set<V> {
const output = new Set<V>();
const [offset, length] = compactFromU8a(u8a);
const types = [];
@@ -30,7 +30,7 @@ function decodeSetFromU8a<V extends Codec = Codec> (registry: Registry, ValClass
}
/** @internal */
function decodeSetFromSet<V extends Codec = Codec> (registry: Registry, ValClass: Constructor<V>, value: Set<any> | string[]): Set<V> {
function decodeSetFromSet<V extends Codec> (registry: Registry, ValClass: Constructor<V>, value: Set<any> | string[]): Set<V> {
const output = new Set<V>();
value.forEach((val: any) => {
@@ -60,7 +60,7 @@ function decodeSetFromSet<V extends Codec = Codec> (registry: Registry, ValClass
* @param jsonSet
* @internal
*/
function decodeSet<V extends Codec = Codec> (registry: Registry, valType: Constructor<V> | string, value?: Uint8Array | string | string[] | Set<any>): Set<V> {
function decodeSet<V extends Codec> (registry: Registry, valType: Constructor<V> | string, value?: Uint8Array | string | string[] | Set<any>): Set<V> {
if (!value) {
return new Set<V>();
}
+2 -2
View File
@@ -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;
+5 -5
View File
@@ -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<K extends Codec = Codec, V extends Codec = Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, u8a: Uint8Array): Map<K, V> {
function decodeMapFromU8a<K extends Codec, V extends Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, u8a: Uint8Array): Map<K, V> {
const output = new Map<K, V>();
const [offset, length] = compactFromU8a(u8a);
const types = [];
@@ -33,7 +33,7 @@ function decodeMapFromU8a<K extends Codec = Codec, V extends Codec = Codec> (reg
}
/** @internal */
function decodeMapFromMap<K extends Codec = Codec, V extends Codec = Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, value: Map<any, any>): Map<K, V> {
function decodeMapFromMap<K extends Codec, V extends Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, value: Map<any, any>): Map<K, V> {
const output = new Map<K, V>();
value.forEach((val: any, key: any) => {
@@ -75,7 +75,7 @@ function decodeMapFromMap<K extends Codec = Codec, V extends Codec = Codec> (reg
* @param jsonMap
* @internal
*/
function decodeMap<K extends Codec = Codec, V extends Codec = Codec> (registry: Registry, keyType: Constructor<K> | string, valType: Constructor<V> | string, value?: Uint8Array | string | Map<any, any>): Map<K, V> {
function decodeMap<K extends Codec, V extends Codec> (registry: Registry, keyType: Constructor<K> | string, valType: Constructor<V> | string, value?: Uint8Array | string | Map<any, any>): Map<K, V> {
const KeyClass = typeToConstructor(registry, keyType);
const ValClass = typeToConstructor(registry, valType);
@@ -92,7 +92,7 @@ function decodeMap<K extends Codec = Codec, V extends Codec = Codec> (registry:
throw new Error('Map: cannot decode type');
}
export class CodecMap<K extends Codec = Codec, V extends Codec = Codec> extends Map<K, V> implements Codec {
export class CodecMap<K extends Codec = Codec, V extends Codec = Codec> extends Map<K, V> implements IMap<K, V> {
public readonly registry: Registry;
public createdAtHash?: Hash;
+2 -2
View File
@@ -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<O extends Codec, E extends Codec> extends Enum {
export class Result<O extends Codec, E extends Codec> extends Enum implements IResult<O, E> {
constructor (registry: Registry, Ok: Constructor<O> | string, Err: Constructor<E> | string, value?: unknown) {
// NOTE This is order-dependent, Ok (with index 0) needs to be first
// eslint-disable-next-line sort-keys
+6 -8
View File
@@ -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<string[]>((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<string[]>((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<string> | 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<string> implements ISet {
public readonly registry: Registry;
@@ -98,13 +97,12 @@ export class CodecSet extends Set<string> 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)
});
});
}
+4 -8
View File
@@ -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, unknown> | unknown[] | string = {} as V, jsonMap: Map<keyof S, string> = 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));
}
/**
+1 -1
View File
@@ -54,7 +54,7 @@ export class Tuple extends AbstractArray<Codec> implements ITuple<Codec[]> {
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));
+2 -2
View File
@@ -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<T extends Codec, K extends string> =
@@ -12,7 +12,7 @@ export type DetectCodec<T extends Codec, K extends string> =
// 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<K>>[0]>>;
+25 -6
View File
@@ -15,6 +15,8 @@ export interface ICompact<T extends INumber = INumber> 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<K extends Codec = Codec, V extends Codec = Codec> extends Map<K, V>, Codec {}
export interface INumber extends Codec {
bitLength (): number;
toBigInt (): bigint;
@@ -40,24 +44,39 @@ export interface IOption<T extends Codec = Codec> extends Codec {
unwrapOrDefault (): T;
}
export interface ISet<K extends string = string> extends Set<K>, Codec {
export interface IResult<O extends Codec = Codec, E extends Codec = Codec> extends IEnum {
readonly asErr: E;
readonly asOk: O;
readonly isErr: boolean;
readonly isOk: boolean;
}
export interface ISet<K = string> extends Set<K>, Codec {
readonly strings: string[];
readonly valueEncoded: BN;
}
export interface IStruct<K extends string | number | symbol = string, V extends Codec = Codec> extends Map<K, V>, Codec {}
export interface IStruct<K = string, V extends Codec = Codec> extends Map<K, V>, Codec {
readonly defKeys: string[];
// A type alias for [Type1, Type2] & Codec, representing a tuple (Type1, Type2)
// FIXME Implement this generic <Sub> on Tuple.ts itself.
export type ITuple<S extends AnyTuple = Codec[]> = S & Codec;
getAtIndex (index: number): Codec
toArray (): Codec[];
}
export type ITuple<T extends AnyTuple = Codec[]> = T & Codec;
export interface IU8a extends Uint8Array, Codec {
readonly isAscii: boolean;
bitLength (): number;
toHuman (isExtended?: boolean): any;
toJSON (): any;
toUtf8 (): string;
}
export interface IVec<S extends Codec = Codec> extends Array<S>, Codec {}
export interface IVec<T extends Codec = Codec> extends Array<T>, Codec {
toArray (): T[];
}
export interface IKeyringPair {
readonly address: string;