Correct handling for storage Option<Option<Type>> (#4927)

* Correct handling for storage Option<Option<Type>>

* Adjust
This commit is contained in:
Jaco
2022-06-12 10:36:41 +03:00
committed by GitHub
parent 54efaa665d
commit 31971b5d2c
3 changed files with 34 additions and 8 deletions
@@ -43,6 +43,24 @@ describe('Option', (): void => {
});
});
it('can decode a nested Option', (): void => {
expect(
new Option(
registry,
Option.with(Option.with(Text)),
new Option(
registry,
Option.with(Text),
new Option(
registry,
Text,
new Uint8Array([1, 3 << 2, 66, 67, 68])
)
)
).toU8a()
).toEqual(new Uint8Array([1, 1, 1, 3 << 2, 66, 67, 68]));
});
it('can convert between different Some/None', (): void => {
const def = '{ "foo":"Text", "zar":"Text" }';
const none = new Option(registry, def, null);
+15 -8
View File
@@ -29,16 +29,23 @@ class None extends Null {
/** @internal */
function decodeOption (registry: Registry, Type: CodecClass, value?: unknown): Codec {
// In the case of an option, unwrap the inner
if (value instanceof Option) {
value = value.value;
}
if (isNull(value) || isUndefined(value) || value === '0x' || value instanceof None) {
return new None(registry);
} else if (value instanceof Type) {
if (value instanceof Type) {
// don't re-create, use as it (which also caters for derived types)
return value;
} else if (value instanceof Option) {
if (value.value instanceof Type) {
// same instance, return it
return value.value;
} else if (value.isNone) {
// internal is None, we are also none
return new None(registry);
}
// convert the actual value into known
return new Type(registry, value.value);
} else if (isNull(value) || isUndefined(value) || value === '0x' || value instanceof None) {
// anyhting empty we pass as-is
return new None(registry);
} 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