Allow struct alias on PortableRegistry (#3808)

* Allow struct aliasses on PortableRegistry

* Add resrved alias

* Naing adjustment

* No name for flattenned Tuple

* Add docs
This commit is contained in:
Jaco
2021-07-25 07:30:57 +02:00
committed by GitHub
parent d763f49e8b
commit 68efac60df
3 changed files with 59 additions and 17 deletions
+12 -3
View File
@@ -43,7 +43,7 @@ function encodeDoNotConstruct (registry: Registry, { displayName }: TypeDef): st
return `DoNotConstruct<${displayName || 'Unknown'}>`;
}
function encodeSubTypes (registry: Registry, sub: TypeDef[], asEnum?: boolean): string {
function encodeSubTypes (registry: Registry, sub: TypeDef[], asEnum?: boolean, extra?: Record<string, unknown>): string {
const names = sub.map(({ name }) => name);
assert(names.every((n) => !!n), () => `Subtypes does not have consistent names, ${names.join(', ')}`);
@@ -51,7 +51,7 @@ function encodeSubTypes (registry: Registry, sub: TypeDef[], asEnum?: boolean):
const inner = sub.reduce< Record<string, string>>((result, type) => ({
...result,
[type.name as string]: encodeTypeDef(registry, type)
}), {});
}), { ...(extra as Record<string, string>) });
return stringify(
asEnum
@@ -75,7 +75,16 @@ function encodeEnum (registry: Registry, typeDef: TypeDef): string {
function encodeStruct (registry: Registry, typeDef: TypeDef): string {
assert(typeDef.sub && Array.isArray(typeDef.sub), 'Unable to encode Struct type');
return encodeSubTypes(registry, typeDef.sub);
return encodeSubTypes(registry, typeDef.sub, false, {
...(
typeDef.alias
? { alias: [...typeDef.alias.entries()].reduce<Record<string, string>>((all, [k, v]) => ({
...all,
[k]: v
}), {}) }
: {}
)
});
}
function encodeTuple (registry: Registry, typeDef: TypeDef): string {
+1
View File
@@ -34,6 +34,7 @@ export enum TypeDefInfo {
export interface TypeDef {
alias?: Map<string, string>;
displayName?: string;
docs?: string[];
fallbackType?: string;
info: TypeDefInfo;
index?: number;
+46 -14
View File
@@ -38,6 +38,9 @@ const PRIMITIVE_SP = [
// These we never use these as top-level names, they are wrappers
const WRAPPERS = ['Box', 'BTreeMap', 'Cow', 'Result', 'Option'];
// These are reserved and conflicts with built-in Codec definitions
const RESERVED = ['entries', 'hash', 'keys', 'size'];
function removeDuplicateNames (names: (string | null)[]): (string | null)[] {
return names.map((name, index): string | null =>
!name || names.some((o, i) => index !== i && name === o)
@@ -137,6 +140,7 @@ export class GenericPortableRegistry extends Struct {
// Setup for a lookup on complex types
return [TypeDefInfo.Enum, TypeDefInfo.Struct].includes(typeDef.info)
? {
docs: typeDef.docs,
info: TypeDefInfo.Si,
lookupIndex,
lookupName: this.#names[lookupIndex],
@@ -199,6 +203,7 @@ export class GenericPortableRegistry extends Struct {
}
return {
docs: type.docs.map((d) => d.toString()),
namespace: path.join('::'),
...typeDef
};
@@ -247,22 +252,10 @@ export class GenericPortableRegistry extends Struct {
type: 'Null'
};
} else if (isTuple && fields.length === 1) {
return {
...this.#createSiDef(fields[0].type),
...(fields[0].name.isSome
? { name: stringCamelCase(fields[0].name.unwrap()) }
: {}
)
};
return this.#createSiDef(fields[0].type);
}
const sub = fields.map(({ name, type }) => ({
...this.#createSiDef(type),
...(name.isSome
? { name: stringCamelCase(name.unwrap()) }
: {}
)
}));
const [sub, alias] = this.#extractFieldsAlias(fields);
return withTypeString(this.registry, {
info: isTuple // Tuple check first
@@ -276,10 +269,49 @@ export class GenericPortableRegistry extends Struct {
lookupName: this.#names[lookupIndex]
}
),
...(
alias.size
? { alias }
: {}
),
sub
});
}
#extractFieldsAlias (fields: SiField[]): [TypeDef[], Map<string, string>] {
const alias = new Map<string, string>();
const sub = fields.map(({ docs, name, type }) => {
const typeDef = this.#createSiDef(type);
if (name.isNone) {
return typeDef;
}
let nameField = stringCamelCase(name.unwrap());
let nameOrig: string | null = null;
if (nameField.includes('#')) {
nameOrig = nameField;
nameField = nameOrig.replace(/#/g, '_');
} else if (RESERVED.includes(nameField)) {
nameOrig = nameField;
nameField = `${nameField}_`;
}
if (nameOrig) {
alias.set(nameField, nameOrig);
}
return {
...typeDef,
docs: docs.map((d) => d.toString()),
name: nameField
};
});
return [sub, alias];
}
#extractHistoric (_: number, type: Type): TypeDef {
return {
...getTypeDef(type),