Skip to content

Commit 1f8add2

Browse files
authored
feat: csharp enum rendering associated values (#355)
1 parent b3a5431 commit 1f8add2

File tree

2 files changed

+231
-11
lines changed

2 files changed

+231
-11
lines changed

src/generators/csharp/renderers/EnumRenderer.ts

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,34 @@ import { pascalCase } from 'change-case';
99
*/
1010
export class EnumRenderer extends CSharpRenderer {
1111
async defaultSelf(): Promise<string> {
12-
const content = [
13-
await this.renderItems(),
14-
];
12+
const enumItems = await this.renderItems();
1513
const formattedName = this.nameType(this.model.$id);
14+
const getValueCaseItemValues = await this.getValueCaseItemValues();
15+
const toEnumCaseItemValues = await this.toEnumCaseItemValues();
1616
return `public enum ${formattedName} {
17-
${this.indent(this.renderBlock(content, 2))}
18-
}`;
17+
${this.indent(enumItems)}
18+
}
19+
public static class ${formattedName}Extensions {
20+
public static dynamic GetValue(this ${formattedName} enumValue)
21+
{
22+
switch (enumValue)
23+
{
24+
${this.indent(getValueCaseItemValues, 6)}
25+
}
26+
return null;
27+
}
28+
29+
public static ${formattedName}? To${formattedName}(dynamic value)
30+
{
31+
switch (value)
32+
{
33+
${this.indent(toEnumCaseItemValues, 6)}
34+
}
35+
return null;
36+
}
37+
}
38+
39+
`;
1940
}
2041

2142
async renderItems(): Promise<string> {
@@ -31,6 +52,51 @@ ${this.indent(this.renderBlock(content, 2))}
3152
return `${content}`;
3253
}
3354

55+
/**
56+
* Some enum values require custom value conversion
57+
*/
58+
getEnumValue(enumValue: any): any {
59+
switch (typeof enumValue) {
60+
case 'number':
61+
case 'bigint':
62+
case 'boolean':
63+
return enumValue;
64+
case 'object':
65+
return `"${JSON.stringify(enumValue).replace(/"/g, '\\"')}"`;
66+
default:
67+
return `"${enumValue}"`;
68+
}
69+
}
70+
71+
async toEnumCaseItemValues(): Promise<string> {
72+
const enums = this.model.enum || [];
73+
const items: string[] = [];
74+
const formattedName = this.nameType(this.model.$id);
75+
76+
for (const enumValue of enums) {
77+
const renderedItem = await this.runItemPreset(enumValue);
78+
const value = this.getEnumValue(enumValue);
79+
items.push(`case ${value}: return ${formattedName}.${renderedItem};`);
80+
}
81+
82+
const content = items.join('\n');
83+
return `${content}`;
84+
}
85+
async getValueCaseItemValues(): Promise<string> {
86+
const enums = this.model.enum || [];
87+
const items: string[] = [];
88+
const formattedName = this.nameType(this.model.$id);
89+
90+
for (const enumValue of enums) {
91+
const renderedItem = await this.runItemPreset(enumValue);
92+
const value = this.getEnumValue(enumValue);
93+
items.push(`case ${formattedName}.${renderedItem}: return ${value};`);
94+
}
95+
96+
const content = items.join('\n');
97+
return `${content}`;
98+
}
99+
34100
runItemPreset(item: any): Promise<string> {
35101
return this.runPreset('item', { item });
36102
}

test/generators/csharp/__snapshots__/CSharpGenerator.spec.ts.snap

Lines changed: 160 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,25 +191,129 @@ exports[`CSharpGenerator should render \`class\` type 2`] = `
191191
exports[`CSharpGenerator should render \`enum\` type $name should not be empty 1`] = `
192192
"public enum States {
193193
Texas, Alabama, California
194-
}"
194+
}
195+
public static class StatesExtensions {
196+
public static dynamic GetValue(this States enumValue)
197+
{
198+
switch (enumValue)
199+
{
200+
case States.Texas: return \\"Texas\\";
201+
case States.Alabama: return \\"Alabama\\";
202+
case States.California: return \\"California\\";
203+
}
204+
return null;
205+
}
206+
207+
public static States? ToStates(dynamic value)
208+
{
209+
switch (value)
210+
{
211+
case \\"Texas\\": return States.Texas;
212+
case \\"Alabama\\": return States.Alabama;
213+
case \\"California\\": return States.California;
214+
}
215+
return null;
216+
}
217+
}
218+
219+
"
195220
`;
196221
197222
exports[`CSharpGenerator should render \`enum\` type $name should not be empty 2`] = `
198223
"public enum States {
199224
Texas, Alabama, California
200-
}"
225+
}
226+
public static class StatesExtensions {
227+
public static dynamic GetValue(this States enumValue)
228+
{
229+
switch (enumValue)
230+
{
231+
case States.Texas: return \\"Texas\\";
232+
case States.Alabama: return \\"Alabama\\";
233+
case States.California: return \\"California\\";
234+
}
235+
return null;
236+
}
237+
238+
public static States? ToStates(dynamic value)
239+
{
240+
switch (value)
241+
{
242+
case \\"Texas\\": return States.Texas;
243+
case \\"Alabama\\": return States.Alabama;
244+
case \\"California\\": return States.California;
245+
}
246+
return null;
247+
}
248+
}
249+
250+
"
201251
`;
202252
203253
exports[`CSharpGenerator should render \`enum\` type $name should not be empty 3`] = `
204254
"public enum Things {
205255
Texas, Number_1, False, TestTest
206-
}"
256+
}
257+
public static class ThingsExtensions {
258+
public static dynamic GetValue(this Things enumValue)
259+
{
260+
switch (enumValue)
261+
{
262+
case Things.Texas: return \\"Texas\\";
263+
case Things.Number_1: return 1;
264+
case Things.False: return false;
265+
case Things.TestTest: return \\"{\\\\\\"test\\\\\\":\\\\\\"test\\\\\\"}\\";
266+
}
267+
return null;
268+
}
269+
270+
public static Things? ToThings(dynamic value)
271+
{
272+
switch (value)
273+
{
274+
case \\"Texas\\": return Things.Texas;
275+
case 1: return Things.Number_1;
276+
case false: return Things.False;
277+
case \\"{\\\\\\"test\\\\\\":\\\\\\"test\\\\\\"}\\": return Things.TestTest;
278+
}
279+
return null;
280+
}
281+
}
282+
283+
"
207284
`;
208285
209286
exports[`CSharpGenerator should render \`enum\` type $name should not be empty 4`] = `
210287
"public enum Things {
211288
Texas, Number_1, False, TestTest
212-
}"
289+
}
290+
public static class ThingsExtensions {
291+
public static dynamic GetValue(this Things enumValue)
292+
{
293+
switch (enumValue)
294+
{
295+
case Things.Texas: return \\"Texas\\";
296+
case Things.Number_1: return 1;
297+
case Things.False: return false;
298+
case Things.TestTest: return \\"{\\\\\\"test\\\\\\":\\\\\\"test\\\\\\"}\\";
299+
}
300+
return null;
301+
}
302+
303+
public static Things? ToThings(dynamic value)
304+
{
305+
switch (value)
306+
{
307+
case \\"Texas\\": return Things.Texas;
308+
case 1: return Things.Number_1;
309+
case false: return Things.False;
310+
case \\"{\\\\\\"test\\\\\\":\\\\\\"test\\\\\\"}\\": return Things.TestTest;
311+
}
312+
return null;
313+
}
314+
}
315+
316+
"
213317
`;
214318
215319
exports[`CSharpGenerator should work custom preset for \`class\` type 1`] = `
@@ -234,11 +338,61 @@ exports[`CSharpGenerator should work custom preset for \`class\` type 1`] = `
234338
exports[`CSharpGenerator should work custom preset for \`enum\` type 1`] = `
235339
"public enum CustomEnum {
236340
Texas, Alabama, California
237-
}"
341+
}
342+
public static class CustomEnumExtensions {
343+
public static dynamic GetValue(this CustomEnum enumValue)
344+
{
345+
switch (enumValue)
346+
{
347+
case CustomEnum.Texas: return \\"Texas\\";
348+
case CustomEnum.Alabama: return \\"Alabama\\";
349+
case CustomEnum.California: return \\"California\\";
350+
}
351+
return null;
352+
}
353+
354+
public static CustomEnum? ToCustomEnum(dynamic value)
355+
{
356+
switch (value)
357+
{
358+
case \\"Texas\\": return CustomEnum.Texas;
359+
case \\"Alabama\\": return CustomEnum.Alabama;
360+
case \\"California\\": return CustomEnum.California;
361+
}
362+
return null;
363+
}
364+
}
365+
366+
"
238367
`;
239368
240369
exports[`CSharpGenerator should work custom preset for \`enum\` type 2`] = `
241370
"public enum CustomEnum {
242371
Texas, Alabama, California
243-
}"
372+
}
373+
public static class CustomEnumExtensions {
374+
public static dynamic GetValue(this CustomEnum enumValue)
375+
{
376+
switch (enumValue)
377+
{
378+
case CustomEnum.Texas: return \\"Texas\\";
379+
case CustomEnum.Alabama: return \\"Alabama\\";
380+
case CustomEnum.California: return \\"California\\";
381+
}
382+
return null;
383+
}
384+
385+
public static CustomEnum? ToCustomEnum(dynamic value)
386+
{
387+
switch (value)
388+
{
389+
case \\"Texas\\": return CustomEnum.Texas;
390+
case \\"Alabama\\": return CustomEnum.Alabama;
391+
case \\"California\\": return CustomEnum.California;
392+
}
393+
return null;
394+
}
395+
}
396+
397+
"
244398
`;

0 commit comments

Comments
 (0)