Skip to content

Commit

Permalink
Unwrap, ungeneric
Browse files Browse the repository at this point in the history
  • Loading branch information
jacogr committed Sep 24, 2018
1 parent 290b55b commit aec1c9e
Showing 1 changed file with 72 additions and 15 deletions.
87 changes: 72 additions & 15 deletions packages/api-codec/src/Type.ts
Expand Up @@ -4,28 +4,85 @@

import String from './String';

// given a starting index, find the closing >
function findClosing (value: string, start: number): number {
let depth = 0;

for (let index = start; index < value.length; index++) {
if (value[index] === '>') {
if (!depth) {
return index;
} else {
depth--;
}
} else if (value[index] === '<') {
depth++;
}
}

throw new Error(`Unable to find closing matching <> on '${value}' (start ${start})`);
}

function ungeneric (value: string): string {
for (let index = 0; index < value.length; index++) {
if (value[index] === '<') {
if (value.substr(index - 3, 3) !== 'Vec') {
const start = index + 1;
const end = findClosing(value, start);

value = `${value.substr(0, index)}${value.substr(end + 1)}`;
}
}
}

return value;
}

// remove the type traits
function untrait (value: string): string {
return value
// anything `T::<type>` to end up as `<type>`
.replace(/T::/g, '')
// `system::` with `` - basically we find `<T as system::Trait>`
.replace(/system::/g, '')
// replace `<T as Trait>::` (possibly sanitiused just above)
.replace(/<T as Trait>::/g, '');
}

// remove wrapping values, i.e. Box<Proposal> -> Proposal
function unwrap (check: string, value: string): string {
let index = 0;

while (index !== -1) {
index = value.indexOf(check);

if (index !== -1) {
const start = index + check.length;
const end = findClosing(value, start);

value = `${value.substr(start, end - start)}`;
}
}

return value;
}

// This is a extended version of String, specifically to handle types. Here we rely full on
// what string provides us, however we also "tweak" the types received from the runtime, i.e.
// we remove the `T::` prefixes found in some types for consistency accross implementation.
export default class Type extends String {
fromU8a (input: Uint8Array): String {
super.fromU8a(input);

// NOTE Hack around the Rust types to make them consistent for actual use
// FIXME we are still missing quite a bit of cleanups -
// - MisbehaviorReport<Hash, BlockNumber> -> MisbehaviorReport
// - RawAddress<AccountId, AccountIndex> - as above, strip generics
// - More of the same ValidatorPrefs<Balance>
// - Actually, anything that is not Box (i.e. wrap) or Vec (i.e. array), should have some magic
this.raw = this.raw
// anything `T::<type>` to end up as `<type>`
.replace(/T::/g, '')
// `system::` with `` - basically we find `<T as system::Trait>`
.replace(/system::/g, '')
// replace `<T as Trait>::` (possibly sanitiused just above)
.replace(/<T as Trait>::/g, '')
// `Box<Proposal>` -> `Proposal`
.replace(/Box<Proposal>/g, 'Proposal');
// Hack around the Rust types to make them consistent for actual use
let result = untrait(this.raw);

// `Box<Proposal>` -> `Proposal`
result = unwrap('Box<', result);
// `MisbehaviorReport<Hash, BlockNumber>` -> `MisbehaviorReport`
result = ungeneric(result);

this.raw = result;

return this;
}
Expand Down

0 comments on commit aec1c9e

Please sign in to comment.