VecFixed now take sub, align ext with UInt (#1909)

* Allow nested definitions for fixed arrays

* Comment nested test

* Don't import U8aFixed + u8
This commit is contained in:
Jaco Greeff
2020-02-20 21:36:12 +01:00
committed by GitHub
parent dd0a31803f
commit 1c1bfb295d
9 changed files with 62 additions and 39 deletions
@@ -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 { Registry, TypeDef, TypeDefInfo, TypeDefExtVecFixed } from '@polkadot/types/types';
import { Registry, TypeDef, TypeDefInfo } from '@polkadot/types/types';
import { getTypeDef } from '@polkadot/types/create';
@@ -20,10 +20,8 @@ function extractTypes (types: string[]): any[] {
case TypeDefInfo.Compact:
case TypeDefInfo.Option:
case TypeDefInfo.Vec:
return extractTypes([(decoded.sub as TypeDef).type]);
case TypeDefInfo.VecFixed:
return extractTypes([(decoded.ext as TypeDefExtVecFixed).type]);
return extractTypes([(decoded.sub as TypeDef).type]);
case TypeDefInfo.BTreeMap:
case TypeDefInfo.BTreeSet:
+2 -4
View File
@@ -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 '@polkadot/types/create/types';
import { TypeDef, TypeDefInfo } from '@polkadot/types/create/types';
import fs from 'fs';
import path from 'path';
@@ -135,9 +135,7 @@ function tsUInt (definitions: object, def: TypeDef, imports: TypeImports): strin
/** @internal */
function tsVec (definitions: object, def: TypeDef, imports: TypeImports): string {
const type = def.info === TypeDefInfo.VecFixed
? (def.ext as TypeDefExtVecFixed).type
: (def.sub as TypeDef).type;
const type = (def.sub as TypeDef).type;
if (def.info === TypeDefInfo.VecFixed && type === 'u8') {
setImports(definitions, imports, ['U8aFixed']);
+6 -3
View File
@@ -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 '@polkadot/types/create/types';
import { TypeDef, TypeDefInfo } from '@polkadot/types/create/types';
import { getTypeDef } from '@polkadot/types/create';
import { paramsNotation } from '@polkadot/types/codec/utils';
@@ -170,14 +170,17 @@ export function formatType (definitions: object, type: string | TypeDef, imports
);
}
case TypeDefInfo.VecFixed: {
if ((typeDef.ext as TypeDefExtVecFixed).type === 'u8') {
const type = (typeDef.sub as TypeDef).type;
if (type === 'u8') {
setImports(definitions, imports, ['U8aFixed']);
return 'U8aFixed';
}
setImports(definitions, imports, ['Vec']);
return formatVec(formatType(definitions, (typeDef.ext as TypeDefExtVecFixed).type, imports));
return formatVec(formatType(definitions, type, imports));
}
case TypeDefInfo.BTreeMap: {
setImports(definitions, imports, ['BTreeMap']);
+1 -1
View File
@@ -60,7 +60,7 @@ export function setImports (allDefs: object, imports: TypeImports, types: string
// TypeDef.sub is a `TypeDef | TypeDef[]`
if (Array.isArray(typeDef.sub)) {
typeDef.sub.forEach((subType): void => setImports(allDefs, imports, [subType.type]));
} else if (typeDef.sub) {
} else if (typeDef.sub && (typeDef.info !== TypeDefInfo.VecFixed || typeDef.sub.type !== 'u8')) {
// typeDef.sub is a TypeDef in this case
setImports(allDefs, imports, [typeDef.sub.type]);
}
@@ -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, TypeDefExtUInt, TypeDefExtVecFixed } from '../../create/types';
import { TypeDef, TypeDefInfo, TypeDefExtLength } from '../../create/types';
import { assert } from '@polkadot/util';
@@ -106,7 +106,7 @@ function encodeTuple (typeDef: Pick<TypeDef, any>): string {
function encodeUInt (typeDef: Pick<TypeDef, any>, type: 'Int' | 'UInt'): string {
assert(typeDef.ext, 'Unable to encode VecFixed type');
const { length } = typeDef.ext as TypeDefExtUInt;
const { length } = typeDef.ext as TypeDefExtLength;
return `${type}<${length}>`;
}
@@ -114,7 +114,8 @@ function encodeUInt (typeDef: Pick<TypeDef, any>, type: 'Int' | 'UInt'): string
function encodeVecFixed (typeDef: Pick<TypeDef, any>): string {
assert(typeDef.ext, 'Unable to encode VecFixed type');
const { type, length } = typeDef.ext as TypeDefExtVecFixed;
const { length } = typeDef.ext as TypeDefExtLength;
const { type } = typeDef.sub as TypeDef;
return `[${type};${length}]`;
}
+9 -7
View File
@@ -3,10 +3,11 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { Codec, Constructor, InterfaceTypes, Registry } from '../types';
import { FromReg, TypeDef, TypeDefExtUInt, TypeDefExtVecFixed, TypeDefInfo } from './types';
import { FromReg, TypeDef, TypeDefExtLength, TypeDefInfo } from './types';
import { assert } from '@polkadot/util';
import { UIntBitLength } from '../codec/AbstractInt';
import BTreeMap from '../codec/BTreeMap';
import BTreeSet from '../codec/BTreeSet';
import Compact from '../codec/Compact';
@@ -80,9 +81,9 @@ function getTypeClassArray (value: TypeDef): (InterfaceTypes)[] {
function createInt (value: TypeDef, Clazz: typeof Int | typeof UInt): Constructor {
assert(value.ext, `Expected bitLength information for ${Clazz.constructor.name}<bitLength>`);
const ext = value.ext as TypeDefExtUInt;
const { length } = value.ext as TypeDefExtLength;
return Clazz.with(ext.length, ext.typeName);
return Clazz.with(length as UIntBitLength, value.displayName);
}
const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => Constructor> = {
@@ -159,12 +160,13 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
[TypeDefInfo.VecFixed]: (registry: Registry, value: TypeDef): Constructor => {
assert(value.ext, 'Expected length & type information for fixed vector');
const ext = value.ext as TypeDefExtVecFixed;
const { length } = value.ext as TypeDefExtLength;
const sub = value.sub as TypeDef;
return (
ext.type === 'u8'
? U8aFixed.with((ext.length * 8) as U8aFixedBitLength, ext.rawName)
: VecFixed.with(ext.type as InterfaceTypes, ext.length)
sub.type === 'u8'
? U8aFixed.with((length * 8) as U8aFixedBitLength, value.displayName)
: VecFixed.with(sub.type as InterfaceTypes, length)
);
}
};
@@ -265,4 +265,29 @@ describe('getTypeDef', (): void => {
]
});
});
// FIXME - not handled atm
it.skip('creates a nested fixed vec', (): void => {
expect(
getTypeDef('[[u8;32];3]')
).toEqual({
info: TypeDefInfo.VecFixed,
type: '[[u8;32];3]',
ext: {
length: 3,
type: '[u8;32]'
},
sub: {
info: TypeDefInfo.VecFixed,
type: '[u8;32]',
ext: {
length: 32
},
sub: {
info: TypeDefInfo.Plain,
type: 'u8'
}
}
});
});
});
+11 -7
View File
@@ -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, TypeDefExtUInt, TypeDefExtVecFixed, TypeDefInfo } from './types';
import { TypeDef, TypeDefExtLength, TypeDefInfo } from './types';
import { assert } from '@polkadot/util';
@@ -67,13 +67,16 @@ function _decodeStruct (value: TypeDef, type: string, _: string): TypeDef {
// decode a fixed vector, e.g. [u8;32]
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function _decodeFixedVec (value: TypeDef, type: string, _: string): TypeDef {
const [vecType, _vecLen, rawName] = type.substr(1, type.length - 2).split(';');
const vecLen = parseInt(_vecLen.trim(), 10);
const [vecType, strLength, displayName] = type.substr(1, type.length - 2).split(';');
const length = parseInt(strLength.trim(), 10);
// as a first round, only u8 via u8aFixed, we can add more support
assert(vecLen <= 256, `${type}: Only support for [Type; <length>], where length <= 256`);
assert(length <= 256, `${type}: Only support for [Type; <length>], where length <= 256`);
value.ext = { length: vecLen, rawName, type: vecType } as TypeDefExtVecFixed;
value.displayName = displayName;
value.ext = { length } as TypeDefExtLength;
// eslint-disable-next-line @typescript-eslint/no-use-before-define
value.sub = getTypeDef(vecType);
return value;
}
@@ -93,13 +96,14 @@ function _decodeTuple (value: TypeDef, _: string, subType: string): TypeDef {
// decode a Int/UInt<bitLength[, name]>
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function _decodeInt (value: TypeDef, type: string, _: string, clazz: 'Int' | 'UInt' = 'Int'): TypeDef {
const [strLength, typeName] = type.substr(clazz.length + 1, type.length - clazz.length - 1 - 1).split(',');
const [strLength, displayName] = type.substr(clazz.length + 1, type.length - clazz.length - 1 - 1).split(',');
const length = parseInt(strLength.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 ${clazz}<bitLength>, where length <= 8192 and a power of 8, found ${length}`);
value.ext = { length, typeName } as TypeDefExtUInt;
value.displayName = displayName;
value.ext = { length } as TypeDefExtLength;
return value;
}
+2 -10
View File
@@ -2,7 +2,6 @@
// 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';
@@ -32,15 +31,8 @@ export enum TypeDefInfo {
Null
}
export interface TypeDefExtUInt {
length: UIntBitLength;
typeName?: string;
}
export interface TypeDefExtVecFixed {
export interface TypeDefExtLength {
length: number;
rawName?: string;
type: string;
}
export interface TypeDefExtEnumDiscriminant {
@@ -51,7 +43,7 @@ export interface TypeDef {
info: TypeDefInfo;
index?: number;
displayName?: string;
ext?: TypeDefExtEnumDiscriminant | TypeDefExtUInt | TypeDefExtVecFixed; // add additional here as required
ext?: TypeDefExtEnumDiscriminant | TypeDefExtLength; // add additional here as required
name?: string;
namespace?: string;
params?: TypeDef[];