Cater for higher-order tuples (#3851)
* Cater for higher-order tuples * IEnum
This commit is contained in:
@@ -55,14 +55,12 @@ const hh = registry.createType('[u128; 32]');
|
||||
assert(hh[0].bitLength(), 'All ok');
|
||||
|
||||
// tuple! ITuple<[u32, Compact<u64>, u128, Codec]>
|
||||
const tt1 = registry.createType('(u32, Compact< u64 >,u128, Something)');
|
||||
const tt1 = registry.createType('(u32, Compact< u64 >, u128 , Something)');
|
||||
// unwraps into a u32
|
||||
const tt2 = registry.createType('( u32 )');
|
||||
// max number of params
|
||||
const tt3 = registry.createType('(u8,u16,u32,u64,u128)');
|
||||
// lots and lots of params
|
||||
const tt4 = registry.createType('(u8,u16,u32,u64,u8,u16,u32,u64,u8,u16,u32,u64,u8,u16,u32,u64)');
|
||||
const tt4 = registry.createType('(u8,u16,u32,u64,u128,u256,Break,u256,u128,u64,u32,u16,u8)');
|
||||
// empty
|
||||
const tt5 = registry.createType('()');
|
||||
|
||||
assert(tt1[2].bitLength() && tt2.bitLength() && tt3[4].bitLength() && tt4[3].bitLength() && tt5.isEmpty, 'All ok');
|
||||
assert(tt1[2].bitLength() && tt2.bitLength() && tt4[3].bitLength() && tt5.isEmpty, 'All ok');
|
||||
|
||||
@@ -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 { assert, BN, BN_BILLION, BN_HUNDRED, BN_MILLION, BN_QUINTILL, BN_ZERO, bnToBn, bnToHex, bnToU8a, formatBalance, formatNumber, hexToBn, isHex, isString, isU8a, stringify, u8aToBn } from '@polkadot/util';
|
||||
@@ -60,7 +60,7 @@ function decodeAbstractInt (value: AnyNumber, bitLength: UIntBitLength, isNegati
|
||||
* @ignore
|
||||
* @noInheritDoc
|
||||
*/
|
||||
export abstract class AbstractInt extends BN implements Codec {
|
||||
export abstract class AbstractInt extends BN implements INumber {
|
||||
public readonly registry: Registry;
|
||||
|
||||
public createdAtHash?: Hash;
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { CodecHash, Hash } from '../interfaces';
|
||||
import type { AnyJson, AnyNumber, Constructor, ICompact, Registry } from '../types';
|
||||
import type { CompactEncodable } from './types';
|
||||
import type { AnyJson, AnyNumber, Constructor, ICompact, INumber, Registry } from '../types';
|
||||
|
||||
import { compactFromU8a, compactToU8a, isBigInt, isBn, isNumber, isString } from '@polkadot/util';
|
||||
|
||||
@@ -18,7 +17,7 @@ import { typeToConstructor } from './utils';
|
||||
* used by other types to add length-prefixed encoding, or in the case of wrapped types, taking
|
||||
* a number and making the compact representation thereof
|
||||
*/
|
||||
export class Compact<T extends CompactEncodable> implements ICompact<T> {
|
||||
export class Compact<T extends INumber> implements ICompact<T> {
|
||||
public readonly registry: Registry;
|
||||
|
||||
public createdAtHash?: Hash;
|
||||
@@ -33,7 +32,7 @@ export class Compact<T extends CompactEncodable> implements ICompact<T> {
|
||||
this.#raw = Compact.decodeCompact<T>(registry, this.#Type, value) as T;
|
||||
}
|
||||
|
||||
public static with<T extends CompactEncodable> (Type: Constructor<T> | string): Constructor<Compact<T>> {
|
||||
public static with<T extends INumber> (Type: Constructor<T> | string): Constructor<Compact<T>> {
|
||||
return class extends Compact<T> {
|
||||
constructor (registry: Registry, value?: Compact<T> | AnyNumber) {
|
||||
super(registry, Type, value);
|
||||
@@ -42,7 +41,7 @@ export class Compact<T extends CompactEncodable> implements ICompact<T> {
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public static decodeCompact<T extends CompactEncodable> (registry: Registry, Type: Constructor<T>, value: Compact<T> | AnyNumber): CompactEncodable {
|
||||
public static decodeCompact<T extends INumber> (registry: Registry, Type: Constructor<T>, value: Compact<T> | AnyNumber): INumber {
|
||||
if (value instanceof Compact) {
|
||||
return new Type(registry, value.#raw);
|
||||
} else if (isString(value) || isNumber(value) || isBn(value) || isBigInt(value)) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { CodecHash, Hash } from '../interfaces';
|
||||
import type { AnyJson, Codec, Constructor, Registry } from '../types';
|
||||
import type { AnyJson, Codec, Constructor, IEnum, Registry } from '../types';
|
||||
|
||||
import { assert, hexToU8a, isHex, isNumber, isObject, isString, isU8a, isUndefined, stringCamelCase, stringify, stringUpperFirst, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||
|
||||
@@ -160,10 +160,7 @@ function decodeEnum (registry: Registry, def: TypesDef, value?: any, index?: num
|
||||
* This implements an enum, that based on the value wraps a different type. It is effectively
|
||||
* an extension to enum where the value type is determined by the actual index.
|
||||
*/
|
||||
// TODO:
|
||||
// - As per Enum, actually use TS enum
|
||||
// - It should rather probably extend Enum instead of copying code
|
||||
export class Enum implements Codec {
|
||||
export class Enum implements IEnum {
|
||||
public readonly registry: Registry;
|
||||
|
||||
public createdAtHash?: Hash;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { CodecHash, Hash } from '../interfaces/runtime';
|
||||
import type { AnyJson, BareOpts, Codec, Constructor, ConstructorDef, Registry } from '../types';
|
||||
import type { AnyJson, BareOpts, Codec, Constructor, ConstructorDef, IStruct, Registry } from '../types';
|
||||
|
||||
import { assert, hexToU8a, isBoolean, isFunction, isHex, isObject, isU8a, isUndefined, stringCamelCase, stringify, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||
|
||||
@@ -136,7 +136,7 @@ export class Struct<
|
||||
// input values, mapped by key can be anything (construction)
|
||||
V extends { [K in keyof S]: any } = { [K in keyof S]: any },
|
||||
// type names, mapped by key, name of Class in S
|
||||
E extends { [K in keyof S]: string } = { [K in keyof S]: string }> extends Map<keyof S, Codec> implements Codec {
|
||||
E extends { [K in keyof S]: string } = { [K in keyof S]: string }> extends Map<keyof S, Codec> implements IStruct {
|
||||
public readonly registry: Registry;
|
||||
|
||||
public createdAtHash?: Hash;
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { Codec } from '../types';
|
||||
|
||||
export interface CompactEncodable extends Codec {
|
||||
bitLength (): number;
|
||||
toBigInt (): bigint;
|
||||
toBn (): BN;
|
||||
toNumber (): number;
|
||||
}
|
||||
|
||||
export type UIntBitLength = 8 | 16 | 32 | 64 | 128 | 256;
|
||||
|
||||
// The 520 here is a weird one - it is explicitly for a [u8; 65] as found as a EcdsaSignature,
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Compact, Option, Raw, Struct, Vec, VecFixed } from '../codec';
|
||||
import type { CompactEncodable } from '../codec/types';
|
||||
import type { Compact, Option, Raw, Vec, VecFixed } from '../codec';
|
||||
import type { Bytes } from '../primitive';
|
||||
import type { Codec, Constructor } from './codec';
|
||||
import type { ICompact, IOption, ITuple, IU8a, IVec } from './interfaces';
|
||||
import type { ICompact, IEnum, INumber, IOption, IStruct, ITuple, IU8a, IVec } from './interfaces';
|
||||
import type { InterfaceTypes } from './registry';
|
||||
|
||||
export type DetectCodec<T extends Codec, K extends string> = Expand<K, T>;
|
||||
export type DetectCodec<T extends Codec, K extends string> = __Expand<K, T>;
|
||||
|
||||
export type DetectConstructor<T extends Codec, K extends string> = Constructor<Expand<K, T>>;
|
||||
|
||||
export type Expand<K extends string, T extends Codec = Codec> = __Internal<Trim<K>, T>;
|
||||
export type DetectConstructor<T extends Codec, K extends string> = Constructor<__Expand<K, T>>;
|
||||
|
||||
// trim leading and trailing spaces
|
||||
export type Trim<K extends string> =
|
||||
@@ -22,40 +19,37 @@ export type Trim<K extends string> =
|
||||
? Trim<X>
|
||||
: K;
|
||||
|
||||
export type __DetectableTypes = CompactEncodable | ICompact<CompactEncodable> | IOption<Codec> | ITuple<Codec[]> | IU8a | IVec<Codec> | Struct;
|
||||
export type __Expand<K extends string, T extends Codec = Codec> = __Internal<Trim<K>, T>;
|
||||
|
||||
export type __Internal<K extends string, T extends Codec> =
|
||||
K extends keyof InterfaceTypes
|
||||
? InterfaceTypes[K]
|
||||
: T extends __DetectableTypes
|
||||
: T extends ICompact | IEnum | INumber | IOption | IStruct | ITuple | IU8a | IVec
|
||||
? T
|
||||
: __Unwrap<K, T>;
|
||||
|
||||
// ensure whatever we wrap is always Compact-capable
|
||||
export type __Compact<T extends Codec> =
|
||||
T extends CompactEncodable
|
||||
T extends INumber
|
||||
? Compact<T>
|
||||
: never;
|
||||
|
||||
// currently we only support 5 levels for auto-extract
|
||||
export type __Params<X extends string> =
|
||||
X extends `${infer A},${infer B}`
|
||||
? [__Expand<A>, ...__Params<B>]
|
||||
: [__Expand<X>];
|
||||
|
||||
export type __Tuple<X extends string, T extends Codec> =
|
||||
X extends `${infer A},${infer B},${infer C},${infer D},${infer E}`
|
||||
? ITuple<[Expand<A>, Expand<B>, Expand<C>, Expand<D>, Expand<E>]>
|
||||
: X extends `${infer A},${infer B},${infer C},${infer D}`
|
||||
? ITuple<[Expand<A>, Expand<B>, Expand<C>, Expand<D>]>
|
||||
: X extends `${infer A},${infer B},${infer C}`
|
||||
? ITuple<[Expand<A>, Expand<B>, Expand<C>]>
|
||||
: X extends `${infer A},${infer B}`
|
||||
? ITuple<[Expand<A>, Expand<B>]>
|
||||
: X extends `${infer A}`
|
||||
? Expand<A>
|
||||
: T;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
X extends `${infer A},${infer B}`
|
||||
? ITuple<__Params<X>>
|
||||
: __Expand<X, T>;
|
||||
|
||||
// vec support with short-circuit for u8
|
||||
export type __Vec<X extends string, T extends Codec> =
|
||||
Trim<X> extends 'u8'
|
||||
? Bytes
|
||||
: Vec<Expand<X, T>>;
|
||||
: Vec<__Expand<X, T>>;
|
||||
|
||||
// fixed vec support
|
||||
export type __VecFixed<X extends string> =
|
||||
@@ -63,14 +57,14 @@ export type __VecFixed<X extends string> =
|
||||
X extends `${infer Y};${infer _}`
|
||||
? Trim<Y> extends 'u8'
|
||||
? Raw
|
||||
: VecFixed<Expand<Y>>
|
||||
: VecFixed<__Expand<Y>>
|
||||
: never;
|
||||
|
||||
export type __Unwrap<K extends string, T extends Codec> =
|
||||
K extends `Compact<${infer X}>`
|
||||
? __Compact<Expand<X>>
|
||||
? __Compact<__Expand<X>>
|
||||
: K extends `Option<${infer X}>`
|
||||
? Option<Expand<X>>
|
||||
? Option<__Expand<X>>
|
||||
: K extends `Vec<${infer X}>`
|
||||
? __Vec<X, T>
|
||||
: K extends `[${infer X}]`
|
||||
|
||||
@@ -7,14 +7,30 @@ import type { FunctionMetadataLatest, StorageEntryMetadataLatest } from '../inte
|
||||
import type { Hash } from '../interfaces/runtime';
|
||||
import type { AnyTuple, ArgsDef, Codec } from './codec';
|
||||
|
||||
export interface ICompact<T extends Codec> extends Codec {
|
||||
export interface ICompact<T extends INumber = INumber> extends Codec {
|
||||
toBigInt (): bigint;
|
||||
toBn (): BN;
|
||||
toNumber (): number;
|
||||
unwrap (): T;
|
||||
}
|
||||
|
||||
export interface IOption<T extends Codec> extends Codec {
|
||||
export interface IEnum extends Codec {
|
||||
index: number;
|
||||
isBasic: boolean
|
||||
type: string;
|
||||
value: Codec;
|
||||
|
||||
toNumber (): number;
|
||||
}
|
||||
|
||||
export interface INumber extends Codec {
|
||||
bitLength (): number;
|
||||
toBigInt (): bigint;
|
||||
toBn (): BN;
|
||||
toNumber (): number;
|
||||
}
|
||||
|
||||
export interface IOption<T extends Codec = Codec> extends Codec {
|
||||
isNone: boolean;
|
||||
isSome: boolean;
|
||||
value: Codec;
|
||||
@@ -24,9 +40,11 @@ export interface IOption<T extends Codec> extends Codec {
|
||||
unwrapOrDefault (): T;
|
||||
}
|
||||
|
||||
export interface IStruct extends Map<unknown, Codec>, Codec {}
|
||||
|
||||
// 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> = S & Codec;
|
||||
export type ITuple<S extends AnyTuple = Codec[]> = S & Codec;
|
||||
|
||||
export interface IU8a extends Uint8Array, Codec {
|
||||
bitLength (): number;
|
||||
@@ -34,7 +52,7 @@ export interface IU8a extends Uint8Array, Codec {
|
||||
toJSON (): any;
|
||||
}
|
||||
|
||||
export type IVec<S extends Codec> = Array<S> & Codec;
|
||||
export interface IVec<S extends Codec = Codec> extends Array<S>, Codec {}
|
||||
|
||||
export interface IKeyringPair {
|
||||
address: string;
|
||||
|
||||
Reference in New Issue
Block a user