Add support for WrapperOpaque (#3997)
* Add support for WrapperOpaque * Dedupe dual params * Adjust case * Re-adjust to Vec
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { WrapperOpaque } from '.';
|
||||
|
||||
describe('WrapperOpaque', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
const u8au32 = new Uint8Array([4 << 2, 135, 214, 18, 0]);
|
||||
|
||||
it('u8a encodes a wrapped u32 correctly', (): void => {
|
||||
expect(
|
||||
new WrapperOpaque(registry, 'u32', 1234567).toU8a()
|
||||
).toEqual(u8au32);
|
||||
});
|
||||
|
||||
it('u8a decodes a wrapped u32 correctly', (): void => {
|
||||
expect(
|
||||
new WrapperOpaque(registry, 'u32', u8au32).toU8a()
|
||||
).toEqual(u8au32);
|
||||
});
|
||||
|
||||
it('hex encodes a wrapped u32 correctly', (): void => {
|
||||
expect(
|
||||
new WrapperOpaque(registry, 'u32', '0x12345678').toHex()
|
||||
).toEqual('0x12345678');
|
||||
});
|
||||
|
||||
it('has the correct unwrap', (): void => {
|
||||
expect(
|
||||
new WrapperOpaque(registry, 'u32', '0x12345678').unwrap().toHex()
|
||||
).toEqual('0x12345678');
|
||||
});
|
||||
|
||||
it('has the correct toRawType', (): void => {
|
||||
expect(
|
||||
new WrapperOpaque(registry, 'u32').toRawType()
|
||||
).toEqual('WrapperOpaque<u32>');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Codec, Constructor, Registry } from '../types';
|
||||
|
||||
import { compactAddLength, compactStripLength, isU8a } from '@polkadot/util';
|
||||
|
||||
import { Base } from './Base';
|
||||
import { typeToConstructor } from './utils';
|
||||
|
||||
function decodeRaw<T extends Codec> (registry: Registry, Type: Constructor<T> | string, value?: unknown): T {
|
||||
const Clazz = typeToConstructor<T>(registry, Type);
|
||||
|
||||
if (isU8a(value)) {
|
||||
const [, u8a] = compactStripLength(value);
|
||||
|
||||
return new Clazz(registry, u8a);
|
||||
}
|
||||
|
||||
return new Clazz(registry, value);
|
||||
}
|
||||
|
||||
export class WrapperOpaque<T extends Codec> extends Base<T> {
|
||||
constructor (registry: Registry, Type: Constructor<T> | string, value?: unknown) {
|
||||
super(registry, decodeRaw(registry, Type, value));
|
||||
}
|
||||
|
||||
public static with<T extends Codec> (Type: Constructor<T> | string): Constructor<WrapperOpaque<T>> {
|
||||
return class extends WrapperOpaque<T> {
|
||||
constructor (registry: Registry, value?: unknown) {
|
||||
super(registry, Type, value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns the base runtime type name for this instance
|
||||
*/
|
||||
public override toRawType (): string {
|
||||
return `WrapperOpaque<${this._raw.toRawType()}>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The length of the value when encoded as a Uint8Array
|
||||
*/
|
||||
public override toU8a (isBare?: boolean): Uint8Array {
|
||||
const u8a = super.toU8a(isBare);
|
||||
|
||||
return isBare
|
||||
? u8a
|
||||
: compactAddLength(u8a);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Return the inner value for the wrapped type
|
||||
*/
|
||||
public unwrap (): T {
|
||||
return this._raw;
|
||||
}
|
||||
}
|
||||
@@ -30,3 +30,4 @@ export { U8aFixed } from './U8aFixed';
|
||||
export { Vec } from './Vec';
|
||||
// export { VecAny } from './VecAny';
|
||||
export { VecFixed } from './VecFixed';
|
||||
export { WrapperOpaque } from './WrapperOpaque';
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { TypeDef } from './types';
|
||||
|
||||
import { assert, isNumber, isUndefined, stringify } from '@polkadot/util';
|
||||
|
||||
import { BTreeMap, BTreeSet, CodecSet, Compact, DoNotConstruct, Enum, HashMap, Int, Option, Range, RangeInclusive, Result, Struct, Tuple, U8aFixed, UInt, Vec, VecFixed } from '../codec';
|
||||
import { BTreeMap, BTreeSet, CodecSet, Compact, DoNotConstruct, Enum, HashMap, Int, Option, Range, RangeInclusive, Result, Struct, Tuple, U8aFixed, UInt, Vec, VecFixed, WrapperOpaque } from '../codec';
|
||||
import { Bytes, Null } from '../primitive';
|
||||
import { getTypeDef } from './getTypeDef';
|
||||
import { TypeDefInfo } from './types';
|
||||
@@ -169,7 +169,10 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
|
||||
? U8aFixed.with((length * 8) as U8aBitLength, displayName)
|
||||
: VecFixed.with(subType, length)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
[TypeDefInfo.WrapperOpaque]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
WrapperOpaque.with(getSubType(value))
|
||||
};
|
||||
|
||||
// Returns the type Class for construction
|
||||
|
||||
@@ -32,6 +32,7 @@ function encodeWithParams (registry: Registry, typeDef: TypeDef, outer: string):
|
||||
case TypeDefInfo.Option:
|
||||
case TypeDefInfo.Result:
|
||||
case TypeDefInfo.Vec:
|
||||
case TypeDefInfo.WrapperOpaque:
|
||||
return paramsNotation(outer, sub, (p) => encodeTypeDef(registry, p));
|
||||
}
|
||||
|
||||
@@ -134,7 +135,9 @@ const encoders: Record<TypeDefInfo, (registry: Registry, typeDef: TypeDef) => st
|
||||
assert(isNumber(length) && !isUndefined(sub) && !Array.isArray(sub), 'Unable to encode VecFixed type');
|
||||
|
||||
return `[${sub.type};${length}]`;
|
||||
}
|
||||
},
|
||||
[TypeDefInfo.WrapperOpaque]: (registry: Registry, typeDef: TypeDef) =>
|
||||
encodeWithParams(registry, typeDef, 'WrapperOpaque')
|
||||
};
|
||||
|
||||
function encodeType (registry: Registry, typeDef: TypeDef, withLookup = true): string {
|
||||
|
||||
@@ -216,7 +216,8 @@ const wrappedExtraction: [string, string, TypeDefInfo][] = [
|
||||
['Compact<', '>', TypeDefInfo.Compact],
|
||||
['Linkage<', '>', TypeDefInfo.Linkage],
|
||||
['Option<', '>', TypeDefInfo.Option],
|
||||
['Vec<', '>', TypeDefInfo.Vec]
|
||||
['Vec<', '>', TypeDefInfo.Vec],
|
||||
['WrapperOpaque<', '>', TypeDefInfo.WrapperOpaque]
|
||||
];
|
||||
|
||||
function extractSubType (type: string, [start, end]: [string, string, TypeDefInfo, any?]): string {
|
||||
|
||||
@@ -8,7 +8,7 @@ interface SanitizeOptions {
|
||||
type Mapper = (value: string, options?: SanitizeOptions) => string;
|
||||
|
||||
const BOUNDED = ['BTreeMap', 'BTreeSet', 'HashMap', 'Vec'];
|
||||
const ALLOWED_BOXES = BOUNDED.concat(['Compact', 'DoNotConstruct', 'Int', 'Linkage', 'Range', 'RangeInclusive', 'Result', 'Option', 'UInt']);
|
||||
const ALLOWED_BOXES = BOUNDED.concat(['Compact', 'DoNotConstruct', 'Int', 'Linkage', 'Range', 'RangeInclusive', 'Result', 'Option', 'UInt', 'WrapperOpaque']);
|
||||
const BOX_PRECEDING = ['<', '(', '[', '"', ',', ' ']; // start of vec, tuple, fixed array, part of struct def or in tuple
|
||||
|
||||
const mappings: Mapper[] = [
|
||||
|
||||
@@ -21,7 +21,8 @@ export enum TypeDefInfo {
|
||||
Tuple,
|
||||
UInt,
|
||||
Vec,
|
||||
VecFixed
|
||||
VecFixed,
|
||||
WrapperOpaque
|
||||
}
|
||||
|
||||
export interface TypeDef {
|
||||
|
||||
@@ -48,7 +48,7 @@ const SETS = [
|
||||
].map((p) => p.split('::'));
|
||||
|
||||
// These we never use these as top-level names, they are wrappers
|
||||
const WRAPPERS = ['BoundedBTreeMap', 'BoundedVec', 'Box', 'BTreeMap', 'Cow', 'Result', 'Option', 'WeakBoundedVec'];
|
||||
const WRAPPERS = ['BoundedBTreeMap', 'BoundedVec', 'Box', 'BTreeMap', 'Cow', 'Result', 'Option', 'WeakBoundedVec', 'WrapperOpaque'];
|
||||
|
||||
// These are reserved and/or conflicts with built-in Codec definitions
|
||||
const RESERVED = ['call', 'entries', 'hash', 'keys', 'new', 'size'];
|
||||
@@ -415,6 +415,11 @@ export class GenericPortableRegistry extends Struct {
|
||||
...this.#createSiDef(type)
|
||||
}))
|
||||
});
|
||||
} else if (specialVariant === 'WrapperOpaque') {
|
||||
return withTypeString(this.registry, {
|
||||
info: TypeDefInfo.WrapperOpaque,
|
||||
sub: this.#createSiDef(params[0].type.unwrap())
|
||||
});
|
||||
}
|
||||
|
||||
return SETS.some((p) => matchParts(p, path))
|
||||
|
||||
Reference in New Issue
Block a user