Skip to content

Commit b4ea00e

Browse files
authored
[dart][dart-dio] Add built_value date support w/o timemachine (#9180)
* [dart][dart-dio] Add built_value date support w/o timemachine * Test improvements * Fix lists of dates not working
1 parent 7a1f7b2 commit b4ea00e

File tree

23 files changed

+292
-25
lines changed

23 files changed

+292
-25
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioNextClientCodegen.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,19 @@ private void configureDateLibrary(String srcFolder) {
205205
imports.put("OffsetDate", "package:time_machine/time_machine.dart");
206206
imports.put("OffsetDateTime", "package:time_machine/time_machine.dart");
207207
if (SERIALIZATION_LIBRARY_BUILT_VALUE.equals(library)) {
208-
supportingFiles.add(new SupportingFile("serialization/built_value/local_date_serializer.mustache", srcFolder, "local_date_serializer.dart"));
208+
supportingFiles.add(new SupportingFile("serialization/built_value/offset_date_serializer.mustache", srcFolder, "local_date_serializer.dart"));
209209
}
210210
break;
211211
default:
212212
case DATE_LIBRARY_CORE:
213-
// this option uses the dart core classes
214213
additionalProperties.put("useDateLibCore", "true");
214+
if (SERIALIZATION_LIBRARY_BUILT_VALUE.equals(library)) {
215+
typeMapping.put("date", "Date");
216+
typeMapping.put("Date", "Date");
217+
importMapping.put("Date", "package:" + pubName + "/src/model/date.dart");
218+
supportingFiles.add(new SupportingFile("serialization/built_value/date.mustache", srcFolder + File.separator + "model", "date.dart"));
219+
supportingFiles.add(new SupportingFile("serialization/built_value/date_serializer.mustache", srcFolder, "date_serializer.dart"));
220+
}
215221
break;
216222
}
217223
}

modules/openapi-generator/src/main/resources/dart/libraries/dio/lib.mustache

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ export 'package:{{pubName}}/src/api.dart';
33
export 'package:{{pubName}}/src/auth/api_key_auth.dart';
44
export 'package:{{pubName}}/src/auth/basic_auth.dart';
55
export 'package:{{pubName}}/src/auth/oauth.dart';
6-
{{#useBuiltValue}}export 'package:{{pubName}}/src/serializers.dart';{{/useBuiltValue}}
6+
{{#useBuiltValue}}export 'package:{{pubName}}/src/serializers.dart';
7+
{{#useDateLibCore}}export 'package:{{pubName}}/src/model/date.dart';{{/useDateLibCore}}{{/useBuiltValue}}
78

89
{{#apiInfo}}{{#apis}}export 'package:{{pubName}}/src/api/{{classFilename}}.dart';
910
{{/apis}}{{/apiInfo}}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/// A gregorian calendar date generated by
2+
/// OpenAPI generator to differentiate
3+
/// between [DateTime] and [Date] formats.
4+
class Date implements Comparable<Date> {
5+
final int year;
6+
7+
/// January is 1.
8+
final int month;
9+
10+
/// First day is 1.
11+
final int day;
12+
13+
Date(this.year, this.month, this.day);
14+
15+
/// The current date
16+
static Date now({bool utc = false}) {
17+
var now = DateTime.now();
18+
if (utc) {
19+
now = now.toUtc();
20+
}
21+
return now.toDate();
22+
}
23+
24+
/// Convert to a [DateTime].
25+
DateTime toDateTime({bool utc = false}) {
26+
if (utc) {
27+
DateTime.utc(year, month, day);
28+
}
29+
return DateTime(year, month, day);
30+
}
31+
32+
@override
33+
int compareTo(Date other) {
34+
int d = year.compareTo(other.year);
35+
if (d != 0) {
36+
return d;
37+
}
38+
d = month.compareTo(other.month);
39+
if (d != 0) {
40+
return d;
41+
}
42+
return day.compareTo(other.day);
43+
}
44+
45+
@override
46+
bool operator ==(Object other) =>
47+
identical(this, other) ||
48+
other is Date &&
49+
runtimeType == other.runtimeType &&
50+
year == other.year &&
51+
month == other.month &&
52+
day == other.day;
53+
54+
@override
55+
int get hashCode => year.hashCode ^ month.hashCode ^ day.hashCode;
56+
57+
@override
58+
String toString() {
59+
final yyyy = year.toString();
60+
final mm = month.toString().padLeft(2, '0');
61+
final dd = day.toString().padLeft(2, '0');
62+
63+
return '$yyyy-$mm-$dd';
64+
}
65+
}
66+
67+
extension DateTimeToDate on DateTime {
68+
Date toDate() => Date(year, month, day);
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{{>header}}
2+
import 'package:built_collection/built_collection.dart';
3+
import 'package:built_value/serializer.dart';
4+
import 'package:{{pubName}}/src/model/date.dart';
5+
6+
class DateSerializer implements PrimitiveSerializer<Date> {
7+
8+
const DateSerializer();
9+
10+
@override
11+
Iterable<Type> get types => BuiltList.of([Date]);
12+
13+
@override
14+
String get wireName => 'Date';
15+
16+
@override
17+
Date deserialize(Serializers serializers, Object serialized,
18+
{FullType specifiedType = FullType.unspecified}) {
19+
final parsed = DateTime.parse(serialized as String);
20+
return Date(parsed.year, parsed.month, parsed.day);
21+
}
22+
23+
@override
24+
Object serialize(Serializers serializers, Date date,
25+
{FullType specifiedType = FullType.unspecified}) {
26+
return date.toString();
27+
}
28+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class OffsetDateSerializer implements PrimitiveSerializer<OffsetDate> {
88
const OffsetDateSerializer();
99
1010
@override
11-
Iterable<Type> get types => BuiltList<Type>([OffsetDate]);
11+
Iterable<Type> get types => BuiltList.of([OffsetDate]);
1212
1313
@override
1414
String get wireName => 'OffsetDate';

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
{{>header}}
2+
// ignore_for_file: unused_import
3+
24
import 'package:built_collection/built_collection.dart';
35
import 'package:built_value/json_object.dart';
46
import 'package:built_value/serializer.dart';
57
import 'package:built_value/standard_json_plugin.dart';
6-
{{#useDateLibCore}}import 'package:built_value/iso_8601_date_time_serializer.dart';{{/useDateLibCore}}
8+
{{#useDateLibCore}}import 'package:built_value/iso_8601_date_time_serializer.dart';
9+
import 'package:{{pubName}}/src/date_serializer.dart';
10+
import 'package:{{pubName}}/src/model/date.dart';{{/useDateLibCore}}
711
{{#useDateLibTimeMachine}}import 'package:time_machine/time_machine.dart';
8-
import 'package:{{pubName}}/src/local_date_serializer.dart';{{/useDateLibTimeMachine}}
12+
import 'package:{{pubName}}/src/offset_date_serializer.dart';{{/useDateLibTimeMachine}}
913
{{#models}}{{#model}}import 'package:{{pubName}}/src/model/{{classFilename}}.dart';
1014
{{/model}}{{/models}}
1115
part 'serializers.g.dart';
@@ -25,8 +29,9 @@ Serializers serializers = (_$serializers.toBuilder(){{#apiInfo}}{{#apis}}{{#seri
2529
{{/isMap}}
2630
){{/serializers}}{{/apis}}{{/apiInfo}}{{#useDateLibTimeMachine}}
2731
..add(const OffsetDateSerializer())
28-
..add(const OffsetDateTimeSerializer()){{/useDateLibTimeMachine}}
29-
..add(Iso8601DateTimeSerializer()))
32+
..add(const OffsetDateTimeSerializer()){{/useDateLibTimeMachine}}{{#useDateLibCore}}
33+
..add(const DateSerializer())
34+
..add(Iso8601DateTimeSerializer())){{/useDateLibCore}}
3035
.build();
3136

3237
Serializers standardSerializers =

samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/.openapi-generator/FILES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ lib/src/auth/api_key_auth.dart
6666
lib/src/auth/auth.dart
6767
lib/src/auth/basic_auth.dart
6868
lib/src/auth/oauth.dart
69+
lib/src/date_serializer.dart
6970
lib/src/model/additional_properties_class.dart
7071
lib/src/model/animal.dart
7172
lib/src/model/api_response.dart
@@ -77,6 +78,7 @@ lib/src/model/cat.dart
7778
lib/src/model/cat_all_of.dart
7879
lib/src/model/category.dart
7980
lib/src/model/class_model.dart
81+
lib/src/model/date.dart
8082
lib/src/model/dog.dart
8183
lib/src/model/dog_all_of.dart
8284
lib/src/model/enum_arrays.dart

samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/doc/FakeApi.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ var int64 = 789; // int | None
478478
var float = 3.4; // double | None
479479
var string = string_example; // String | None
480480
var binary = BINARY_DATA_HERE; // Uint8List | None
481-
var date = 2013-10-20; // DateTime | None
481+
var date = 2013-10-20; // Date | None
482482
var dateTime = 2013-10-20T19:20:30+01:00; // DateTime | None
483483
var password = password_example; // String | None
484484
var callback = callback_example; // String | None
@@ -504,7 +504,7 @@ Name | Type | Description | Notes
504504
**float** | **double**| None | [optional]
505505
**string** | **String**| None | [optional]
506506
**binary** | **Uint8List**| None | [optional]
507-
**date** | **DateTime**| None | [optional]
507+
**date** | **Date**| None | [optional]
508508
**dateTime** | **DateTime**| None | [optional]
509509
**password** | **String**| None | [optional]
510510
**callback** | **String**| None | [optional]

samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/doc/FormatTest.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Name | Type | Description | Notes
1818
**string** | **String** | | [optional]
1919
**byte** | **String** | |
2020
**binary** | [**Uint8List**](Uint8List.md) | | [optional]
21-
**date** | [**DateTime**](DateTime.md) | |
21+
**date** | [**Date**](Date.md) | |
2222
**dateTime** | [**DateTime**](DateTime.md) | | [optional]
2323
**uuid** | **String** | | [optional]
2424
**password** | **String** | |

samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/doc/NullableClass.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Name | Type | Description | Notes
1212
**numberProp** | **num** | | [optional]
1313
**booleanProp** | **bool** | | [optional]
1414
**stringProp** | **String** | | [optional]
15-
**dateProp** | [**DateTime**](DateTime.md) | | [optional]
15+
**dateProp** | [**Date**](Date.md) | | [optional]
1616
**datetimeProp** | [**DateTime**](DateTime.md) | | [optional]
1717
**arrayNullableProp** | [**BuiltList<JsonObject>**](JsonObject.md) | | [optional]
1818
**arrayAndItemsNullableProp** | [**BuiltList<JsonObject>**](JsonObject.md) | | [optional]

samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/lib/openapi.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export 'package:openapi/src/auth/api_key_auth.dart';
77
export 'package:openapi/src/auth/basic_auth.dart';
88
export 'package:openapi/src/auth/oauth.dart';
99
export 'package:openapi/src/serializers.dart';
10+
export 'package:openapi/src/model/date.dart';
1011

1112
export 'package:openapi/src/api/another_fake_api.dart';
1213
export 'package:openapi/src/api/default_api.dart';

samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/lib/src/api/fake_api.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'package:dio/dio.dart';
1010
import 'dart:typed_data';
1111
import 'package:built_collection/built_collection.dart';
1212
import 'package:openapi/src/api_util.dart';
13+
import 'package:openapi/src/model/date.dart';
1314
import 'package:openapi/src/model/file_schema_test_class.dart';
1415
import 'package:openapi/src/model/health_check_result.dart';
1516
import 'package:openapi/src/model/model_client.dart';
@@ -826,7 +827,7 @@ class FakeApi {
826827
double? float,
827828
String? string,
828829
Uint8List? binary,
829-
DateTime? date,
830+
Date? date,
830831
DateTime? dateTime,
831832
String? password,
832833
String? callback,
@@ -875,7 +876,7 @@ class FakeApi {
875876
r'pattern_without_delimiter': encodeFormParameter(_serializers, patternWithoutDelimiter, const FullType(String)),
876877
r'byte': encodeFormParameter(_serializers, byte, const FullType(String)),
877878
if (binary != null) r'binary': MultipartFile.fromBytes(binary, filename: r'binary'),
878-
if (date != null) r'date': encodeFormParameter(_serializers, date, const FullType(DateTime)),
879+
if (date != null) r'date': encodeFormParameter(_serializers, date, const FullType(Date)),
879880
if (dateTime != null) r'dateTime': encodeFormParameter(_serializers, dateTime, const FullType(DateTime)),
880881
if (password != null) r'password': encodeFormParameter(_serializers, password, const FullType(String)),
881882
if (callback != null) r'callback': encodeFormParameter(_serializers, callback, const FullType(String)),
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//
2+
// AUTO-GENERATED FILE, DO NOT MODIFY!
3+
//
4+
5+
import 'package:built_collection/built_collection.dart';
6+
import 'package:built_value/serializer.dart';
7+
import 'package:openapi/src/model/date.dart';
8+
9+
class DateSerializer implements PrimitiveSerializer<Date> {
10+
11+
const DateSerializer();
12+
13+
@override
14+
Iterable<Type> get types => BuiltList.of([Date]);
15+
16+
@override
17+
String get wireName => 'Date';
18+
19+
@override
20+
Date deserialize(Serializers serializers, Object serialized,
21+
{FullType specifiedType = FullType.unspecified}) {
22+
final parsed = DateTime.parse(serialized as String);
23+
return Date(parsed.year, parsed.month, parsed.day);
24+
}
25+
26+
@override
27+
Object serialize(Serializers serializers, Date date,
28+
{FullType specifiedType = FullType.unspecified}) {
29+
return date.toString();
30+
}
31+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/// A gregorian calendar date generated by
2+
/// OpenAPI generator to differentiate
3+
/// between [DateTime] and [Date] formats.
4+
class Date implements Comparable<Date> {
5+
final int year;
6+
7+
/// January is 1.
8+
final int month;
9+
10+
/// First day is 1.
11+
final int day;
12+
13+
Date(this.year, this.month, this.day);
14+
15+
/// The current date
16+
static Date now({bool utc = false}) {
17+
var now = DateTime.now();
18+
if (utc) {
19+
now = now.toUtc();
20+
}
21+
return now.toDate();
22+
}
23+
24+
/// Convert to a [DateTime].
25+
DateTime toDateTime({bool utc = false}) {
26+
if (utc) {
27+
DateTime.utc(year, month, day);
28+
}
29+
return DateTime(year, month, day);
30+
}
31+
32+
@override
33+
int compareTo(Date other) {
34+
int d = year.compareTo(other.year);
35+
if (d != 0) {
36+
return d;
37+
}
38+
d = month.compareTo(other.month);
39+
if (d != 0) {
40+
return d;
41+
}
42+
return day.compareTo(other.day);
43+
}
44+
45+
@override
46+
bool operator ==(Object other) =>
47+
identical(this, other) ||
48+
other is Date &&
49+
runtimeType == other.runtimeType &&
50+
year == other.year &&
51+
month == other.month &&
52+
day == other.day;
53+
54+
@override
55+
int get hashCode => year.hashCode ^ month.hashCode ^ day.hashCode;
56+
57+
@override
58+
String toString() {
59+
final yyyy = year.toString();
60+
final mm = month.toString().padLeft(2, '0');
61+
final dd = day.toString().padLeft(2, '0');
62+
63+
return '$yyyy-$mm-$dd';
64+
}
65+
}
66+
67+
extension DateTimeToDate on DateTime {
68+
Date toDate() => Date(year, month, day);
69+
}

samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/lib/src/model/format_test.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//
44

55
import 'dart:typed_data';
6+
import 'package:openapi/src/model/date.dart';
67
import 'package:built_value/built_value.dart';
78
import 'package:built_value/serializer.dart';
89

@@ -42,7 +43,7 @@ abstract class FormatTest implements Built<FormatTest, FormatTestBuilder> {
4243
Uint8List? get binary;
4344

4445
@BuiltValueField(wireName: r'date')
45-
DateTime get date;
46+
Date get date;
4647

4748
@BuiltValueField(wireName: r'dateTime')
4849
DateTime? get dateTime;
@@ -141,7 +142,7 @@ class _$FormatTestSerializer implements StructuredSerializer<FormatTest> {
141142
result
142143
..add(r'date')
143144
..add(serializers.serialize(object.date,
144-
specifiedType: const FullType(DateTime)));
145+
specifiedType: const FullType(Date)));
145146
if (object.dateTime != null) {
146147
result
147148
..add(r'dateTime')
@@ -226,7 +227,7 @@ class _$FormatTestSerializer implements StructuredSerializer<FormatTest> {
226227
break;
227228
case r'date':
228229
result.date = serializers.deserialize(value,
229-
specifiedType: const FullType(DateTime)) as DateTime;
230+
specifiedType: const FullType(Date)) as Date;
230231
break;
231232
case r'dateTime':
232233
result.dateTime = serializers.deserialize(value,

0 commit comments

Comments
 (0)