Small decoding cleanups (#4823)
* Small decoding cleanups * isHex * Adjust struct * Additional
This commit is contained in:
@@ -25,10 +25,8 @@ function toPercentage (value: BN, divisor: BN): string {
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function decodeAbstractInt (value: AnyNumber, bitLength: UIntBitLength, isNegative: boolean): string {
|
||||
if (isU8a(value)) {
|
||||
return u8aToBn(value.subarray(0, bitLength / 8), { isLe: true, isNegative }).toString();
|
||||
} else if (isBn(value)) {
|
||||
function decodeAbstractInt (value: Exclude<AnyNumber, Uint8Array>, isNegative: boolean): string {
|
||||
if (isBn(value)) {
|
||||
return value.toString();
|
||||
} else if (isHex(value, -1, true)) {
|
||||
return hexToBn(value, { isLe: false, isNegative }).toString();
|
||||
@@ -65,7 +63,7 @@ export abstract class AbstractInt extends BN implements INumber {
|
||||
// shortcut isU8a as used in SCALE decoding
|
||||
isU8a(value)
|
||||
? u8aToBn(value.subarray(0, bitLength / 8), { isLe: true, isNegative: isSigned }).toString()
|
||||
: decodeAbstractInt(value, bitLength, isSigned)
|
||||
: decodeAbstractInt(value, isSigned)
|
||||
);
|
||||
|
||||
this.registry = registry;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { AnyJson, Codec, CodecClass, IEnum, Inspect, IU8a, Registry } from '../types';
|
||||
|
||||
import { assert, isHex, isNumber, isObject, isString, isU8a, isUndefined, objectProperties, stringCamelCase, stringify, stringPascalCase, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
import { assert, isCodec, isHex, isNumber, isObject, isString, isU8a, isUndefined, objectProperties, stringCamelCase, stringify, stringPascalCase, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import { mapToTypeMap, typesToMap } from '../utils';
|
||||
import { Null } from './Null';
|
||||
@@ -88,7 +88,7 @@ function createFromValue (registry: Registry, def: TypesDef, index = 0, value?:
|
||||
|
||||
return {
|
||||
index,
|
||||
value: value instanceof entry.Type
|
||||
value: isCodec(value) && value instanceof entry.Type
|
||||
? value
|
||||
: new entry.Type(registry, value)
|
||||
};
|
||||
@@ -266,7 +266,7 @@ export class Enum implements IEnum {
|
||||
* @deprecated use isNone
|
||||
*/
|
||||
public get isNull (): boolean {
|
||||
return this.#raw instanceof Null;
|
||||
return this.isNone;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -310,7 +310,7 @@ export class Enum implements IEnum {
|
||||
return this.type === other;
|
||||
} else if (isHex(other)) {
|
||||
return this.toHex() === other;
|
||||
} else if (other instanceof Enum) {
|
||||
} else if (isCodec(other) && other instanceof Enum) {
|
||||
return this.index === other.index && this.value.eq(other.value);
|
||||
} else if (isObject(other)) {
|
||||
return this.value.eq(other[this.type]);
|
||||
@@ -404,7 +404,7 @@ export class Enum implements IEnum {
|
||||
* @description Returns the string representation of the value
|
||||
*/
|
||||
public toString (): string {
|
||||
return this.isNull
|
||||
return this.isNone
|
||||
? this.type
|
||||
: stringify(this.toJSON());
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ type TupleTypes = TupleType[] | {
|
||||
};
|
||||
|
||||
/** @internal */
|
||||
function decodeTuple (registry: Registry, Classes: TupleCodecClasss, value?: AnyTupleValue): [Codec[], number] {
|
||||
function decodeTuple (registry: Registry, Classes: TupleCodecClasss, value?: Exclude<AnyTupleValue, Uint8Array>): [Codec[], number] {
|
||||
if (isU8a(value) || isHex(value)) {
|
||||
return decodeU8a(registry, u8aToU8a(value), Classes);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { decodeU8aVec, typeToConstructor } from '../utils';
|
||||
import { decodeVec } from './Vec';
|
||||
|
||||
/** @internal */
|
||||
function decodeVecFixed<T extends Codec> (registry: Registry, value: Uint8Array | HexString | unknown[], Type: CodecClass<T>, length: number): [T[], number, number] {
|
||||
function decodeVecFixed<T extends Codec> (registry: Registry, value: HexString | unknown[], Type: CodecClass<T>, length: number): [T[], number, number] {
|
||||
const [values, decodedLength, decodedLengthNoOffset] = decodeVec(registry, Type, value, length);
|
||||
|
||||
while (values.length < length) {
|
||||
|
||||
@@ -11,7 +11,7 @@ import { compareSet, decodeU8aVec, sortSet, typeToConstructor } from '../utils';
|
||||
const l = logger('BTreeSet');
|
||||
|
||||
/** @internal */
|
||||
function decodeSetFromU8a<V extends Codec> (registry: Registry, ValClass: CodecClass<V>, u8a: Uint8Array): [Set<V>, number] {
|
||||
function decodeSetFromU8a<V extends Codec> (registry: Registry, ValClass: CodecClass<V>, u8a: Uint8Array): [CodecClass<V>, Set<V>, number] {
|
||||
const output = new Set<V>();
|
||||
const [offset, length] = compactFromU8a(u8a);
|
||||
const [values, decodedLength] = decodeU8aVec(registry, u8a, offset, ValClass, length.toNumber());
|
||||
@@ -20,11 +20,11 @@ function decodeSetFromU8a<V extends Codec> (registry: Registry, ValClass: CodecC
|
||||
output.add(values[i]);
|
||||
}
|
||||
|
||||
return [output, decodedLength];
|
||||
return [ValClass, output, decodedLength];
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function decodeSetFromSet<V extends Codec> (registry: Registry, ValClass: CodecClass<V>, value: Set<any> | string[]): [Set<V>, number] {
|
||||
function decodeSetFromSet<V extends Codec> (registry: Registry, ValClass: CodecClass<V>, value: Set<any> | string[]): [CodecClass<V>, Set<V>, number] {
|
||||
const output = new Set<V>();
|
||||
|
||||
value.forEach((val: any) => {
|
||||
@@ -37,7 +37,7 @@ function decodeSetFromSet<V extends Codec> (registry: Registry, ValClass: CodecC
|
||||
}
|
||||
});
|
||||
|
||||
return [output, 0];
|
||||
return [ValClass, output, 0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,14 +54,12 @@ function decodeSetFromSet<V extends Codec> (registry: Registry, ValClass: CodecC
|
||||
* @param jsonSet
|
||||
* @internal
|
||||
*/
|
||||
function decodeSet<V extends Codec> (registry: Registry, valType: CodecClass<V> | string, value?: Uint8Array | string | string[] | Set<any>): [Set<V>, number] {
|
||||
if (!value) {
|
||||
return [new Set<V>(), 0];
|
||||
}
|
||||
|
||||
function decodeSet<V extends Codec> (registry: Registry, valType: CodecClass<V> | string, value?: Uint8Array | string | string[] | Set<any>): [CodecClass<V>, Set<V>, number] {
|
||||
const ValClass = typeToConstructor(registry, valType);
|
||||
|
||||
if (isU8a(value) || isHex(value)) {
|
||||
if (!value) {
|
||||
return [ValClass, new Set<V>(), 0];
|
||||
} else if (isU8a(value) || isHex(value)) {
|
||||
return decodeSetFromU8a<V>(registry, ValClass, u8aToU8a(value));
|
||||
} else if (Array.isArray(value) || value instanceof Set) {
|
||||
return decodeSetFromSet<V>(registry, ValClass, value);
|
||||
@@ -80,13 +78,13 @@ export class BTreeSet<V extends Codec = Codec> extends Set<V> implements ISet<V>
|
||||
readonly #ValClass: CodecClass<V>;
|
||||
|
||||
constructor (registry: Registry, valType: CodecClass<V> | string, rawValue?: Uint8Array | string | string[] | Set<any>) {
|
||||
const [values, decodedLength] = decodeSet(registry, valType, rawValue);
|
||||
const [ValClass, values, decodedLength] = decodeSet(registry, valType, rawValue);
|
||||
|
||||
super(sortSet(values));
|
||||
|
||||
this.registry = registry;
|
||||
this.initialU8aLength = decodedLength;
|
||||
this.#ValClass = typeToConstructor(registry, valType);
|
||||
this.#ValClass = ValClass;
|
||||
}
|
||||
|
||||
public static with<V extends Codec> (valType: CodecClass<V> | string): CodecClass<BTreeSet<V>> {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import type { AnyU8a, Inspect, Registry } from '../types';
|
||||
|
||||
import { assert, compactAddLength, compactFromU8a, compactToU8a, isString, isU8a, u8aToU8a } from '@polkadot/util';
|
||||
import { assert, compactAddLength, compactFromU8a, compactToU8a, isCodec, isString, isU8a, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import { Raw } from '../native/Raw';
|
||||
|
||||
@@ -26,19 +26,6 @@ function decodeBytesU8a (value: Uint8Array): [Uint8Array, number] {
|
||||
return [value.subarray(offset, total), total];
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function decodeBytes (value?: AnyU8a): [Uint8Array | undefined, number] {
|
||||
if (Array.isArray(value) || isString(value)) {
|
||||
return [u8aToU8a(value), 0];
|
||||
} else if (!(value instanceof Raw) && isU8a(value)) {
|
||||
// We are ensuring we are not a Raw instance. In the case of a Raw we already have gotten
|
||||
// rid of the length, i.e. new Bytes(new Bytes(...)) will work as expected
|
||||
return decodeBytesU8a(value);
|
||||
}
|
||||
|
||||
return [value, 0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Bytes
|
||||
* @description
|
||||
@@ -48,7 +35,11 @@ function decodeBytes (value?: AnyU8a): [Uint8Array | undefined, number] {
|
||||
*/
|
||||
export class Bytes extends Raw {
|
||||
constructor (registry: Registry, value?: AnyU8a) {
|
||||
const [u8a, decodedLength] = decodeBytes(value);
|
||||
const [u8a, decodedLength] = isU8a(value) && !(isCodec(value) && value instanceof Raw)
|
||||
? decodeBytesU8a(value)
|
||||
: Array.isArray(value) || isString(value)
|
||||
? [u8aToU8a(value), 0]
|
||||
: [value, 0];
|
||||
|
||||
super(registry, u8a, decodedLength);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import { compareMap, decodeU8a, sortMap, typeToConstructor } from '../utils';
|
||||
const l = logger('Map');
|
||||
|
||||
/** @internal */
|
||||
function decodeMapFromU8a<K extends Codec, V extends Codec> (registry: Registry, KeyClass: CodecClass<K>, ValClass: CodecClass<V>, u8a: Uint8Array): [Map<K, V>, number] {
|
||||
function decodeMapFromU8a<K extends Codec, V extends Codec> (registry: Registry, KeyClass: CodecClass<K>, ValClass: CodecClass<V>, u8a: Uint8Array): [CodecClass<K>, CodecClass<V>, Map<K, V>, number] {
|
||||
const output = new Map<K, V>();
|
||||
const [offset, length] = compactFromU8a(u8a);
|
||||
const count = length.toNumber();
|
||||
@@ -30,11 +30,11 @@ function decodeMapFromU8a<K extends Codec, V extends Codec> (registry: Registry,
|
||||
output.set(values[i] as K, values[i + 1] as V);
|
||||
}
|
||||
|
||||
return [output, offset + decodedLength];
|
||||
return [KeyClass, ValClass, output, offset + decodedLength];
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function decodeMapFromMap<K extends Codec, V extends Codec> (registry: Registry, KeyClass: CodecClass<K>, ValClass: CodecClass<V>, value: Map<any, any>): [Map<K, V>, number] {
|
||||
function decodeMapFromMap<K extends Codec, V extends Codec> (registry: Registry, KeyClass: CodecClass<K>, ValClass: CodecClass<V>, value: Map<any, any>): [CodecClass<K>, CodecClass<V>, Map<K, V>, number] {
|
||||
const output = new Map<K, V>();
|
||||
|
||||
for (const [key, val] of value.entries()) {
|
||||
@@ -58,7 +58,7 @@ function decodeMapFromMap<K extends Codec, V extends Codec> (registry: Registry,
|
||||
}
|
||||
}
|
||||
|
||||
return [output, 0];
|
||||
return [KeyClass, ValClass, output, 0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,12 +76,12 @@ function decodeMapFromMap<K extends Codec, V extends Codec> (registry: Registry,
|
||||
* @param jsonMap
|
||||
* @internal
|
||||
*/
|
||||
function decodeMap<K extends Codec, V extends Codec> (registry: Registry, keyType: CodecClass<K> | string, valType: CodecClass<V> | string, value?: Uint8Array | string | Map<any, any>): [Map<K, V>, number] {
|
||||
function decodeMap<K extends Codec, V extends Codec> (registry: Registry, keyType: CodecClass<K> | string, valType: CodecClass<V> | string, value?: Uint8Array | string | Map<any, any>): [CodecClass<K>, CodecClass<V>, Map<K, V>, number] {
|
||||
const KeyClass = typeToConstructor(registry, keyType);
|
||||
const ValClass = typeToConstructor(registry, valType);
|
||||
|
||||
if (!value) {
|
||||
return [new Map<K, V>(), 0];
|
||||
return [KeyClass, ValClass, new Map<K, V>(), 0];
|
||||
} else if (isU8a(value) || isHex(value)) {
|
||||
return decodeMapFromU8a<K, V>(registry, KeyClass, ValClass, u8aToU8a(value));
|
||||
} else if (value instanceof Map) {
|
||||
@@ -107,14 +107,14 @@ export class CodecMap<K extends Codec = Codec, V extends Codec = Codec> extends
|
||||
readonly #type: string;
|
||||
|
||||
constructor (registry: Registry, keyType: CodecClass<K> | string, valType: CodecClass<V> | string, rawValue: Uint8Array | string | Map<any, any> | undefined, type: 'BTreeMap' | 'HashMap' = 'HashMap') {
|
||||
const [decoded, decodedLength] = decodeMap(registry, keyType, valType, rawValue);
|
||||
const [KeyClass, ValClass, decoded, decodedLength] = decodeMap(registry, keyType, valType, rawValue);
|
||||
|
||||
super(type === 'BTreeMap' ? sortMap(decoded) : decoded);
|
||||
|
||||
this.registry = registry;
|
||||
this.initialU8aLength = decodedLength;
|
||||
this.#KeyClass = typeToConstructor(registry, keyType);
|
||||
this.#ValClass = typeToConstructor(registry, valType);
|
||||
this.#KeyClass = KeyClass;
|
||||
this.#ValClass = ValClass;
|
||||
this.#type = type;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,17 +6,6 @@ import type { Codec, Inspect, IU8a, Registry } from '../types';
|
||||
|
||||
import { isU8a, u8aToHex } from '@polkadot/util';
|
||||
|
||||
/** @internal */
|
||||
function decodeBool (value: any): boolean {
|
||||
if (isU8a(value)) {
|
||||
return value[0] === 1;
|
||||
} else if (value instanceof Boolean) {
|
||||
return value.valueOf();
|
||||
}
|
||||
|
||||
return !!value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name bool
|
||||
* @description
|
||||
@@ -30,7 +19,13 @@ export class bool extends Boolean implements Codec {
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
constructor (registry: Registry, value: bool | Boolean | Uint8Array | boolean | number = false) {
|
||||
super(decodeBool(value));
|
||||
super(
|
||||
isU8a(value)
|
||||
? value[0] === 1
|
||||
: value instanceof Boolean
|
||||
? value.valueOf()
|
||||
: !!value
|
||||
);
|
||||
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ const BITLENGTH: UIntBitLength = 64;
|
||||
|
||||
function decodeDate (value: CodecDate | Date | AnyNumber): Date {
|
||||
if (isU8a(value)) {
|
||||
value = u8aToBn(value.subarray(0, BITLENGTH / 8), true);
|
||||
value = u8aToBn(value.subarray(0, BITLENGTH / 8));
|
||||
} else if (value instanceof Date) {
|
||||
return value;
|
||||
} else if (isString(value)) {
|
||||
|
||||
@@ -111,8 +111,8 @@ export class CodecSet extends Set<string> implements ISet<string> {
|
||||
}
|
||||
|
||||
return class extends CodecSet {
|
||||
constructor (registry: Registry, value?: unknown) {
|
||||
super(registry, values, value as undefined, bitLength);
|
||||
constructor (registry: Registry, value?: string[] | Set<string> | Uint8Array | BN | number | string) {
|
||||
super(registry, values, value, bitLength);
|
||||
|
||||
objectProperties(this, isKeys, (_, i) => this.strings.includes(keys[i]));
|
||||
}
|
||||
|
||||
@@ -45,8 +45,6 @@ function decodeText (value?: null | Text | string | AnyU8a | { toString: () => s
|
||||
* object, inheriting all methods exposed from `String`.
|
||||
* @noInheritDoc
|
||||
*/
|
||||
// TODO
|
||||
// - Strings should probably be trimmed (docs do come through with extra padding)
|
||||
export class Text extends String implements IText {
|
||||
public readonly registry: Registry;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user