Allow for Bounded* type usage (#3504)

* Allow for `Bounded*` type usage

* Adjust start index after found

* Adjust

* Add tests for bounded

* Bounded with length value

* adjust
This commit is contained in:
Jaco
2021-05-07 10:47:09 +02:00
committed by GitHub
parent dfeef40037
commit 12be027b18
3 changed files with 54 additions and 32 deletions
+1
View File
@@ -9,6 +9,7 @@ Contributed:
Changes:
- Allow for `Bounded*` type usage (as per latest Substrate)
- Adjust internal TS definitions for providers
+25 -11
View File
@@ -1,32 +1,32 @@
// Copyright 2017-2021 @polkadot/types authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { alias, removeColons } from './sanitize';
import { alias, removeBounded, removeColons } from './sanitize';
describe('sanitize', (): void => {
describe('alias', (): void => {
const exec = alias('String', 'Text');
const fn = alias('String', 'Text');
it('replaces all occurrences for types', (): void => {
expect(exec('(String,Address,MasterString,String)')).toEqual(
expect(fn('(String,Address,MasterString,String)')).toEqual(
'(Text,Address,MasterString,Text)'
);
});
it('replaces actual types, but leaves struct names', (): void => {
expect(exec('{"system":"String","versionString":"String"}')).toEqual(
expect(fn('{"system":"String","versionString":"String"}')).toEqual(
'{"system":"Text","versionString":"Text"}'
);
});
it('handles the preceding correctly', (): void => {
// NOTE This type doesn't make sense
expect(exec('String String (String,[String;32],String)"String<String>')).toEqual(
expect(fn('String String (String,[String;32],String)"String<String>')).toEqual(
'Text Text (Text,[Text;32],Text)"Text<Text>'
);
});
it('handles emdedded Vec/Tuples', (): void => {
it('handles embedded Vec/Tuples', (): void => {
const ann = alias('Announcement', 'ProxyAnnouncement');
expect(ann('(Vec<Announcement>,BalanceOf)')).toEqual(
@@ -36,24 +36,38 @@ describe('sanitize', (): void => {
});
describe('removeColons', (): void => {
const fn = removeColons();
it('removes preceding ::Text -> Text', (): void => {
expect(removeColons()('::Text')).toEqual('Text');
expect(fn('::Text')).toEqual('Text');
});
it('removes middle voting::TallyType -> TallyType', (): void => {
expect(removeColons()('voting::TallyType')).toEqual('TallyType');
expect(fn('voting::TallyType')).toEqual('TallyType');
});
it('removes on embedded values (one)', (): void => {
expect(removeColons()('(T::AccountId, SpanIndex)')).toEqual('(AccountId, SpanIndex)');
expect(fn('(T::AccountId, SpanIndex)')).toEqual('(AccountId, SpanIndex)');
});
it('removes on embedded values (all)', (): void => {
expect(removeColons()('(T::AccountId, slashing::SpanIndex)')).toEqual('(AccountId, SpanIndex)');
expect(fn('(T::AccountId, slashing::SpanIndex)')).toEqual('(AccountId, SpanIndex)');
});
it('keeps with allowNamespaces', (): void => {
expect(removeColons()('::slashing::SpanIndex', { allowNamespaces: true })).toEqual('slashing::SpanIndex');
expect(fn('::slashing::SpanIndex', { allowNamespaces: true })).toEqual('slashing::SpanIndex');
});
});
describe('bounded', (): void => {
const fn = removeBounded();
it('correctly cleans up bounded values', (): void => {
expect(fn('BoundedVec<u32, 256>')).toEqual('Vec<u32>');
});
it('correctly cleans up nested bounded values', (): void => {
expect(fn('BoundedBTreeMap<BoundedVec<BoundedVec<u32, 1>, 2>, BoundedBTreeSet<u32, BoundedVec<u64, 3>, 4>, 5>')).toEqual('BTreeMap<Vec<Vec<u32>>, BTreeSet<u32, Vec<u64>>>');
});
});
});
+28 -21
View File
@@ -7,7 +7,8 @@ interface SanitizeOptions {
type Mapper = (value: string, options?: SanitizeOptions) => string;
const ALLOWED_BOXES = ['BTreeMap', 'BTreeSet', 'Compact', 'DoNotConstruct', 'HashMap', 'Int', 'Linkage', 'Result', 'Option', 'UInt', 'Vec'];
const BOUNDED = ['BTreeMap', 'BTreeSet', 'HashMap', 'Vec'];
const ALLOWED_BOXES = BOUNDED.concat(['Compact', 'DoNotConstruct', 'Int', 'Linkage', 'Result', 'Option', 'UInt']);
const BOX_PRECEDING = ['<', '(', '[', '"', ',', ' ']; // start of vec, tuple, fixed array, part of struct def or in tuple
const mappings: Mapper[] = [
@@ -17,7 +18,7 @@ const mappings: Mapper[] = [
// <T::Balance as HasCompact>
cleanupCompact(),
// Change BoundedVec<Type, Size> to Vec<Type>
removeBoundedVec(),
removeBounded(),
// Remove all the trait prefixes
removeTraits(),
// remove PairOf<T> -> (T, T)
@@ -77,14 +78,12 @@ export function alias (src: string, dest: string, withChecks = true): Mapper {
export function cleanupCompact (): Mapper {
return (value: string): string => {
for (let index = 0; index < value.length; index++) {
if (value[index] !== '<') {
continue;
}
if (value[index] === '<') {
const end = findClosing(value, index + 1) - 14;
const end = findClosing(value, index + 1) - 14;
if (value.substr(end, 14) === ' as HasCompact') {
value = `Compact<${value.substr(index + 1, end - index - 1)}>`;
if (value.substr(end, 14) === ' as HasCompact') {
value = `Compact<${value.substr(index + 1, end - index - 1)}>`;
}
}
}
@@ -98,24 +97,32 @@ export function flattenSingleTuple (): Mapper {
}
function replaceTagWith (value: string, matcher: string, replacer: (inner: string) => string): string {
for (let index = 0; index < value.length; index++) {
if (value.substr(index, matcher.length) === matcher) {
const start = index + matcher.length;
const end = findClosing(value, start);
let index = -1;
value = `${value.substr(0, index)}${replacer(value.substr(start, end - start))}${value.substr(end + 1)}`;
while (true) {
index = value.indexOf(matcher, index + 1);
if (index === -1) {
return value;
}
}
return value;
const start = index + matcher.length;
const end = findClosing(value, start);
value = `${value.substr(0, index)}${replacer(value.substr(start, end - start))}${value.substr(end + 1)}`;
}
}
// remove the BoundedVec wrappers
export function removeBoundedVec (): Mapper {
const replacer = (inner: string) => `Vec<${inner.split(',')[0]}>`;
// remove the Bounded* wrappers
export function removeBounded (): Mapper {
return (value: string) =>
replaceTagWith(value, 'BoundedVec<', replacer);
BOUNDED.reduce((value, tag) =>
replaceTagWith(value, `Bounded${tag}<`, (inner: string): string => {
const parts = inner.split(',');
return `${tag}<${parts.filter((_, i) => i !== parts.length - 1).join(',')}>`;
}), value
);
}
export function removeColons (): Mapper {