Skip to content

Commit

Permalink
feat: csharp enum rendering associated values (#355)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaslagoni authored Sep 8, 2021
1 parent b3a5431 commit 1f8add2
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 11 deletions.
76 changes: 71 additions & 5 deletions src/generators/csharp/renderers/EnumRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,34 @@ import { pascalCase } from 'change-case';
*/
export class EnumRenderer extends CSharpRenderer {
async defaultSelf(): Promise<string> {
const content = [
await this.renderItems(),
];
const enumItems = await this.renderItems();
const formattedName = this.nameType(this.model.$id);
const getValueCaseItemValues = await this.getValueCaseItemValues();
const toEnumCaseItemValues = await this.toEnumCaseItemValues();
return `public enum ${formattedName} {
${this.indent(this.renderBlock(content, 2))}
}`;
${this.indent(enumItems)}
}
public static class ${formattedName}Extensions {
public static dynamic GetValue(this ${formattedName} enumValue)
{
switch (enumValue)
{
${this.indent(getValueCaseItemValues, 6)}
}
return null;
}
public static ${formattedName}? To${formattedName}(dynamic value)
{
switch (value)
{
${this.indent(toEnumCaseItemValues, 6)}
}
return null;
}
}
`;
}

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

/**
* Some enum values require custom value conversion
*/
getEnumValue(enumValue: any): any {
switch (typeof enumValue) {
case 'number':
case 'bigint':
case 'boolean':
return enumValue;
case 'object':
return `"${JSON.stringify(enumValue).replace(/"/g, '\\"')}"`;
default:
return `"${enumValue}"`;
}
}

async toEnumCaseItemValues(): Promise<string> {
const enums = this.model.enum || [];
const items: string[] = [];
const formattedName = this.nameType(this.model.$id);

for (const enumValue of enums) {
const renderedItem = await this.runItemPreset(enumValue);
const value = this.getEnumValue(enumValue);
items.push(`case ${value}: return ${formattedName}.${renderedItem};`);
}

const content = items.join('\n');
return `${content}`;
}
async getValueCaseItemValues(): Promise<string> {
const enums = this.model.enum || [];
const items: string[] = [];
const formattedName = this.nameType(this.model.$id);

for (const enumValue of enums) {
const renderedItem = await this.runItemPreset(enumValue);
const value = this.getEnumValue(enumValue);
items.push(`case ${formattedName}.${renderedItem}: return ${value};`);
}

const content = items.join('\n');
return `${content}`;
}

runItemPreset(item: any): Promise<string> {
return this.runPreset('item', { item });
}
Expand Down
166 changes: 160 additions & 6 deletions test/generators/csharp/__snapshots__/CSharpGenerator.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -191,25 +191,129 @@ exports[`CSharpGenerator should render \`class\` type 2`] = `
exports[`CSharpGenerator should render \`enum\` type $name should not be empty 1`] = `
"public enum States {
Texas, Alabama, California
}"
}
public static class StatesExtensions {
public static dynamic GetValue(this States enumValue)
{
switch (enumValue)
{
case States.Texas: return \\"Texas\\";
case States.Alabama: return \\"Alabama\\";
case States.California: return \\"California\\";
}
return null;
}
public static States? ToStates(dynamic value)
{
switch (value)
{
case \\"Texas\\": return States.Texas;
case \\"Alabama\\": return States.Alabama;
case \\"California\\": return States.California;
}
return null;
}
}
"
`;
exports[`CSharpGenerator should render \`enum\` type $name should not be empty 2`] = `
"public enum States {
Texas, Alabama, California
}"
}
public static class StatesExtensions {
public static dynamic GetValue(this States enumValue)
{
switch (enumValue)
{
case States.Texas: return \\"Texas\\";
case States.Alabama: return \\"Alabama\\";
case States.California: return \\"California\\";
}
return null;
}
public static States? ToStates(dynamic value)
{
switch (value)
{
case \\"Texas\\": return States.Texas;
case \\"Alabama\\": return States.Alabama;
case \\"California\\": return States.California;
}
return null;
}
}
"
`;
exports[`CSharpGenerator should render \`enum\` type $name should not be empty 3`] = `
"public enum Things {
Texas, Number_1, False, TestTest
}"
}
public static class ThingsExtensions {
public static dynamic GetValue(this Things enumValue)
{
switch (enumValue)
{
case Things.Texas: return \\"Texas\\";
case Things.Number_1: return 1;
case Things.False: return false;
case Things.TestTest: return \\"{\\\\\\"test\\\\\\":\\\\\\"test\\\\\\"}\\";
}
return null;
}
public static Things? ToThings(dynamic value)
{
switch (value)
{
case \\"Texas\\": return Things.Texas;
case 1: return Things.Number_1;
case false: return Things.False;
case \\"{\\\\\\"test\\\\\\":\\\\\\"test\\\\\\"}\\": return Things.TestTest;
}
return null;
}
}
"
`;
exports[`CSharpGenerator should render \`enum\` type $name should not be empty 4`] = `
"public enum Things {
Texas, Number_1, False, TestTest
}"
}
public static class ThingsExtensions {
public static dynamic GetValue(this Things enumValue)
{
switch (enumValue)
{
case Things.Texas: return \\"Texas\\";
case Things.Number_1: return 1;
case Things.False: return false;
case Things.TestTest: return \\"{\\\\\\"test\\\\\\":\\\\\\"test\\\\\\"}\\";
}
return null;
}
public static Things? ToThings(dynamic value)
{
switch (value)
{
case \\"Texas\\": return Things.Texas;
case 1: return Things.Number_1;
case false: return Things.False;
case \\"{\\\\\\"test\\\\\\":\\\\\\"test\\\\\\"}\\": return Things.TestTest;
}
return null;
}
}
"
`;
exports[`CSharpGenerator should work custom preset for \`class\` type 1`] = `
Expand All @@ -234,11 +338,61 @@ exports[`CSharpGenerator should work custom preset for \`class\` type 1`] = `
exports[`CSharpGenerator should work custom preset for \`enum\` type 1`] = `
"public enum CustomEnum {
Texas, Alabama, California
}"
}
public static class CustomEnumExtensions {
public static dynamic GetValue(this CustomEnum enumValue)
{
switch (enumValue)
{
case CustomEnum.Texas: return \\"Texas\\";
case CustomEnum.Alabama: return \\"Alabama\\";
case CustomEnum.California: return \\"California\\";
}
return null;
}
public static CustomEnum? ToCustomEnum(dynamic value)
{
switch (value)
{
case \\"Texas\\": return CustomEnum.Texas;
case \\"Alabama\\": return CustomEnum.Alabama;
case \\"California\\": return CustomEnum.California;
}
return null;
}
}
"
`;
exports[`CSharpGenerator should work custom preset for \`enum\` type 2`] = `
"public enum CustomEnum {
Texas, Alabama, California
}"
}
public static class CustomEnumExtensions {
public static dynamic GetValue(this CustomEnum enumValue)
{
switch (enumValue)
{
case CustomEnum.Texas: return \\"Texas\\";
case CustomEnum.Alabama: return \\"Alabama\\";
case CustomEnum.California: return \\"California\\";
}
return null;
}
public static CustomEnum? ToCustomEnum(dynamic value)
{
switch (value)
{
case \\"Texas\\": return CustomEnum.Texas;
case \\"Alabama\\": return CustomEnum.Alabama;
case \\"California\\": return CustomEnum.California;
}
return null;
}
}
"
`;

0 comments on commit 1f8add2

Please sign in to comment.