Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Move `H160`, `H256` & `H512` to interfaces in `@polkadot/types/interfaces`
- Align construction of unknown types via `registry.get` e.g. in Events, warn on detection, throw on use
- Expose static with on `UInt`, `Int` & `U8aFixed` classes with optional type name override
- Support for arbitrary UInt types via `UInt<bitLength>` definitions

# 1.3.1 Feb 18, 2020

Expand Down
8 changes: 8 additions & 0 deletions packages/typegen/src/generate/tsDef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ function tsStruct (definitions: object, { name: structName, sub }: TypeDef, impo
return exportInterface(structName, 'Struct', keys.join(''));
}

/** @internal */
function tsUInt (definitions: object, def: TypeDef, imports: TypeImports): string {
setImports(definitions, imports, ['UInt']);

return exportInterface(def.name, 'UInt');
}

/** @internal */
function tsVec (definitions: object, def: TypeDef, imports: TypeImports): string {
const type = def.info === TypeDefInfo.VecFixed
Expand Down Expand Up @@ -155,6 +162,7 @@ function generateInterfaces (definitions: object, { types }: { types: Record<str
[TypeDefInfo.Set]: tsSet,
[TypeDefInfo.Struct]: tsStruct,
[TypeDefInfo.Tuple]: tsTuple,
[TypeDefInfo.UInt]: tsUInt,
[TypeDefInfo.Vec]: tsVec,
[TypeDefInfo.VecFixed]: tsVec
};
Expand Down
11 changes: 10 additions & 1 deletion packages/types/src/codec/utils/encodeTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.

import { TypeDef, TypeDefInfo, TypeDefExtVecFixed } from '../../create/types';
import { TypeDef, TypeDefInfo, TypeDefExtUInt, TypeDefExtVecFixed } from '../../create/types';

import { assert } from '@polkadot/util';

Expand Down Expand Up @@ -103,6 +103,14 @@ function encodeTuple (typeDef: Pick<TypeDef, any>): string {
})`;
}

function encodeUInt (typeDef: Pick<TypeDef, any>): string {
assert(typeDef.ext, 'Unable to encode VecFixed type');

const { length } = typeDef.ext as TypeDefExtUInt;

return `UInt<${length}>`;
}

function encodeVecFixed (typeDef: Pick<TypeDef, any>): string {
assert(typeDef.ext, 'Unable to encode VecFixed type');

Expand All @@ -127,6 +135,7 @@ const encoders: Record<TypeDefInfo, (typeDef: TypeDef) => string> = {
[TypeDefInfo.Set]: (typeDef: TypeDef): string => typeDef.type,
[TypeDefInfo.Struct]: (typeDef: TypeDef): string => encodeStruct(typeDef),
[TypeDefInfo.Tuple]: (typeDef: TypeDef): string => encodeTuple(typeDef),
[TypeDefInfo.UInt]: (typeDef: TypeDef): string => encodeUInt(typeDef),
[TypeDefInfo.Vec]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'Vec'),
[TypeDefInfo.VecFixed]: (typeDef: TypeDef): string => encodeVecFixed(typeDef)
};
Expand Down
11 changes: 10 additions & 1 deletion packages/types/src/create/createClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.

import { Codec, Constructor, InterfaceTypes, Registry } from '../types';
import { FromReg, TypeDef, TypeDefExtVecFixed, TypeDefInfo } from './types';
import { FromReg, TypeDef, TypeDefExtUInt, TypeDefExtVecFixed, TypeDefInfo } from './types';

import { assert } from '@polkadot/util';

Expand All @@ -17,6 +17,7 @@ import CodecSet from '../codec/Set';
import Struct from '../codec/Struct';
import Tuple from '../codec/Tuple';
import U8aFixed, { BitLength as U8aFixedBitLength } from '../codec/U8aFixed';
import UInt from '../codec/UInt';
import Vec from '../codec/Vec';
import VecFixed from '../codec/VecFixed';
import { InterfaceRegistry } from '../interfaceRegistry';
Expand Down Expand Up @@ -132,6 +133,14 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C

[TypeDefInfo.Tuple]: (registry: Registry, value: TypeDef): Constructor => Tuple.with(getTypeClassArray(value)),

[TypeDefInfo.UInt]: (registry: Registry, value: TypeDef): Constructor => {
assert(value.ext, 'Expected bitLength information for UInt<bitLength>');

const ext = value.ext as TypeDefExtUInt;

return UInt.with(ext.length, ext.typeName);
},

[TypeDefInfo.Vec]: (registry: Registry, value: TypeDef): Constructor => {
const subType = getSubType(value);

Expand Down
50 changes: 32 additions & 18 deletions packages/types/src/create/createType.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ describe('createType', (): void => {
});

it('allows creation of a Struct', (): void => {
expect(
createTypeUnsafe(registry, '{"balance":"Balance","index":"u32"}', [{
balance: 1234,
index: '0x10'
}]).toJSON()
).toEqual({
const raw = '{"balance":"Balance","index":"u32"}';
const struct = createTypeUnsafe(registry, raw, [{
balance: 1234,
index: '0x10'
}]);

expect(struct.toJSON()).toEqual({
balance: 1234,
index: 16
});
expect(struct.toRawType()).toEqual(raw);
});

it('allows creation of a BTreeMap', (): void => {
Expand All @@ -41,18 +43,6 @@ describe('createType', (): void => {
).toEqual('[2,24,30,80]');
});

it('allows creation of a Result', (): void => {
expect(
createTypeUnsafe(registry, 'Result<u32,Text>', ['0x011064656667']).toJSON()
).toEqual({ Error: 'defg' });
});

it('allows creation of a Tuple', (): void => {
expect(
createTypeUnsafe(registry, '(Balance,u32)', [[1234, 5678]]).toJSON()
).toEqual([1234, 5678]);
});

it('allows creation of a Enum (simple)', (): void => {
expect(
createTypeUnsafe(registry, '{"_enum": ["A", "B", "C"]}', [1]).toJSON()
Expand All @@ -65,12 +55,36 @@ describe('createType', (): void => {
).toEqual({ B: 0 });
});

it('allows creation of a Result', (): void => {
expect(
createTypeUnsafe(registry, 'Result<u32,Text>', ['0x011064656667']).toJSON()
).toEqual({ Error: 'defg' });
});

it('allows creation of a Set', (): void => {
expect(
createTypeUnsafe<CodecSet>(registry, '{"_set": { "A": 1, "B": 2, "C": 4, "D": 8, "E": 16, "G": 32, "H": 64, "I": 128 } }', [1 + 4 + 16 + 64]).strings
).toEqual(['A', 'C', 'E', 'H']);
});

it('allows creation of a Tuple', (): void => {
expect(
createTypeUnsafe(registry, '(Balance,u32)', [[1234, 5678]]).toJSON()
).toEqual([1234, 5678]);
});

it('allows creation for a UInt<bitLength>', (): void => {
expect(
createTypeUnsafe(registry, 'UInt<2048>').toRawType()
).toEqual('u2048');
});

it('fails creation for a UInt<bitLength> where bitLength is not power of 8', (): void => {
expect(
() => createTypeUnsafe(registry, 'UInt<20>').toRawType()
).toThrow('UInt<20>: Only support for UInt<bitLength>, where length <= 8192 and a power of 8');
});

it('allows creation of a [u8; 8]', (): void => {
expect(
createTypeUnsafe(registry, '[u8; 8]', [[0x12, 0x00, 0x23, 0x00, 0x45, 0x00, 0x67, 0x00]]).toHex()
Expand Down
19 changes: 17 additions & 2 deletions packages/types/src/create/getTypeDef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.

import { TypeDef, TypeDefExtVecFixed, TypeDefInfo } from './types';
import { TypeDef, TypeDefExtUInt, TypeDefExtVecFixed, TypeDefInfo } from './types';

import { assert } from '@polkadot/util';

Expand Down Expand Up @@ -90,6 +90,20 @@ function _decodeTuple (value: TypeDef, _: string, subType: string): TypeDef {
return value;
}

// decode a fixed vector, e.g. [u8;32]
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function _decodeUInt (value: TypeDef, type: string, _: string): TypeDef {
const _bitLength = type.substr(5, type.length - 6);
const length = parseInt(_bitLength.trim(), 10);

// as a first round, only u8 via u8aFixed, we can add more support
assert(length <= 8192 && (length % 8) === 0, `${type}: Only support for UInt<bitLength>, where length <= 8192 and a power of 8`);

value.ext = { length } as TypeDefExtUInt;

return value;
}

function hasWrapper (type: string, [start, end]: [string, string, TypeDefInfo, any?]): boolean {
if (type.substr(0, start.length) !== start) {
return false;
Expand All @@ -106,7 +120,8 @@ const nestedExtraction: [string, string, TypeDefInfo, (value: TypeDef, type: str
['(', ')', TypeDefInfo.Tuple, _decodeTuple],
// the inner for these are the same as tuple, multiple values
['BTreeMap<', '>', TypeDefInfo.BTreeMap, _decodeTuple],
['Result<', '>', TypeDefInfo.Result, _decodeTuple]
['Result<', '>', TypeDefInfo.Result, _decodeTuple],
['UInt<', '>', TypeDefInfo.UInt, _decodeUInt]
];

const wrappedExtraction: [string, string, TypeDefInfo][] = [
Expand Down
2 changes: 1 addition & 1 deletion packages/types/src/create/sanitize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

type Mapper = (value: string) => string;

const ALLOWED_BOXES = ['BTreeMap', 'BTreeSet', 'Compact', 'Linkage', 'Result', 'Option', 'Vec'];
const ALLOWED_BOXES = ['BTreeMap', 'BTreeSet', 'Compact', 'Linkage', 'Result', 'Option', 'UInt', 'Vec'];
const BOX_PRECEDING = ['<', '(', '[', '"', ',', ' ']; // start of vec, tuple, fixed array, part of struct def or in tuple

const mappings: Mapper[] = [
Expand Down
9 changes: 8 additions & 1 deletion packages/types/src/create/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.

import { UIntBitLength } from '../codec/AbstractInt';
import { Codec, InterfaceTypes } from '../types';

import { InterfaceRegistry } from '../interfaceRegistry';
Expand All @@ -25,10 +26,16 @@ export enum TypeDefInfo {
Tuple,
Vec,
VecFixed,
UInt,
// anything not fully supported (keep this as the last entry)
Null
}

export interface TypeDefExtUInt {
length: UIntBitLength;
typeName?: string;
}

export interface TypeDefExtVecFixed {
length: number;
rawName?: string;
Expand All @@ -43,7 +50,7 @@ export interface TypeDef {
info: TypeDefInfo;
index?: number;
displayName?: string;
ext?: TypeDefExtVecFixed | TypeDefExtEnumDiscriminant; // add additional here as required
ext?: TypeDefExtEnumDiscriminant | TypeDefExtUInt | TypeDefExtVecFixed; // add additional here as required
name?: string;
namespace?: string;
params?: TypeDef[];
Expand Down