Skip to content

Commit 931346c

Browse files
committed
fix(dart-dio): use enum type for discriminator when property is enum
When discriminator property references an enum type, use that enum type instead of String for discriminatorValue getter/extension. This ensures type safety and proper enum handling in generated Dart code. Changes: - Updated class_discriminator.mustache to handle enum discriminators - Use enum.valueOf() for enum discriminators, throw error instead of returning null - Added test case for enum discriminator scenario - regenerated sample client with correct enum discriminator handling Fixes #21570
1 parent 570915e commit 931346c

5 files changed

Lines changed: 113 additions & 11 deletions

File tree

modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/class.mustache

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ part '{{classFilename}}.g.dart';
1313
}
1414
{{#discriminator}}{{#hasDiscriminatorWithNonEmptyMapping}}
1515
{{>serialization/built_value/class_discriminator}}
16-
1716
{{/hasDiscriminatorWithNonEmptyMapping}}{{/discriminator}}
1817
{{>serialization/built_value/class_serializer}}{{#vendorExtensions.x-is-parent}}
1918

2019
{{>serialization/built_value/class_concrete}}{{/vendorExtensions.x-is-parent}}
21-
{{>serialization/built_value/class_inline_enums}}
20+
{{>serialization/built_value/class_inline_enums}}

modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/class_discriminator.mustache

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{{^discriminator.isEnum}}
12
extension {{classname}}DiscriminatorExt on {{classname}} {
23
String? get discriminatorValue {
34
{{#mappedModels}}
@@ -17,4 +18,27 @@ extension {{classname}}BuilderDiscriminatorExt on {{classname}}Builder {
1718
{{/mappedModels}}
1819
return null;
1920
}
20-
}
21+
}
22+
{{/discriminator.isEnum}}
23+
{{#discriminator.isEnum}}
24+
extension {{classname}}DiscriminatorExt on {{classname}} {
25+
{{discriminator.propertyType}} get discriminatorValue {
26+
{{#mappedModels}}
27+
if (this is {{modelName}}) {
28+
return {{discriminator.propertyType}}.valueOf(r'{{mappingName}}');
29+
}
30+
{{/mappedModels}}
31+
throw UnsupportedError('Invalid discriminator value for {{classname}}');
32+
}
33+
}
34+
extension {{classname}}BuilderDiscriminatorExt on {{classname}}Builder {
35+
{{discriminator.propertyType}} get discriminatorValue {
36+
{{#mappedModels}}
37+
if (this is {{modelName}}Builder) {
38+
return {{discriminator.propertyType}}.valueOf(r'{{mappingName}}');
39+
}
40+
{{/mappedModels}}
41+
throw UnsupportedError('Invalid discriminator value for {{classname}}Builder');
42+
}
43+
}
44+
{{/discriminator.isEnum}}

modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioClientCodegenTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,32 @@ public void verifyDartDioGeneratorRuns() throws IOException {
115115
TestUtils.ensureContainsFile(files, output, "README.md");
116116
TestUtils.ensureContainsFile(files, output, "lib/src/api.dart");
117117
}
118+
119+
@Test
120+
public void verifyEnumDiscriminatorUsesEnumType() throws IOException {
121+
File output = Files.createTempDirectory("test").toFile();
122+
output.deleteOnExit();
123+
124+
final CodegenConfigurator configurator = new CodegenConfigurator()
125+
.setGeneratorName("dart-dio")
126+
.setInputSpec("src/test/resources/3_0/dart-dio/enum-discriminator.yaml")
127+
.setOutputDir(output.getAbsolutePath().replace("\\", "/"))
128+
.addAdditionalProperty(CodegenConstants.SERIALIZATION_LIBRARY, DartDioClientCodegen.SERIALIZATION_LIBRARY_BUILT_VALUE)
129+
.addAdditionalProperty(CodegenConstants.LEGACY_DISCRIMINATOR_BEHAVIOR, false)
130+
.addAdditionalProperty(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE, true);
131+
132+
ClientOptInput opts = configurator.toClientOptInput();
133+
134+
Generator generator = new DefaultGenerator().opts(opts);
135+
List<File> files = generator.generate();
136+
files.forEach(File::deleteOnExit);
137+
138+
File modelFile = new File(output, "lib/src/model/merchant_details_dto.dart");
139+
TestUtils.ensureContainsFile(files, output, "lib/src/model/merchant_details_dto.dart");
140+
141+
String contents = Files.readString(modelFile.toPath(), StandardCharsets.UTF_8);
142+
Assert.assertTrue(contents.contains("MerchantTypeEnum get discriminatorValue"));
143+
Assert.assertTrue(contents.contains("MerchantTypeEnum.valueOf(r'TYPE_A')"));
144+
Assert.assertFalse(contents.contains("String? get discriminatorValue"));
145+
}
118146
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
openapi: 3.0.3
2+
info:
3+
title: Dart Dio Enum Discriminator
4+
version: 1.0.0
5+
paths:
6+
/merchant:
7+
get:
8+
responses:
9+
'200':
10+
description: ok
11+
content:
12+
application/json:
13+
schema:
14+
$ref: '#/components/schemas/MerchantDetailsDto'
15+
components:
16+
schemas:
17+
MerchantDetailsDto:
18+
type: object
19+
properties:
20+
uuid:
21+
type: string
22+
format: uuid
23+
merchantType:
24+
$ref: '#/components/schemas/MerchantTypeEnum'
25+
required:
26+
- uuid
27+
- merchantType
28+
discriminator:
29+
propertyName: merchantType
30+
mapping:
31+
TYPE_A: '#/components/schemas/MerchantDetailsTypeADto'
32+
TYPE_B: '#/components/schemas/MerchantDetailsTypeBDto'
33+
MerchantDetailsTypeADto:
34+
allOf:
35+
- $ref: '#/components/schemas/MerchantDetailsDto'
36+
- type: object
37+
properties:
38+
aField:
39+
type: string
40+
MerchantDetailsTypeBDto:
41+
allOf:
42+
- $ref: '#/components/schemas/MerchantDetailsDto'
43+
- type: object
44+
properties:
45+
bField:
46+
type: string
47+
MerchantTypeEnum:
48+
type: string
49+
enum:
50+
- TYPE_A
51+
- TYPE_B

samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/fruit.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,25 @@ abstract class Fruit implements Built<Fruit, FruitBuilder> {
4646
}
4747

4848
extension FruitDiscriminatorExt on Fruit {
49-
String? get discriminatorValue {
49+
FruitType get discriminatorValue {
5050
if (this is Apple) {
51-
return r'APPLE';
51+
return FruitType.valueOf(r'APPLE');
5252
}
5353
if (this is Banana) {
54-
return r'BANANA';
54+
return FruitType.valueOf(r'BANANA');
5555
}
56-
return null;
56+
throw UnsupportedError('Invalid discriminator value for Fruit');
5757
}
5858
}
5959
extension FruitBuilderDiscriminatorExt on FruitBuilder {
60-
String? get discriminatorValue {
60+
FruitType get discriminatorValue {
6161
if (this is AppleBuilder) {
62-
return r'APPLE';
62+
return FruitType.valueOf(r'APPLE');
6363
}
6464
if (this is BananaBuilder) {
65-
return r'BANANA';
65+
return FruitType.valueOf(r'BANANA');
6666
}
67-
return null;
67+
throw UnsupportedError('Invalid discriminator value for FruitBuilder');
6868
}
6969
}
7070

0 commit comments

Comments
 (0)