Add BTreeSet<V> Codec (#1639)
* add BTreeSet Codec * Add following BTreeMap * fix linting * fix linting * add validate Types and encode Types * type def info is incremented. * fix compareSet
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,49 +1,49 @@
|
||||
[
|
||||
{
|
||||
"info": 7,
|
||||
"info": 8,
|
||||
"type": "{\"value\": {\"cell\": {\"cell\": ([u8;32])}}}",
|
||||
"name": "Flipper",
|
||||
"namespace": "flipper::normal",
|
||||
"sub": [
|
||||
{
|
||||
"info": 7,
|
||||
"info": 8,
|
||||
"type": "{\"cell\": {\"cell\": ([u8;32])}}",
|
||||
"name": "value",
|
||||
"namespace": "ink_core::storage::value",
|
||||
"params": [
|
||||
{
|
||||
"info": 5,
|
||||
"info": 6,
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"sub": [
|
||||
{
|
||||
"info": 7,
|
||||
"info": 8,
|
||||
"type": "{\"cell\": ([u8;32])}",
|
||||
"name": "cell",
|
||||
"namespace": "ink_core::storage::cell::sync_cell",
|
||||
"params": [
|
||||
{
|
||||
"info": 5,
|
||||
"info": 6,
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"sub": [
|
||||
{
|
||||
"info": 8,
|
||||
"info": 9,
|
||||
"type": "([u8;32])",
|
||||
"name": "cell",
|
||||
"namespace": "ink_core::storage::key",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
"info": 11,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": ""
|
||||
},
|
||||
"sub": {
|
||||
"info": 5,
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
"index": 0
|
||||
@@ -57,44 +57,44 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"info": 7,
|
||||
"info": 8,
|
||||
"type": "{\"cell\": {\"cell\": ([u8;32])}}",
|
||||
"name": "Value",
|
||||
"namespace": "ink_core::storage::value",
|
||||
"params": [
|
||||
{
|
||||
"info": 5,
|
||||
"info": 6,
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"sub": [
|
||||
{
|
||||
"info": 7,
|
||||
"info": 8,
|
||||
"type": "{\"cell\": ([u8;32])}",
|
||||
"name": "cell",
|
||||
"namespace": "ink_core::storage::cell::sync_cell",
|
||||
"params": [
|
||||
{
|
||||
"info": 5,
|
||||
"info": 6,
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"sub": [
|
||||
{
|
||||
"info": 8,
|
||||
"info": 9,
|
||||
"type": "([u8;32])",
|
||||
"name": "cell",
|
||||
"namespace": "ink_core::storage::key",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
"info": 11,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": ""
|
||||
},
|
||||
"sub": {
|
||||
"info": 5,
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
"index": 0
|
||||
@@ -106,36 +106,36 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"info": 5,
|
||||
"info": 6,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"info": 7,
|
||||
"info": 8,
|
||||
"type": "{\"cell\": ([u8;32])}",
|
||||
"name": "SyncCell",
|
||||
"namespace": "ink_core::storage::cell::sync_cell",
|
||||
"params": [
|
||||
{
|
||||
"info": 5,
|
||||
"info": 6,
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"sub": [
|
||||
{
|
||||
"info": 8,
|
||||
"info": 9,
|
||||
"type": "([u8;32])",
|
||||
"name": "cell",
|
||||
"namespace": "ink_core::storage::key",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
"info": 11,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": ""
|
||||
},
|
||||
"sub": {
|
||||
"info": 5,
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
"index": 0
|
||||
@@ -145,20 +145,20 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"info": 8,
|
||||
"info": 9,
|
||||
"type": "([u8;32])",
|
||||
"name": "Key",
|
||||
"namespace": "ink_core::storage::key",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
"info": 11,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": ""
|
||||
},
|
||||
"sub": {
|
||||
"info": 5,
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
"index": 0
|
||||
@@ -166,19 +166,19 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"info": 10,
|
||||
"info": 11,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": ""
|
||||
},
|
||||
"sub": {
|
||||
"info": 5,
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"info": 5,
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
}
|
||||
]
|
||||
@@ -1,29 +1,29 @@
|
||||
[
|
||||
{
|
||||
"info": 9,
|
||||
"info": 10,
|
||||
"type": "{ \"value\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\"} }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"info": 10,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"info": 10,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
"info": 11,
|
||||
"type": "([u8;32])",
|
||||
"sub": [
|
||||
{
|
||||
"info": 12,
|
||||
"info": 13,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "u8"
|
||||
},
|
||||
"index": 0
|
||||
@@ -37,7 +37,7 @@
|
||||
"namespace": "ink_core::storage::cell::sync_cell",
|
||||
"params": [
|
||||
{
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "u32"
|
||||
}
|
||||
]
|
||||
@@ -47,7 +47,7 @@
|
||||
"namespace": "ink_core::storage::value",
|
||||
"params": [
|
||||
{
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "u32"
|
||||
}
|
||||
]
|
||||
@@ -57,26 +57,26 @@
|
||||
"namespace": "incrementer::normal"
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"info": 10,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"info": 10,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
"info": 11,
|
||||
"type": "([u8;32])",
|
||||
"sub": [
|
||||
{
|
||||
"info": 12,
|
||||
"info": 13,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "u8"
|
||||
},
|
||||
"index": 0
|
||||
@@ -90,7 +90,7 @@
|
||||
"namespace": "ink_core::storage::cell::sync_cell",
|
||||
"params": [
|
||||
{
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "u32"
|
||||
}
|
||||
]
|
||||
@@ -100,32 +100,32 @@
|
||||
"namespace": "ink_core::storage::value",
|
||||
"params": [
|
||||
{
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "u32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "u32"
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"info": 10,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
"info": 11,
|
||||
"type": "([u8;32])",
|
||||
"sub": [
|
||||
{
|
||||
"info": 12,
|
||||
"info": 13,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "u8"
|
||||
},
|
||||
"index": 0
|
||||
@@ -139,24 +139,24 @@
|
||||
"namespace": "ink_core::storage::cell::sync_cell",
|
||||
"params": [
|
||||
{
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "u32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"info": 10,
|
||||
"info": 11,
|
||||
"type": "([u8;32])",
|
||||
"sub": [
|
||||
{
|
||||
"info": 12,
|
||||
"info": 13,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "u8"
|
||||
},
|
||||
"index": 0
|
||||
@@ -166,23 +166,23 @@
|
||||
"namespace": "ink_core::storage::key"
|
||||
},
|
||||
{
|
||||
"info": 12,
|
||||
"info": 13,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "u8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"info": 7,
|
||||
"type": "bool"
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,7 @@ function extractTypes (types: string[]): any[] {
|
||||
return extractTypes([(decoded.ext as TypeDefExtVecFixed).type]);
|
||||
|
||||
case TypeDefInfo.BTreeMap:
|
||||
case TypeDefInfo.BTreeSet:
|
||||
case TypeDefInfo.Result:
|
||||
case TypeDefInfo.Tuple:
|
||||
return extractTypes((decoded.sub as TypeDef[]).map((sub): string => sub.type));
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { TypeRegistry } from '../codec';
|
||||
import Text from '../primitive/Text';
|
||||
import U32 from '../primitive/U32';
|
||||
import Struct from './Struct';
|
||||
import { CodecTo } from '../types';
|
||||
|
||||
import BTreeSet from './BTreeSet';
|
||||
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
const mockU32Set = new Set<U32>();
|
||||
mockU32Set.add(new U32(registry, 2));
|
||||
mockU32Set.add(new U32(registry, 24));
|
||||
mockU32Set.add(new U32(registry, 30));
|
||||
mockU32Set.add(new U32(registry, 80));
|
||||
const mockU32SetString = '[2,24,30,80]';
|
||||
const mockU32SetObject = [2, 24, 30, 80];
|
||||
const mockU32SetHexString = '0x1002000000180000001e00000050000000';
|
||||
const mockU32SetUint8Array = Uint8Array.from([16, 2, 0, 0, 0, 24, 0, 0, 0, 30, 0, 0, 0, 80, 0, 0, 0]);
|
||||
|
||||
describe('BTreeSet', (): void => {
|
||||
describe('decoding', (): void => {
|
||||
const testDecode = (type: string, input: any, output: string): void =>
|
||||
it(`can decode from ${type}`, (): void => {
|
||||
const s = new BTreeSet(registry, U32, input);
|
||||
|
||||
expect(s.toString()).toBe(output);
|
||||
});
|
||||
|
||||
testDecode('Set', mockU32Set, mockU32SetString);
|
||||
testDecode('hex', mockU32SetHexString, mockU32SetString);
|
||||
testDecode('Uint8Array', mockU32SetUint8Array, mockU32SetString);
|
||||
|
||||
testDecode('Set', mockU32Set, mockU32SetString);
|
||||
testDecode('hex', mockU32SetHexString, mockU32SetString);
|
||||
testDecode('Uint8Array', mockU32SetUint8Array, mockU32SetString);
|
||||
});
|
||||
|
||||
describe('encoding muple values', (): void => {
|
||||
const testEncode = (to: CodecTo, expected: any): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
const s = new BTreeSet(registry, U32, mockU32Set);
|
||||
expect(s[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
testEncode('toHex', mockU32SetHexString);
|
||||
testEncode('toJSON', mockU32SetObject);
|
||||
testEncode('toU8a', mockU32SetUint8Array);
|
||||
testEncode('toString', mockU32SetString);
|
||||
});
|
||||
|
||||
it('decodes null', (): void => {
|
||||
expect(
|
||||
new (
|
||||
BTreeSet.with(U32)
|
||||
)(registry, null).toString()
|
||||
).toEqual('[]');
|
||||
});
|
||||
|
||||
it('decodes within more complicated types', (): void => {
|
||||
const s = new Struct(registry, {
|
||||
placeholder: U32,
|
||||
value: BTreeSet.with(U32)
|
||||
});
|
||||
s.set('value', new BTreeSet(registry, U32, mockU32Set));
|
||||
expect(s.toString()).toBe('{"placeholder":0,"value":[2,24,30,80]}');
|
||||
});
|
||||
|
||||
it('throws when it cannot decode', (): void => {
|
||||
expect(
|
||||
(): BTreeSet<U32> => new (
|
||||
BTreeSet.with(U32)
|
||||
)(registry, 'ABC')
|
||||
).toThrowError(/BTreeSet: cannot decode type/);
|
||||
});
|
||||
|
||||
it('correctly encodes length', (): void => {
|
||||
expect(
|
||||
new (
|
||||
BTreeSet.with(U32))(registry, mockU32Set).encodedLength
|
||||
).toEqual(17);
|
||||
});
|
||||
|
||||
it('generates sane toRawTypes', (): void => {
|
||||
expect(new (BTreeSet.with(U32))(registry).toRawType()).toBe('BTreeSet<u32>');
|
||||
expect(new (BTreeSet.with(Text))(registry).toRawType()).toBe('BTreeSet<Text>');
|
||||
expect(new (BTreeSet.with(Struct.with({ a: U32, b: Text })))(registry).toRawType())
|
||||
.toBe('BTreeSet<{"a":"u32","b":"Text"}>');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,182 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AnyJsonArray, Constructor, Codec, IHash, InterfaceTypes, Registry } from '../types';
|
||||
|
||||
import { isHex, hexToU8a, isU8a, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
import { blake2AsU8a } from '@polkadot/util-crypto';
|
||||
|
||||
import Compact from './Compact';
|
||||
import U8a from './U8aFixed';
|
||||
import { compareSet, decodeU8a, typeToConstructor } from './utils';
|
||||
|
||||
export default class BTreeSet<V extends Codec = Codec> extends Set<V> implements Codec {
|
||||
public readonly registry: Registry;
|
||||
|
||||
protected _ValClass: Constructor<V>;
|
||||
|
||||
constructor (registry: Registry, valType: Constructor<V> | InterfaceTypes, rawValue: any) {
|
||||
const ValClass = typeToConstructor(registry, valType);
|
||||
|
||||
super(BTreeSet.decodeBTreeSet(registry, ValClass, rawValue));
|
||||
|
||||
this.registry = registry;
|
||||
this._ValClass = ValClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode input to pass into constructor.
|
||||
*
|
||||
* @param ValClass - Type of the map value
|
||||
* @param value - Value to decode, one of:
|
||||
* - null
|
||||
* - undefined
|
||||
* - hex
|
||||
* - Uint8Array
|
||||
* - Set<any>, where both key and value types are either
|
||||
* constructors or decodeable values for their types.
|
||||
* @param jsonSet
|
||||
*/
|
||||
private static decodeBTreeSet<V extends Codec = Codec> (registry: Registry, ValClass: Constructor<V>, value: Uint8Array | string | Set<any>): Set<V> {
|
||||
if (!value) {
|
||||
return new Set<V>();
|
||||
} else if (isHex(value)) {
|
||||
return BTreeSet.decodeBTreeSet(registry, ValClass, hexToU8a(value));
|
||||
} else if (isU8a(value)) {
|
||||
return BTreeSet.decodeBTreeSetFromU8a<V>(registry, ValClass, u8aToU8a(value));
|
||||
} else if (value instanceof Set) {
|
||||
return BTreeSet.decodeBTreeSetFromSet<V>(registry, ValClass, value);
|
||||
}
|
||||
|
||||
throw new Error('BTreeSet: cannot decode type');
|
||||
}
|
||||
|
||||
private static decodeBTreeSetFromU8a<V extends Codec = Codec> (registry: Registry, ValClass: Constructor<V>, u8a: Uint8Array): Set<V> {
|
||||
const output = new Set<V>();
|
||||
const [offset, length] = Compact.decodeU8a(u8a);
|
||||
const types = [];
|
||||
|
||||
for (let i = 0; i < length.toNumber(); i++) {
|
||||
types.push(ValClass);
|
||||
}
|
||||
|
||||
const values = decodeU8a(registry, u8a.subarray(offset), types);
|
||||
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
output.add(values[i] as V);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
private static decodeBTreeSetFromSet<V extends Codec = Codec> (registry: Registry, ValClass: Constructor<V>, value: Set<any>): Set<V> {
|
||||
const output = new Set<V>();
|
||||
|
||||
value.forEach((v: any) => {
|
||||
let val;
|
||||
try {
|
||||
val = (v instanceof ValClass) ? v : new ValClass(registry, v);
|
||||
} catch (error) {
|
||||
console.error('Failed to decode BTreeSet key or value:', error.message);
|
||||
throw error;
|
||||
}
|
||||
|
||||
output.add(val);
|
||||
});
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public static with<V extends Codec> (valType: Constructor<V> | InterfaceTypes): Constructor<BTreeSet<V>> {
|
||||
return class extends BTreeSet<V> {
|
||||
constructor (registry: Registry, value?: any) {
|
||||
super(registry, valType, value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The length of the value when encoded as a Uint8Array
|
||||
*/
|
||||
public get encodedLength (): number {
|
||||
let len = Compact.encodeU8a(this.size).length;
|
||||
|
||||
this.forEach((v: V) => {
|
||||
len += v.encodedLength;
|
||||
});
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns a hash of the value
|
||||
*/
|
||||
public get hash (): IHash {
|
||||
return new U8a(this.registry, blake2AsU8a(this.toU8a(), 256));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Checks if the value is an empty value
|
||||
*/
|
||||
public get isEmpty (): boolean {
|
||||
return this.size === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Compares the value of the input to see if there is a match
|
||||
*/
|
||||
public eq (other?: any): boolean {
|
||||
return compareSet(this, other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns a hex string representation of the value. isLe returns a LE (number-only) representation
|
||||
*/
|
||||
public toHex (): string {
|
||||
return u8aToHex(this.toU8a());
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Converts the Object to JSON, typically used for RPC transfers
|
||||
*/
|
||||
public toJSON (): AnyJsonArray {
|
||||
const json: any = [];
|
||||
this.forEach((v: V) => {
|
||||
json.push(v.toJSON());
|
||||
});
|
||||
return json;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns the base runtime type name for this instance
|
||||
*/
|
||||
public toRawType (): string {
|
||||
return `BTreeSet<${new this._ValClass(this.registry).toRawType()}>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns the string representation of the value
|
||||
*/
|
||||
public toString (): string {
|
||||
return JSON.stringify(this.toJSON());
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Encodes the value as a Uint8Array as per the SCALE specifications
|
||||
* @param isBare true when the value has none of the type-specific prefixes (internal)
|
||||
*/
|
||||
public toU8a (isBare?: boolean): Uint8Array {
|
||||
const encoded = new Array<Uint8Array>();
|
||||
|
||||
if (!isBare) {
|
||||
encoded.push(Compact.encodeU8a(this.size));
|
||||
}
|
||||
|
||||
this.forEach((v: V) => {
|
||||
encoded.push(v.toU8a(isBare));
|
||||
});
|
||||
|
||||
return u8aConcat(...encoded);
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,12 @@ describe('createType', (): void => {
|
||||
).toEqual('{"bazzing":69}');
|
||||
});
|
||||
|
||||
it('allows creation of a BTreeSet', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe(registry, 'BTreeSet<u32>', ['0x1002000000180000001e00000050000000']).toString()
|
||||
).toEqual('[2,24,30,80]');
|
||||
});
|
||||
|
||||
it('allows creation of a Result', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe(registry, 'Result<u32,Text>', ['0x011064656667']).toJSON()
|
||||
|
||||
@@ -8,6 +8,7 @@ import { TypeDef, TypeDefExtVecFixed, TypeDefInfo } from './types';
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
import BTreeMap from '../BTreeMap';
|
||||
import BTreeSet from '../BTreeSet';
|
||||
import Compact from '../Compact';
|
||||
import Enum from '../Enum';
|
||||
import Option from '../Option';
|
||||
@@ -62,6 +63,8 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
|
||||
return BTreeMap.with(keyType, valueType);
|
||||
},
|
||||
|
||||
[TypeDefInfo.BTreeSet]: (registry: Registry, value: TypeDef): Constructor => BTreeSet.with(getSubType(value)),
|
||||
|
||||
[TypeDefInfo.Compact]: (registry: Registry, value: TypeDef): Constructor => Compact.with(getSubType(value)),
|
||||
|
||||
[TypeDefInfo.Enum]: (registry: Registry, value: TypeDef): Constructor => Enum.with(getTypeClassMap(value)),
|
||||
|
||||
@@ -47,6 +47,19 @@ describe('getTypeDef', (): void => {
|
||||
});
|
||||
});
|
||||
|
||||
it('properly decodes a BTreeSet<Text>', (): void => {
|
||||
expect(
|
||||
getTypeDef('BTreeSet<Text>')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.BTreeSet,
|
||||
type: 'BTreeSet<Text>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Text'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('properly decodes a Result<u32, Text>', (): void => {
|
||||
expect(
|
||||
getTypeDef('Result<u32, Text>')
|
||||
|
||||
@@ -108,6 +108,7 @@ const nestedExtraction: [string, string, TypeDefInfo, (value: TypeDef, type: str
|
||||
];
|
||||
|
||||
const wrappedExtraction: [string, string, TypeDefInfo][] = [
|
||||
['BTreeSet<', '>', TypeDefInfo.BTreeSet],
|
||||
['Compact<', '>', TypeDefInfo.Compact],
|
||||
['Linkage<', '>', TypeDefInfo.Linkage],
|
||||
['Option<', '>', TypeDefInfo.Option],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
type Mapper = (value: string) => string;
|
||||
|
||||
const ALLOWED_BOXES = ['BTreeMap', 'Compact', 'Linkage', 'Result', 'Option', 'Vec'];
|
||||
const ALLOWED_BOXES = ['BTreeMap', 'BTreeSet', 'Compact', 'Linkage', 'Result', 'Option', 'Vec'];
|
||||
|
||||
const mappings: Mapper[] = [
|
||||
// alias <T::InherentOfflineReport as InherentOfflineReport>::Inherent -> InherentOfflineReport
|
||||
|
||||
@@ -13,6 +13,7 @@ export type FromReg<T extends Codec, K extends string> = K extends InterfaceType
|
||||
|
||||
export enum TypeDefInfo {
|
||||
BTreeMap,
|
||||
BTreeSet,
|
||||
Compact,
|
||||
Enum,
|
||||
Linkage,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
// These are the base codec types, generally used for construction
|
||||
export { default as BTreeMap } from './BTreeMap';
|
||||
export { default as BTreeSet } from './BTreeSet';
|
||||
export { default as Compact } from './Compact';
|
||||
// export { default as Date } from './Date';
|
||||
export { default as Enum } from './Enum';
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { isObject } from '@polkadot/util';
|
||||
|
||||
// NOTE These are used internally and when comparing objects, expects that
|
||||
// when the second is an Set<string, Codec> that the first has to be as well
|
||||
export default function compareSet (a: Set<any>, b?: any): boolean {
|
||||
if (Array.isArray(b)) {
|
||||
// equal number of entries and each entry in the array should match
|
||||
return (a.size === b.length) && !b.some((entry): boolean => !a.has(entry));
|
||||
} else if (b instanceof Set) {
|
||||
return compareSet(a, [...b.entries()]);
|
||||
} else if (isObject(b)) {
|
||||
return compareSet(a, Object.entries(b));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -25,6 +25,7 @@ function encodeWithParams (typeDef: Pick<TypeDef, any>, outer = typeDef.displayN
|
||||
|
||||
switch (info) {
|
||||
case TypeDefInfo.BTreeMap:
|
||||
case TypeDefInfo.BTreeSet:
|
||||
case TypeDefInfo.Compact:
|
||||
case TypeDefInfo.Linkage:
|
||||
case TypeDefInfo.Option:
|
||||
@@ -114,6 +115,7 @@ function encodeVecFixed (typeDef: Pick<TypeDef, any>): string {
|
||||
// in a compile-time error with the missing index)
|
||||
const encoders: Record<TypeDefInfo, (typeDef: TypeDef) => string> = {
|
||||
[TypeDefInfo.BTreeMap]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'BTreeMap'),
|
||||
[TypeDefInfo.BTreeSet]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'BTreeSet'),
|
||||
[TypeDefInfo.Compact]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'Compact'),
|
||||
[TypeDefInfo.Enum]: (typeDef: TypeDef): string => encodeEnum(typeDef),
|
||||
[TypeDefInfo.Linkage]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'Linkage'),
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
export { default as compareArray } from './compareArray';
|
||||
export { default as compareMap } from './compareMap';
|
||||
export { default as compareSet } from './compareSet';
|
||||
export { default as decodeU8a } from './decodeU8a';
|
||||
export * from './encodeTypes';
|
||||
export * from './mapToTypeMap';
|
||||
|
||||
@@ -32,6 +32,7 @@ function tsExport (definitions: object, def: TypeDef, imports: TypeImports): str
|
||||
}
|
||||
|
||||
const tsBTreeMap = tsExport;
|
||||
const tsBTreeSet = tsExport;
|
||||
const tsCompact = tsExport;
|
||||
const tsOption = tsExport;
|
||||
const tsPlain = tsExport;
|
||||
@@ -132,6 +133,7 @@ function generateInterfaces (definitions: object, { types }: { types: Record<str
|
||||
// we are being explicit in having no handlers where we do not support (yet)
|
||||
const generators = {
|
||||
[TypeDefInfo.BTreeMap]: tsBTreeMap,
|
||||
[TypeDefInfo.BTreeSet]: tsBTreeSet,
|
||||
[TypeDefInfo.Compact]: tsCompact,
|
||||
[TypeDefInfo.Enum]: tsEnum,
|
||||
[TypeDefInfo.Linkage]: errorUnhandled,
|
||||
|
||||
@@ -41,6 +41,13 @@ function formatBTreeMap (key: string, val: string): string {
|
||||
return `BTreeMap<${key}, ${val}>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the inner `V`, return a `BTreeSet<V>` string
|
||||
*/
|
||||
function formatBTreeSet (val: string): string {
|
||||
return `BTreeSet<${val}>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the inner `T`, return a `Compact<T>` string
|
||||
*/
|
||||
@@ -129,6 +136,11 @@ export function formatType (definitions: object, type: string | TypeDef, imports
|
||||
const [keyDef, valDef] = (typeDef.sub as TypeDef[]);
|
||||
return formatBTreeMap(formatType(definitions, keyDef.type, imports), formatType(definitions, valDef.type, imports));
|
||||
}
|
||||
case TypeDefInfo.BTreeSet: {
|
||||
setImports(definitions, imports, ['BTreeSet']);
|
||||
const valDef = typeDef.sub as TypeDef;
|
||||
return formatBTreeSet(formatType(definitions, valDef.type, imports));
|
||||
}
|
||||
case TypeDefInfo.Result: {
|
||||
setImports(definitions, imports, ['Result']);
|
||||
const [okDef, errorDef] = (typeDef.sub as TypeDef[]);
|
||||
|
||||
Reference in New Issue
Block a user