Skip to content

Commit

Permalink
Use toJson() instead of .name if enums have toJson(). (#596)
Browse files Browse the repository at this point in the history
* The version of source_gen must be lower than 1.4.0.

[email protected] requires Dart 3.0.

* Use `toJson()` instead of `.name` if enums have `toJson()`.
  • Loading branch information
kzrnm authored Jul 5, 2023
1 parent e187541 commit a11998e
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 11 deletions.
2 changes: 1 addition & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ dependency_overrides:
path: ../retrofit
retrofit_generator:
path: ../generator
source_gen: ^1.2.7
source_gen: ">=1.3.0 <1.4.0"
2 changes: 1 addition & 1 deletion example_relative_base_url/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ dependency_overrides:
path: ../retrofit
retrofit_generator:
path: ../generator
source_gen: ^1.2.7
source_gen: ">=1.3.0 <1.4.0"
3 changes: 3 additions & 0 deletions generator/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Changelog
## 7.0.8
- Use `toJson()` instead of `.name` if enums have `toJson()`.

## 7.0.7

- Enums return types generated iterating over the enum values instead of calling `.toJson()` method
Expand Down
28 changes: 21 additions & 7 deletions generator/lib/src/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ You should create a new class to encapsulate the response.
'$displayString.fromJson($_resultVar.data!,${_getInnerJsonSerializableMapperFn(returnType)})',
);
} else {
if (_isEnum(returnType)) {
if (_isEnum(returnType) && !_hasFromJson(returnType)) {
mapperCode = refer(
'${_displayString(returnType)}.values.firstWhere((e) => e.name == _result.data,'
'orElse: () => throw ArgumentError('
Expand Down Expand Up @@ -1307,12 +1307,13 @@ if (T != dynamic &&
_typeChecker(Float).isExactlyType(returnType);
}

bool _isEnum(DartType? dartType){
if (dartType == null || dartType.element == null){
bool _isEnum(DartType? dartType) {
if (dartType == null || dartType.element == null) {
return false;
}
return dartType.element is EnumElement;
}

bool _isDateTime(DartType? dartType) {
if (dartType == null) {
return false;
Expand All @@ -1325,6 +1326,20 @@ if (T != dynamic &&
return _isBasicType(innerType);
}

bool _hasFromJson(DartType? dartType) {
if (dartType is! InterfaceType) {
return false;
}
return dartType.element.getNamedConstructor('fromJson') != null;
}

bool _hasToJson(DartType? dartType) {
if (dartType is! InterfaceType) {
return false;
}
return dartType.element.getMethod('toJson') != null;
}

void _generateQueries(
MethodElement m,
List<Code> blocks,
Expand All @@ -1347,12 +1362,11 @@ if (T != dynamic &&
.nullSafeProperty('toIso8601String')
.call([])
: refer(p.displayName).property('toIso8601String').call([]);
} else if(_isEnum(p.type)) {
} else if (_isEnum(p.type) && !_hasToJson(p.type)) {
value = p.type.nullabilitySuffix == NullabilitySuffix.question
? refer(p.displayName)
.nullSafeProperty('name')
? refer(p.displayName).nullSafeProperty('name')
: refer(p.displayName).property('name');
}else{
} else {
value = p.type.nullabilitySuffix == NullabilitySuffix.question
? refer(p.displayName).nullSafeProperty('toJson').call([])
: refer(p.displayName).property('toJson').call([]);
Expand Down
2 changes: 1 addition & 1 deletion generator/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ topics:
- build-runner
- codegen
- api
version: 7.0.7
version: 7.0.8
environment:
sdk: '>=2.19.0 <4.0.0'

Expand Down
48 changes: 47 additions & 1 deletion generator/test/src/generator_test_src.dart
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,8 @@ abstract class EnumReturnType {
}

enum EnumParam {
enabled, disabled,
enabled,
disabled,
}

@ShouldGenerate(
Expand All @@ -416,6 +417,51 @@ abstract class TestQueryParamEnum {
Future<void> getTest(@Query('test') EnumParam? status);
}

enum FromJsonEnum {
a,
b,
;

factory FromJsonEnum.fromJson(Map<String, dynamic> json) => FromJsonEnum.a;
}

@ShouldGenerate(
'''
final value = FromJsonEnum.fromJson(_result.data!);
return value;
''',
contains: true,
)
@RestApi()
abstract class EnumFromJsonReturnType {
@GET('/')
Future<FromJsonEnum> getTestEnum();
}

enum ToJsonEnum {
plus(1),
minus(-1),
;

const ToJsonEnum(this.value);

final int value;

int toJson() => value;
}

@ShouldGenerate(
'''
final queryParameters = <String, dynamic>{r'test': status?.toJson()};
''',
contains: true,
)
@RestApi()
abstract class TestQueryParamEnumToJson {
@GET('/test')
Future<void> getTest(@Query('test') ToJsonEnum? status);
}

@ShouldGenerate(
'''
Stream<User> getUser() async* {
Expand Down

0 comments on commit a11998e

Please sign in to comment.