Adjustments for getTypeDef (#4944)

* Adjustments for getTypeDef

* Cleanup unneeded +

* Adjust sanitize replacers

* Ordering

* Adjust sanitize
This commit is contained in:
Jaco
2022-06-17 11:29:01 +03:00
committed by GitHub
parent 6149b6ca76
commit 51b583d9ea
7 changed files with 60 additions and 75 deletions
+6 -6
View File
@@ -1,6 +1,7 @@
// Copyright 2017-2022 @polkadot/types-create authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { AnyString } from '@polkadot/types-codec/types';
import type { TypeDef } from '@polkadot/types-create/types';
import { sanitize } from '@polkadot/types-codec';
@@ -15,6 +16,8 @@ interface TypeDefOptions {
}
const MAX_NESTED = 64;
const MAX_FIX_LEN = 2048;
const MAX_BIT_LEN = 8192;
const KNOWN_INTERNALS = ['_alias', '_fallback'];
function getTypeString (typeOrObj: any): string {
@@ -132,8 +135,7 @@ function _decodeFixedVec (value: TypeDef, type: string, _: string, count: number
const [strLength, displayName] = type.substring(index + 1, max).split(';');
const length = parseInt(strLength.trim(), 10);
// as a first round, only u8 via u8aFixed, we can add more support
assert(length <= 256, () => `${type}: Only support for [Type; <length>], where length <= 256`);
assert(length <= MAX_FIX_LEN, () => `${type}: Only support for [Type; <length>], where length <= ${MAX_FIX_LEN}`);
value.displayName = displayName;
value.length = length;
@@ -157,8 +159,7 @@ function _decodeAnyInt (value: TypeDef, type: string, _: string, clazz: 'Int' |
const [strLength, displayName] = type.substring(clazz.length + 1, type.length - 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}`);
assert(length <= MAX_BIT_LEN && (length % 8) === 0, () => `${type}: Only support for ${clazz}<bitLength>, where length <= ${MAX_BIT_LEN} and a power of 8, found ${length}`);
value.displayName = displayName;
value.length = length;
@@ -216,8 +217,7 @@ function extractSubType (type: string, [start, end]: [string, string, TypeDefInf
return type.substring(start.length, type.length - end.length);
}
// eslint-disable-next-line @typescript-eslint/ban-types
export function getTypeDef (_type: String | string, { displayName, name }: TypeDefOptions = {}, count = 0): TypeDef {
export function getTypeDef (_type: AnyString, { displayName, name }: TypeDefOptions = {}, count = 0): TypeDef {
// create the type via Type, allowing types to be sanitized
const type = sanitize(_type);
const value: TypeDef = { displayName, info: TypeDefInfo.Plain, name, type };
@@ -36,13 +36,13 @@ describe('typeSplit', (): void => {
it('checks for unclosed vec', (): void => {
expect(
(): string[] => typeSplit('Text, Vec<u64')
() => typeSplit('Text, Vec<u64')
).toThrow(/Invalid definition/);
});
it('checks for unclosed tuple', (): void => {
expect(
(): string[] => typeSplit('Text, (u64, u32')
() => typeSplit('Text, (u64, u32')
).toThrow(/Invalid definition/);
});
});
+29 -24
View File
@@ -3,46 +3,51 @@
import { assert } from '@polkadot/util';
function isNotNested (...counters: number[]): boolean {
return !counters.some((counter): boolean => counter !== 0);
}
// safely split a string on ', ' while taking care of any nested occurences
export function typeSplit (type: string): string[] {
let [cDepth, fDepth, sDepth, tDepth, start] = [0, 0, 0, 0, 0];
const result = [];
const result: string[] = [];
const extract = (index: number): void => {
if (isNotNested(cDepth, fDepth, sDepth, tDepth)) {
result.push(type.substring(start, index).trim());
start = index + 1;
}
};
// these are the depths of the various tokens: <, [, {, (
let c = 0;
let f = 0;
let s = 0;
let t = 0;
for (let index = 0; index < type.length; index++) {
switch (type[index]) {
// current start position
let start = 0;
for (let i = 0; i < type.length; i++) {
switch (type[i]) {
// if we are not nested, add the type
case ',': extract(index); break;
case ',': {
if (!(c || f || s || t)) {
result.push(type.substring(start, i).trim());
start = i + 1;
}
break;
}
// adjust compact/vec (and friends) depth
case '<': cDepth++; break;
case '>': cDepth--; break;
case '<': c++; break;
case '>': c--; break;
// adjust fixed vec depths
case '[': fDepth++; break;
case ']': fDepth--; break;
case '[': f++; break;
case ']': f--; break;
// adjust struct depth
case '{': sDepth++; break;
case '}': sDepth--; break;
case '{': s++; break;
case '}': s--; break;
// adjust tuple depth
case '(': tDepth++; break;
case ')': tDepth--; break;
case '(': t++; break;
case ')': t--; break;
}
}
assert(isNotNested(cDepth, fDepth, sDepth, tDepth), () => `Invalid definition (missing terminators) found in ${type}`);
// ensure we have all the terminators taken care of
assert(!(c || f || s || t), () => `Invalid definition (missing terminators) found in ${type}`);
// the final leg of the journey
result.push(type.substring(start, type.length).trim());