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:
@@ -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 {
|
||||
|
||||
@@ -34,6 +34,7 @@ export enum TypeDefInfo {
|
||||
export interface TypeDef {
|
||||
alias?: Map<string, string>;
|
||||
displayName?: string;
|
||||
docs?: string[];
|
||||
fallbackType?: string;
|
||||
info: TypeDefInfo;
|
||||
index?: number;
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user