Add Option.unwrapOrDefault (#1942)
* Add Option.unwrapOrDefault * linting * metadata createType(registry, ...) -> registry.createType(...) * Linting * Cleanup tests
This commit is contained in:
@@ -5,11 +5,9 @@
|
||||
import { MetadataLatest } from '@polkadot/types/interfaces/metadata';
|
||||
import { AnyJson, Registry } from '@polkadot/types/types';
|
||||
|
||||
import { createType } from '@polkadot/types/create';
|
||||
|
||||
/** @internal */
|
||||
export default function toCallsOnly (registry: Registry, { extrinsic, modules }: MetadataLatest): AnyJson {
|
||||
return createType(registry, 'MetadataLatest', {
|
||||
return registry.createType('MetadataLatest', {
|
||||
// FIXME, this needs typing, not any
|
||||
modules: modules.map(({ calls, name }): any => ({
|
||||
name,
|
||||
|
||||
@@ -6,17 +6,15 @@
|
||||
import { EventMetadataV1, FunctionMetadataV1, MetadataV0, MetadataV1, ModuleMetadataV1, RuntimeModuleMetadataV0, StorageFunctionMetadataV1 } from '@polkadot/types/interfaces/metadata';
|
||||
import { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { stringUpperFirst } from '@polkadot/util';
|
||||
|
||||
import { createType } from '@polkadot/types/create';
|
||||
import { Option, Vec } from '@polkadot/types/codec';
|
||||
import { Option } from '@polkadot/types/codec';
|
||||
import { Text } from '@polkadot/types/primitive';
|
||||
import { stringUpperFirst } from '@polkadot/util';
|
||||
|
||||
/** @internal */
|
||||
function toV1Calls (registry: Registry, { module: { call: { functions } } }: RuntimeModuleMetadataV0): Option<FunctionMetadataV1> {
|
||||
return functions.length
|
||||
? new Option(registry, Vec.with('FunctionMetadataV1'), functions)
|
||||
: new Option(registry, Vec.with('FunctionMetadataV1'));
|
||||
? new Option(registry, 'Vec<FunctionMetadataV1>', functions)
|
||||
: new Option(registry, 'Vec<FunctionMetadataV1>');
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -24,27 +22,25 @@ function toV1Events (registry: Registry, metadataV0: MetadataV0, prefix: Text):
|
||||
const events = metadataV0.outerEvent.events.find((event): boolean => event[0].eq(prefix));
|
||||
|
||||
return events
|
||||
? new Option(registry, Vec.with('EventMetadataV1'), events[1])
|
||||
: new Option(registry, Vec.with('EventMetadataV1'));
|
||||
? new Option(registry, 'Vec<EventMetadataV1>', events[1])
|
||||
: new Option(registry, 'Vec<EventMetadataV1>');
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function toV1Storage (registry: Registry, { storage }: RuntimeModuleMetadataV0): Option<StorageFunctionMetadataV1> {
|
||||
return storage.isSome
|
||||
? new Option(registry, 'Vec<StorageFunctionMetadataV1>', storage.unwrap().functions)
|
||||
: new Option(registry, 'Vec<StorageFunctionMetadataV1>');
|
||||
return new Option(registry, 'Vec<StorageFunctionMetadataV1>', storage.unwrapOr(undefined)?.functions);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export default function toV1 (registry: Registry, metadataV0: MetadataV0): MetadataV1 {
|
||||
return createType(registry, 'MetadataV1', {
|
||||
return registry.createType('MetadataV1', {
|
||||
modules: metadataV0.modules.map((mod): ModuleMetadataV1 => {
|
||||
// The prefix of this module (capitalized)
|
||||
const prefix = mod.storage.isSome
|
||||
? mod.storage.unwrap().prefix.toString()
|
||||
: stringUpperFirst(mod.prefix.toString()); // If this module doesn't have storage, we just assume the prefix is the name capitalized
|
||||
|
||||
return createType(registry, 'ModuleMetadataV1', {
|
||||
return registry.createType('ModuleMetadataV1', {
|
||||
name: mod.prefix, // Not capitalized
|
||||
prefix, // Capitalized
|
||||
storage: toV1Storage(registry, mod),
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
import { MetadataV1, MetadataV2 } from '@polkadot/types/interfaces/metadata';
|
||||
import { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { createType } from '@polkadot/types/create';
|
||||
|
||||
/** @internal */
|
||||
export default function toV2 (registry: Registry, metadataV1: MetadataV1): MetadataV2 {
|
||||
return createType(registry, 'MetadataV2', metadataV1);
|
||||
return registry.createType('MetadataV2', metadataV1);
|
||||
}
|
||||
|
||||
@@ -5,11 +5,9 @@
|
||||
import { MetadataV10, MetadataV11 } from '@polkadot/types/interfaces/metadata';
|
||||
import { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { createType } from '@polkadot/types/create';
|
||||
|
||||
/** @internal */
|
||||
export default function toV11 (registry: Registry, { modules }: MetadataV10): MetadataV11 {
|
||||
return createType(registry, 'MetadataV11', {
|
||||
return registry.createType('MetadataV11', {
|
||||
modules,
|
||||
// This is new in V11, pass V0 here - something non-existing, telling the API to use
|
||||
// the fallback for this information (on-chain detection)
|
||||
|
||||
@@ -7,7 +7,6 @@ import { FunctionMetadataV11, FunctionMetadataLatest, MetadataV11, MetadataLates
|
||||
import { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { getModuleTypes } from '@polkadot/types/known';
|
||||
import { createType } from '@polkadot/types/create';
|
||||
import { Type } from '@polkadot/types/primitive';
|
||||
import { stringCamelCase } from '@polkadot/util';
|
||||
|
||||
@@ -33,7 +32,7 @@ function convertCalls (registry: Registry, calls: FunctionMetadataV11[], section
|
||||
return calls.map(({ args, documentation, name }): FunctionMetadataLatest => {
|
||||
args.forEach(({ type }): void => setTypeOverride(sectionTypes, type));
|
||||
|
||||
return createType(registry, 'FunctionMetadataLatest', { args, name, documentation });
|
||||
return registry.createType('FunctionMetadataLatest', { args, name, documentation });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -42,7 +41,7 @@ function convertCalls (registry: Registry, calls: FunctionMetadataV11[], section
|
||||
* @internal
|
||||
**/
|
||||
function convertStorage (registry: Registry, { items, prefix }: StorageMetadataV11, sectionTypes: OverrideModuleType): StorageMetadataLatest {
|
||||
return createType(registry, 'StorageMetadataLatest', {
|
||||
return registry.createType('StorageMetadataLatest', {
|
||||
items: items.map(({ documentation, fallback, modifier, name, type }): StorageEntryMetadataLatest => {
|
||||
let resultType: Type;
|
||||
|
||||
@@ -56,7 +55,7 @@ function convertStorage (registry: Registry, { items, prefix }: StorageMetadataV
|
||||
|
||||
setTypeOverride(sectionTypes, resultType);
|
||||
|
||||
return createType(registry, 'StorageEntryMetadataLatest', { documentation, fallback, modifier, name, type });
|
||||
return registry.createType('StorageEntryMetadataLatest', { documentation, fallback, modifier, name, type });
|
||||
}),
|
||||
prefix
|
||||
});
|
||||
@@ -68,13 +67,13 @@ function convertStorage (registry: Registry, { items, prefix }: StorageMetadataV
|
||||
* @internal
|
||||
**/
|
||||
export default function toLatest (registry: Registry, { modules, extrinsic }: MetadataV11): MetadataLatest {
|
||||
return createType(registry, 'MetadataLatest', {
|
||||
return registry.createType('MetadataLatest', {
|
||||
modules: modules.map((mod): ModuleMetadataLatest => {
|
||||
const calls = mod.calls.unwrapOr(null);
|
||||
const storage = mod.storage.unwrapOr(null);
|
||||
const sectionTypes = getModuleTypes(stringCamelCase(mod.name.toString()));
|
||||
|
||||
return createType(registry, 'ModuleMetadataLatest', {
|
||||
return registry.createType('ModuleMetadataLatest', {
|
||||
...mod,
|
||||
calls: calls
|
||||
? convertCalls(registry, calls, sectionTypes)
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
import { MetadataV2, MetadataV3 } from '@polkadot/types/interfaces/metadata';
|
||||
import { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { createType } from '@polkadot/types/create';
|
||||
|
||||
/** @internal */
|
||||
export default function toV3 (registry: Registry, metadataV2: MetadataV2): MetadataV3 {
|
||||
return createType(registry, 'MetadataV3', metadataV2);
|
||||
return registry.createType('MetadataV3', metadataV2);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
import { MetadataV3, MetadataV4, ModuleMetadataV4, StorageFunctionMetadataV3, StorageFunctionMetadataV4 } from '@polkadot/types/interfaces/metadata';
|
||||
import { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { createType } from '@polkadot/types/create';
|
||||
import { Option } from '@polkadot/types/codec';
|
||||
|
||||
/** @internal */
|
||||
@@ -18,34 +17,34 @@ function toV4StorageFunction (registry: Registry, storageFn: StorageFunctionMeta
|
||||
const [newType, index] = type.isPlain
|
||||
? [type.asPlain, 0]
|
||||
: type.isMap
|
||||
? [createType(registry, 'MapTypeV4', {
|
||||
hasher: createType(registry, 'StorageHasherV4', 'Twox128'),
|
||||
? [registry.createType('MapTypeV4', {
|
||||
hasher: registry.createType('StorageHasherV4', 'Twox128'),
|
||||
key: type.asMap.key,
|
||||
value: type.asMap.value,
|
||||
linked: type.asMap.linked
|
||||
}), 1]
|
||||
: [createType(registry, 'DoubleMapTypeV4', {
|
||||
hasher: createType(registry, 'StorageHasherV4', 'Twox128'),
|
||||
: [registry.createType('DoubleMapTypeV4', {
|
||||
hasher: registry.createType('StorageHasherV4', 'Twox128'),
|
||||
key1: type.asDoubleMap.key1,
|
||||
key2: type.asDoubleMap.key2,
|
||||
value: type.asDoubleMap.value,
|
||||
key2Hasher: type.asDoubleMap.key2Hasher
|
||||
}), 2];
|
||||
|
||||
return createType(registry, 'StorageFunctionMetadataV4', {
|
||||
return registry.createType('StorageFunctionMetadataV4', {
|
||||
documentation,
|
||||
fallback,
|
||||
name,
|
||||
modifier,
|
||||
type: createType(registry, 'StorageFunctionTypeV4', newType, index)
|
||||
type: registry.createType('StorageFunctionTypeV4', newType, index)
|
||||
});
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export default function toV4 (registry: Registry, { modules }: MetadataV3): MetadataV4 {
|
||||
return createType(registry, 'MetadataV4', {
|
||||
return registry.createType('MetadataV4', {
|
||||
modules: modules.map(({ calls, events, name, prefix, storage }): ModuleMetadataV4 =>
|
||||
createType(registry, 'ModuleMetadataV4', {
|
||||
registry.createType('ModuleMetadataV4', {
|
||||
calls,
|
||||
events,
|
||||
name,
|
||||
|
||||
@@ -5,11 +5,9 @@
|
||||
import { MetadataV4, MetadataV5, ModuleMetadataV5, StorageFunctionMetadataV4, StorageFunctionMetadataV5, StorageHasherV5 } from '@polkadot/types/interfaces/metadata';
|
||||
import { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
import { Option } from '@polkadot/types/codec';
|
||||
import { createType } from '@polkadot/types/create';
|
||||
import Text from '@polkadot/types/primitive/Text';
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
const hasherMap: Map<string, string> = new Map([
|
||||
['blake2_128', 'Blake2_128'],
|
||||
@@ -25,7 +23,7 @@ function toStorageHasher (registry: Registry, text: Text): StorageHasherV5 {
|
||||
|
||||
assert(mapped, `Invalid Storage hasher: ${text.toString()}`);
|
||||
|
||||
return createType(registry, 'StorageHasherV5', mapped);
|
||||
return registry.createType('StorageHasherV5', mapped);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -35,7 +33,7 @@ function toV5StorageFunction (registry: Registry, storageFn: StorageFunctionMeta
|
||||
? [type.asPlain, 0]
|
||||
: type.isMap
|
||||
? [type.asMap, 1]
|
||||
: [createType(registry, 'DoubleMapTypeV5', {
|
||||
: [registry.createType('DoubleMapTypeV5', {
|
||||
hasher: type.asDoubleMap.hasher,
|
||||
key1: type.asDoubleMap.key1,
|
||||
key2: type.asDoubleMap.key2,
|
||||
@@ -43,20 +41,20 @@ function toV5StorageFunction (registry: Registry, storageFn: StorageFunctionMeta
|
||||
key2Hasher: toStorageHasher(registry, type.asDoubleMap.key2Hasher)
|
||||
}), 2];
|
||||
|
||||
return createType(registry, 'StorageFunctionMetadataV5', {
|
||||
return registry.createType('StorageFunctionMetadataV5', {
|
||||
documentation,
|
||||
fallback,
|
||||
name,
|
||||
modifier,
|
||||
type: createType(registry, 'StorageFunctionTypeV5', newType, index)
|
||||
type: registry.createType('StorageFunctionTypeV5', newType, index)
|
||||
});
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export default function toV5 (registry: Registry, { modules }: MetadataV4): MetadataV5 {
|
||||
return createType(registry, 'MetadataV5', {
|
||||
return registry.createType('MetadataV5', {
|
||||
modules: modules.map(({ calls, events, name, prefix, storage }): ModuleMetadataV5 =>
|
||||
createType(registry, 'ModuleMetadataV5', {
|
||||
registry.createType('ModuleMetadataV5', {
|
||||
name,
|
||||
prefix,
|
||||
storage: storage.isSome
|
||||
|
||||
@@ -5,13 +5,11 @@
|
||||
import { MetadataV5, MetadataV6, ModuleMetadataV6 } from '@polkadot/types/interfaces/metadata';
|
||||
import { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { createType } from '@polkadot/types/create';
|
||||
|
||||
/** @internal */
|
||||
export default function toV6 (registry: Registry, { modules }: MetadataV5): MetadataV6 {
|
||||
return createType(registry, 'MetadataV6', {
|
||||
return registry.createType('MetadataV6', {
|
||||
modules: modules.map(({ calls, events, name, prefix, storage }): ModuleMetadataV6 =>
|
||||
createType(registry, 'ModuleMetadataV6', {
|
||||
registry.createType('ModuleMetadataV6', {
|
||||
calls,
|
||||
constants: [],
|
||||
events,
|
||||
|
||||
@@ -5,19 +5,17 @@
|
||||
import { MetadataV6, MetadataV7, ModuleMetadataV7 } from '@polkadot/types/interfaces/metadata';
|
||||
import { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { createType } from '@polkadot/types/create';
|
||||
|
||||
/** @internal */
|
||||
export default function toV7 (registry: Registry, { modules }: MetadataV6): MetadataV7 {
|
||||
return createType(registry, 'MetadataV7', {
|
||||
return registry.createType('MetadataV7', {
|
||||
modules: modules.map(({ calls, constants, events, name, prefix, storage }): ModuleMetadataV7 =>
|
||||
createType(registry, 'ModuleMetadataV7', {
|
||||
registry.createType('ModuleMetadataV7', {
|
||||
calls,
|
||||
constants,
|
||||
events,
|
||||
name,
|
||||
storage: storage.isSome
|
||||
? createType(registry, 'StorageMetadataV7', { prefix, items: storage.unwrap() })
|
||||
? registry.createType('StorageMetadataV7', { prefix, items: storage.unwrap() })
|
||||
: null
|
||||
})
|
||||
)
|
||||
|
||||
@@ -5,13 +5,11 @@
|
||||
import { MetadataV7, MetadataV8, ModuleMetadataV8 } from '@polkadot/types/interfaces/metadata';
|
||||
import { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { createType } from '@polkadot/types/create';
|
||||
|
||||
/** @internal */
|
||||
export default function toV8 (registry: Registry, { modules }: MetadataV7): MetadataV8 {
|
||||
return createType(registry, 'MetadataV8', {
|
||||
return registry.createType('MetadataV8', {
|
||||
modules: modules.map(({ calls, constants, events, name, storage }): ModuleMetadataV8 =>
|
||||
createType(registry, 'ModuleMetadataV8', {
|
||||
registry.createType('ModuleMetadataV8', {
|
||||
calls,
|
||||
constants,
|
||||
errors: [],
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
import { MetadataV8, MetadataV9 } from '@polkadot/types/interfaces/metadata';
|
||||
import { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { createType } from '@polkadot/types/create';
|
||||
|
||||
/** @internal */
|
||||
export default function toV9 (registry: Registry, { modules }: MetadataV8): MetadataV9 {
|
||||
return createType(registry, 'MetadataV9', { modules });
|
||||
return registry.createType('MetadataV9', { modules });
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
import { MetadataV9, MetadataV10, ModuleMetadataV9, ModuleMetadataV10, StorageEntryMetadataV9, StorageEntryTypeV9, StorageHasherV9, StorageHasherV10 } from '@polkadot/types/interfaces/metadata';
|
||||
import { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { createType } from '@polkadot/types/create';
|
||||
|
||||
// migrate a storage hasher type
|
||||
// see https://github.com/paritytech/substrate/pull/4462
|
||||
/** @internal */
|
||||
@@ -14,10 +12,10 @@ function createStorageHasher (registry: Registry, hasher: StorageHasherV9): Stor
|
||||
// Blake2_128_Concat has been added at index 2, so we increment all the
|
||||
// indexes greater than 2
|
||||
if (hasher.toNumber() >= 2) {
|
||||
return createType(registry, 'StorageHasherV10', hasher.toNumber() + 1);
|
||||
return registry.createType('StorageHasherV10', hasher.toNumber() + 1);
|
||||
}
|
||||
|
||||
return createType(registry, 'StorageHasherV10', hasher);
|
||||
return registry.createType('StorageHasherV10', hasher);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -44,14 +42,14 @@ function createStorageType (registry: Registry, entryType: StorageEntryTypeV9):
|
||||
function convertModule (registry: Registry, mod: ModuleMetadataV9): ModuleMetadataV10 {
|
||||
const storage = mod.storage.unwrapOr(null);
|
||||
|
||||
return createType(registry, 'ModuleMetadataV10', {
|
||||
return registry.createType('ModuleMetadataV10', {
|
||||
...mod,
|
||||
storage: storage
|
||||
? {
|
||||
...storage,
|
||||
items: storage.items.map((item: StorageEntryMetadataV9): any => ({
|
||||
...item,
|
||||
type: createType(registry, 'StorageEntryTypeV10', ...createStorageType(registry, item.type))
|
||||
type: registry.createType('StorageEntryTypeV10', ...createStorageType(registry, item.type))
|
||||
}))
|
||||
}
|
||||
: null
|
||||
@@ -60,7 +58,7 @@ function convertModule (registry: Registry, mod: ModuleMetadataV9): ModuleMetada
|
||||
|
||||
/** @internal */
|
||||
export default function toV10 (registry: Registry, { modules }: MetadataV9): MetadataV10 {
|
||||
return createType(registry, 'MetadataV10', {
|
||||
return registry.createType('MetadataV10', {
|
||||
modules: modules.map((mod): ModuleMetadataV10 => convertModule(registry, mod))
|
||||
});
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ describe('Option', (): void => {
|
||||
// Option<Option<Bytes>> (hence the length, since it is from storage)
|
||||
const HEX = '0x210100000000000000000000000000000000000000000000000000000000000000000000000000000000011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce';
|
||||
|
||||
// whatc the hex prefix and length
|
||||
// watch the hex prefix and length
|
||||
expect(
|
||||
new Option(registry, Bytes, HEX).toHex().substr(6)
|
||||
).toEqual(HEX.substr(2));
|
||||
@@ -59,7 +59,7 @@ describe('Option', (): void => {
|
||||
const HEX = '0x12345678';
|
||||
|
||||
expect(
|
||||
(new Option(registry, U32, HEX).unwrap() as U32).toNumber()
|
||||
new Option(registry, U32, HEX).unwrap().toNumber()
|
||||
).toEqual(0x12345678);
|
||||
});
|
||||
|
||||
@@ -97,22 +97,30 @@ describe('Option', (): void => {
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
const testeq = new Option(registry, Text, '1234');
|
||||
const test = new Option(registry, Text, '1234');
|
||||
|
||||
it('compares against other option', (): void => {
|
||||
expect(testeq.eq(new Option(registry, Text, '1234'))).toBe(true);
|
||||
expect(test.eq(new Option(registry, Text, '1234'))).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against raw value', (): void => {
|
||||
expect(testeq.eq('1234')).toBe(true);
|
||||
expect(test.eq('1234')).toBe(true);
|
||||
});
|
||||
|
||||
it('unwraps to default if empty', (): void => {
|
||||
expect(new Option(registry, Text).unwrapOr('6789')).toBe('6789');
|
||||
it('unwrapOr to specified if empty', (): void => {
|
||||
expect(new Option(registry, Text).unwrapOr('6789').toString()).toEqual('6789');
|
||||
});
|
||||
|
||||
it('unwraps to value if non-empty', (): void => {
|
||||
expect((new Option(registry, Text, '1234').unwrapOr(null) as Text).toString()).toBe('1234');
|
||||
it('unwrapOr to specified if non-empty', (): void => {
|
||||
expect(new Option(registry, Text, '1234').unwrapOr(null)?.toString()).toEqual('1234');
|
||||
});
|
||||
|
||||
it('unwrapOrDefault to default if empty', (): void => {
|
||||
expect(new Option(registry, U32).unwrapOrDefault().toNumber()).toEqual(0);
|
||||
});
|
||||
|
||||
it('unwrapOrDefault to specified if non-empty', (): void => {
|
||||
expect(new Option(registry, U32, '1234').unwrapOrDefault().toNumber()).toEqual(1234);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,6 +10,32 @@ import Null from '../primitive/Null';
|
||||
import { typeToConstructor } from './utils';
|
||||
import Base from './Base';
|
||||
|
||||
/** @internal */
|
||||
function decodeOptionU8a (registry: Registry, Type: Constructor, value: Uint8Array): Codec {
|
||||
return !value.length || value[0] === 0
|
||||
? new Null(registry)
|
||||
: new Type(registry, value.subarray(1));
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function decodeOption (registry: Registry, Type: Constructor, value?: any): Codec {
|
||||
if (isNull(value) || isUndefined(value) || value instanceof Null) {
|
||||
return new Null(registry);
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
} else if (value instanceof Option) {
|
||||
return decodeOption(registry, Type, value.value);
|
||||
} else if (value instanceof Type) {
|
||||
// don't re-create, use as it (which also caters for derived types)
|
||||
return value;
|
||||
} else if (isU8a(value)) {
|
||||
// the isU8a check happens last in the if-tree - since the wrapped value
|
||||
// may be an instance of it, so Type and Option checks go in first
|
||||
return decodeOptionU8a(registry, Type, value);
|
||||
}
|
||||
|
||||
return new Type(registry, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Option
|
||||
* @description
|
||||
@@ -19,42 +45,17 @@ import Base from './Base';
|
||||
* with a value if/as required/found.
|
||||
*/
|
||||
export default class Option<T extends Codec> extends Base<T> {
|
||||
private _Type: Constructor;
|
||||
private _Type: Constructor<T>;
|
||||
|
||||
constructor (registry: Registry, Type: Constructor | keyof InterfaceTypes, value?: any) {
|
||||
constructor (registry: Registry, Type: Constructor<T> | keyof InterfaceTypes, value?: any) {
|
||||
const Clazz = typeToConstructor(registry, Type);
|
||||
|
||||
super(registry, Option.decodeOption(registry, Clazz, value));
|
||||
super(registry, decodeOption(registry, Clazz, value));
|
||||
|
||||
this._Type = Clazz;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public static decodeOption (registry: Registry, Type: Constructor, value?: any): Codec {
|
||||
if (isNull(value) || isUndefined(value) || value instanceof Null) {
|
||||
return new Null(registry);
|
||||
} else if (value instanceof Option) {
|
||||
return Option.decodeOption(registry, Type, value.value);
|
||||
} else if (value instanceof Type) {
|
||||
// don't re-create, use as it (which also caters for derived types)
|
||||
return value;
|
||||
} else if (isU8a(value)) {
|
||||
// the isU8a check happens last in the if-tree - since the wrapped value
|
||||
// may be an instance of it, so Type and Option checks go in first
|
||||
return Option.decodeOptionU8a(registry, Type, value);
|
||||
}
|
||||
|
||||
return new Type(registry, value);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
private static decodeOptionU8a (registry: Registry, Type: Constructor, value: Uint8Array): Codec {
|
||||
return !value.length || value[0] === 0
|
||||
? new Null(registry)
|
||||
: new Type(registry, value.subarray(1));
|
||||
}
|
||||
|
||||
public static with<O extends Codec> (Type: Constructor | keyof InterfaceTypes): Constructor<Option<O>> {
|
||||
public static with<O extends Codec> (Type: Constructor<O> | keyof InterfaceTypes): Constructor<Option<O>> {
|
||||
return class extends Option<O> {
|
||||
constructor (registry: Registry, value?: any) {
|
||||
super(registry, Type, value);
|
||||
@@ -170,4 +171,14 @@ export default class Option<T extends Codec> extends Base<T> {
|
||||
? this.unwrap()
|
||||
: defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns the value that the Option represents (if available) or defaultValue if none
|
||||
* @param defaultValue The value to return if the option isNone
|
||||
*/
|
||||
public unwrapOrDefault (): T {
|
||||
return this.isSome
|
||||
? this.unwrap()
|
||||
: new this._Type(this.registry);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user