Skip to content

Commit

Permalink
Merge pull request #429 from davidmorgan/iso-datetime
Browse files Browse the repository at this point in the history
Add Iso8601DateTimeSerializer.
  • Loading branch information
davidmorgan authored May 29, 2018
2 parents 74e7e0d + 46bec53 commit 9efbeed
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

- Support serializing `BuiltSet` with `StandardJsonPlugin`. It's serialized to
a JSON list.
- Add `Iso8601DateTimeSerializer` for use when you want ISO8601 serialization
instead of microseconds since epoch.
- Fix code generation when inherited generic fields are made non-generic.


# 5.4.5

- Improve error message on failure to deserialize.
Expand Down
38 changes: 38 additions & 0 deletions built_value/lib/iso_8601_date_time_serializer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2018, Google Inc. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

import 'package:built_collection/built_collection.dart';
import 'package:built_value/serializer.dart';

/// Alternative serializer for [DateTime].
///
/// Install this to use ISO8601 format instead of the default (microseconds
/// since epoch). Use [SerializersBuilder.add] to install it.
///
/// An exception will be thrown on attempt to serialize local DateTime
/// instances; you must use UTC.
class Iso8601DateTimeSerializer implements PrimitiveSerializer<DateTime> {
final bool structured = false;
@override
final Iterable<Type> types = new BuiltList<Type>([DateTime]);
@override
final String wireName = 'DateTime';

@override
Object serialize(Serializers serializers, DateTime dateTime,
{FullType specifiedType: FullType.unspecified}) {
if (!dateTime.isUtc) {
throw new ArgumentError.value(
dateTime, 'dateTime', 'Must be in utc for serialization.');
}

return dateTime.toIso8601String();
}

@override
DateTime deserialize(Serializers serializers, Object serialized,
{FullType specifiedType: FullType.unspecified}) {
return DateTime.parse(serialized as String).toUtc();
}
}
4 changes: 4 additions & 0 deletions built_value/lib/standard_json_plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import 'dart:convert' show json;
/// and support for more collection types. But, you may need to interact with
/// other systems that use simple map-based JSON. If so, use
/// [SerializersBuilder.addPlugin] to install this plugin.
///
/// When using this plugin you may wish to also install
/// `Iso8601DateTimeSerializer` which switches serialization of `DateTime`
/// from microseconds since epoch to ISO 8601 format.
class StandardJsonPlugin implements SerializerPlugin {
static final BuiltSet<Type> _unsupportedTypes =
new BuiltSet<Type>([BuiltListMultimap, BuiltSetMultimap]);
Expand Down
50 changes: 50 additions & 0 deletions built_value/test/iso_8601_date_time_serializer_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) 2018, Google Inc. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

import 'package:built_value/iso_8601_date_time_serializer.dart';
import 'package:built_value/serializer.dart';
import 'package:test/test.dart';

void main() {
final serializers = (new Serializers().toBuilder()
..add(new Iso8601DateTimeSerializer()))
.build();

group('DateTime with known specifiedType', () {
final data = new DateTime.utc(1980, 1, 2, 3, 4, 5, 6, 7);
final serialized = '1980-01-02T03:04:05.006007Z';
final specifiedType = const FullType(DateTime);

test('can be serialized', () {
expect(serializers.serialize(data, specifiedType: specifiedType),
serialized);
});

test('can be deserialized', () {
expect(serializers.deserialize(serialized, specifiedType: specifiedType),
data);
});

test('serialize throws if not UTC', () {
expect(() => serializers.serialize(new DateTime.now()),
throwsA(new isInstanceOf<ArgumentError>()));
});
});

group('DateTime with unknown specifiedType', () {
final data = new DateTime.utc(1980, 1, 2, 3, 4, 5, 6, 7);
final serialized = ['DateTime', '1980-01-02T03:04:05.006007Z'];
final specifiedType = FullType.unspecified;

test('can be serialized', () {
expect(serializers.serialize(data, specifiedType: specifiedType),
serialized);
});

test('can be deserialized', () {
expect(serializers.deserialize(serialized, specifiedType: specifiedType),
data);
});
});
}

0 comments on commit 9efbeed

Please sign in to comment.