-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
StructType.ts
94 lines (72 loc) · 2.75 KB
/
StructType.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import type { IRawAbiTypeComponent } from '../../index';
import type { TargetEnum } from '../../types/enums/TargetEnum';
import type { IType } from '../../types/interfaces/IType';
import { extractStructName } from '../../utils/extractStructName';
import { findType } from '../../utils/findType';
import { parseTypeArguments } from '../../utils/parseTypeArguments';
import { AType } from './AType';
export class StructType extends AType implements IType {
public static swayType = 'struct MyStruct';
public name = 'struct';
static MATCH_REGEX: RegExp = /^struct (.+)$/m;
static IGNORE_REGEX: RegExp = /^struct (Vec|RawVec|EvmAddress)$/m;
static isSuitableFor(params: { type: string }) {
const isAMatch = StructType.MATCH_REGEX.test(params.type);
const shouldBeIgnored = StructType.IGNORE_REGEX.test(params.type);
return isAMatch && !shouldBeIgnored;
}
public parseComponentsAttributes(_params: { types: IType[] }) {
const structName = this.getStructName();
this.attributes = {
structName,
inputLabel: `${structName}Input`,
outputLabel: `${structName}Output`,
};
return this.attributes;
}
public getStructName() {
const name = extractStructName({
rawAbiType: this.rawAbiType,
regex: StructType.MATCH_REGEX,
});
return name;
}
public getStructContents(params: { types: IType[]; target: TargetEnum }) {
const { types, target } = params;
const { components } = this.rawAbiType;
// `components` array guaranteed to always exist for structs/enums
const structComponents = components as IRawAbiTypeComponent[];
// loop through all components
const members = structComponents.map((component) => {
const { name, type: typeId, typeArguments } = component;
const type = findType({ types, typeId });
let typeDecl: string;
if (typeArguments) {
// recursively process child `typeArguments`
typeDecl = parseTypeArguments({
types,
target,
parentTypeId: typeId,
typeArguments,
});
} else {
// or just collect type declaration
const attributeKey: 'inputLabel' | 'outputLabel' = `${target}Label`;
typeDecl = type.attributes[attributeKey];
}
// assemble it in `[key: string]: <Type>` fashion
return `${name}: ${typeDecl}`;
});
return members.join(', ');
}
public getStructDeclaration(params: { types: IType[] }) {
const { types } = params;
const { typeParameters } = this.rawAbiType;
if (typeParameters) {
const structs = typeParameters.map((typeId) => findType({ types, typeId }));
const labels = structs.map(({ attributes: { inputLabel } }) => inputLabel);
return `<${labels.join(', ')}>`;
}
return '';
}
}