AbstractArray base & VectorAny (no types in constructor) (#833)

* AbstractArray base & VectorAny (no  types in constrctor)

* Remove noInheritDoc from Tuple, Vector* (already on abstract)
This commit is contained in:
Jaco Greeff
2019-04-10 12:36:00 +02:00
committed by GitHub
parent efaa2af78a
commit b37aebe88b
4 changed files with 147 additions and 174 deletions
+123
View File
@@ -0,0 +1,123 @@
// 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 { u8aConcat, u8aToHex } from '@polkadot/util';
import Compact from './Compact';
import { Codec } from '../types';
import { compareArray } from './utils';
/**
* @name AbstractArray
* @description
* This manages codec arrays. It is an extension to Array, providing
* specific encoding/decoding on top of the base type.
* @noInheritDoc
*/
export default abstract class AbstractArray<T extends Codec> extends Array<T> implements Codec {
/**
* @description Checks if the value is an empty value
*/
get isEmpty (): boolean {
return this.length === 0;
}
/**
* @description The length of the value when encoded as a Uint8Array
*/
get encodedLength (): number {
return this.reduce((total, raw) => {
return total + raw.encodedLength;
}, Compact.encodeU8a(this.length).length);
}
/**
* @description The length of the value
*/
get length (): number {
// only included here since we ignore inherited docs
return super.length;
}
/**
* @description Compares the value of the input to see if there is a match
*/
eq (other?: any): boolean {
return compareArray(this, other);
}
/**
* @description Converts the Object to an standard JavaScript Array
*/
toArray (): Array<T> {
return Array.from(this);
}
/**
* @description Returns a hex string representation of the value
*/
toHex (): string {
return u8aToHex(this.toU8a());
}
/**
* @description Converts the Object to JSON, typically used for RPC transfers
*/
toJSON (): any {
return this.map((entry) =>
entry.toJSON()
);
}
/**
* @description Returns the string representation of the value
*/
toString (): string {
// Overwrite the default toString representation of Array.
const data = this.map((entry) =>
entry.toString()
);
return `[${data.join(', ')}]`;
}
/**
* @description Encodes the value as a Uint8Array as per the parity-codec specifications
* @param isBare true when the value has none of the type-specific prefixes (internal)
*/
toU8a (isBare?: boolean): Uint8Array {
const encoded = this.map((entry) =>
entry.toU8a(isBare)
);
return isBare
? u8aConcat(...encoded)
: u8aConcat(
Compact.encodeU8a(this.length),
...encoded
);
}
// Below are methods that we override. When we do a `new Vector(...).map()`,
// we want it to return an Array. We only override the methods that return a
// new instance.
/**
* @description Filters the array with the callback
* @param callbackfn The filter function
* @param thisArg The `this` object to apply the result to
*/
filter (callbackfn: (value: T, index: number, array: Array<T>) => any, thisArg?: any): Array<T> {
return this.toArray().filter(callbackfn, thisArg);
}
/**
* @description Maps the array with the callback
* @param callbackfn The mapping function
* @param thisArg The `this` onject to apply the result to
*/
map<U> (callbackfn: (value: T, index: number, array: Array<T>) => U, thisArg?: any): Array<U> {
return this.toArray().map(callbackfn, thisArg);
}
}
+4 -63
View File
@@ -2,10 +2,11 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { isU8a, u8aConcat, u8aToHex, isHex, hexToU8a } from '@polkadot/util';
import { isU8a, u8aConcat, isHex, hexToU8a } from '@polkadot/util';
import { AnyNumber, AnyU8a, AnyString, Codec, Constructor } from '../types';
import { compareArray, decodeU8a } from './utils';
import { decodeU8a } from './utils';
import AbstractArray from './AbstractArray';
type TupleConstructors = Array<Constructor> | {
[index: string]: Constructor
@@ -16,9 +17,8 @@ type TupleConstructors = Array<Constructor> | {
* @description
* A Tuple defines an anonymous fixed-length array, where each element has its
* own type. It extends the base JS `Array` object.
* @noInheritDoc
*/
export default class Tuple extends Array<Codec> implements Codec {
export default class Tuple extends AbstractArray<Codec> {
private _Types: TupleConstructors;
constructor (Types: TupleConstructors, value: any) {
@@ -62,13 +62,6 @@ export default class Tuple extends Array<Codec> implements Codec {
}, 0);
}
/**
* @description Checks if the value is an empty value
*/
get isEmpty (): boolean {
return this.length === 0;
}
/**
* @description The types definition of the tuple
*/
@@ -78,36 +71,6 @@ export default class Tuple extends Array<Codec> implements Codec {
: Object.keys(this._Types);
}
/**
* @description Compares the value of the input to see if there is a match
*/
eq (other?: any): boolean {
return compareArray(this, other);
}
/**
* @description Converts the Object to an standard JavaScript Array
*/
toArray (): Array<Codec> {
return Array.from(this);
}
/**
* @description Returns a hex string representation of the value
*/
toHex () {
return u8aToHex(this.toU8a());
}
/**
* @description Converts the Object to JSON, typically used for RPC transfers
*/
toJSON (): any {
return this.map((entry) =>
entry.toJSON()
);
}
/**
* @description Returns the string representation of the value
*/
@@ -127,26 +90,4 @@ export default class Tuple extends Array<Codec> implements Codec {
)
);
}
// Below are methods that we override. When we do a `new Tuple(...).map()`,
// we want it to throw an error. We only override the methods that return a
// new instance.
/**
* @description Filters the array with the callback
* @param callbackfn The filter function
* @param thisArg The `this` object to apply the result to
*/
filter (callbackfn: (value: Codec, index: number, array: Array<Codec>) => any, thisArg?: any): Array<Codec> {
return this.toArray().filter(callbackfn, thisArg);
}
/**
* @description Maps the array with the callback
* @param callbackfn The mapping function
* @param thisArg The `this` onject to apply the result to
*/
map<U> (callbackfn: (value: Codec, index: number, array: Array<Codec>) => U, thisArg?: any): Array<U> {
return this.toArray().map(callbackfn, thisArg);
}
}
+4 -111
View File
@@ -2,11 +2,12 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { u8aConcat, u8aToU8a, u8aToHex } from '@polkadot/util';
import { u8aToU8a } from '@polkadot/util';
import Compact from './Compact';
import { Codec, Constructor } from '../types';
import { compareArray, decodeU8a } from './utils';
import { decodeU8a } from './utils';
import AbstractArray from './AbstractArray';
/**
* @name Vector
@@ -14,11 +15,8 @@ import { compareArray, decodeU8a } from './utils';
* This manages codec arrays. Internally it keeps track of the length (as decoded) and allows
* construction with the passed `Type` in the constructor. It is an extension to Array, providing
* specific encoding/decoding on top of the base type.
* @noInheritDoc
*/
export default class Vector<
T extends Codec
> extends Array<T> implements Codec {
export default class Vector<T extends Codec> extends AbstractArray<T> {
private _Type: Constructor<T>;
constructor (Type: Constructor<T>, value: Vector<any> | Uint8Array | string | Array<any> = [] as Array<any>) {
@@ -53,13 +51,6 @@ export default class Vector<
};
}
/**
* @description Checks if the value is an empty value
*/
get isEmpty (): boolean {
return this.length === 0;
}
/**
* @description The type for the items
*/
@@ -67,30 +58,6 @@ export default class Vector<
return this._Type.name;
}
/**
* @description The length of the value when encoded as a Uint8Array
*/
get encodedLength (): number {
return this.reduce((total, raw) => {
return total + raw.encodedLength;
}, Compact.encodeU8a(this.length).length);
}
/**
* @description The length of the value
*/
get length (): number {
// only included here since we ignore inherited docs
return super.length;
}
/**
* @description Compares the value of the input to see if there is a match
*/
eq (other?: any): boolean {
return compareArray(this, other);
}
/**
* @description Finds the index of the value in the array
*/
@@ -108,78 +75,4 @@ export default class Vector<
return -1;
}
/**
* @description Converts the Object to an standard JavaScript Array
*/
toArray (): Array<T> {
return Array.from(this);
}
/**
* @description Returns a hex string representation of the value
*/
toHex (): string {
return u8aToHex(this.toU8a());
}
/**
* @description Converts the Object to JSON, typically used for RPC transfers
*/
toJSON (): any {
return this.map((entry) =>
entry.toJSON()
);
}
/**
* @description Returns the string representation of the value
*/
toString (): string {
// Overwrite the default toString representation of Array.
const data = this.map((entry) =>
entry.toString()
);
return `[${data.join(', ')}]`;
}
/**
* @description Encodes the value as a Uint8Array as per the parity-codec specifications
* @param isBare true when the value has none of the type-specific prefixes (internal)
*/
toU8a (isBare?: boolean): Uint8Array {
const encoded = this.map((entry) =>
entry.toU8a(isBare)
);
return isBare
? u8aConcat(...encoded)
: u8aConcat(
Compact.encodeU8a(this.length),
...encoded
);
}
// Below are methods that we override. When we do a `new Vector(...).map()`,
// we want it to return an Array. We only override the methods that return a
// new instance.
/**
* @description Filters the array with the callback
* @param callbackfn The filter function
* @param thisArg The `this` object to apply the result to
*/
filter (callbackfn: (value: T, index: number, array: Array<T>) => any, thisArg?: any): Array<T> {
return this.toArray().filter(callbackfn, thisArg);
}
/**
* @description Maps the array with the callback
* @param callbackfn The mapping function
* @param thisArg The `this` onject to apply the result to
*/
map<U> (callbackfn: (value: T, index: number, array: Array<T>) => U, thisArg?: any): Array<U> {
return this.toArray().map(callbackfn, thisArg);
}
}
+16
View File
@@ -0,0 +1,16 @@
// 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 { Codec } from '../types';
import AbstractArray from './AbstractArray';
/**
* @name VectorAny
* @description
* This manages codec arrays, assuming that the inputs are already of type Codec. Unlike
* a vector, this cane be used to manage array-like structures with variable arguments of
* any types
*/
export default class VectorAny<T extends Codec> extends AbstractArray<T> {
}