2.4.1, etc.
This commit is contained in:
parent
8b5bb94981
commit
d97feaa899
16 changed files with 117 additions and 74 deletions
22
README.md
22
README.md
|
@ -255,13 +255,20 @@ Provide `serializer` and `deserializer` arguments to `@SerializableField()` as y
|
||||||
They are typically used together. Note that the argument to `serializer` will always be
|
They are typically used together. Note that the argument to `serializer` will always be
|
||||||
`dynamic`.
|
`dynamic`.
|
||||||
|
|
||||||
|
In such a case, you might want to also provide a `serializesTo` argument.
|
||||||
|
This lets the generator, as well as the ORM, apply the correct (de)serialization rules
|
||||||
|
and validations.
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
DateTime _dateFromString(s) => s is String ? HttpDate.parse(s) : null;
|
DateTime _dateFromString(s) => s is String ? HttpDate.parse(s) : null;
|
||||||
String _dateToString(v) => v == null ? null : HttpDate.format(v);
|
String _dateToString(v) => v == null ? null : HttpDate.format(v);
|
||||||
|
|
||||||
@Serializable(autoIdAndDateFields: false)
|
@serializable
|
||||||
abstract class _HttpRequest {
|
abstract class _HttpRequest {
|
||||||
@SerializableField(serializer: #_dateToString, deserializer: #_dateFromString)
|
@SerializableField(
|
||||||
|
serializer: #_dateToString,
|
||||||
|
deserializer: #_dateFromString,
|
||||||
|
serializesTo: String)
|
||||||
DateTime date;
|
DateTime date;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -294,15 +301,8 @@ then you will need to generate `book.g.dart` before, `author.g.dart`,
|
||||||
# ID and Dates
|
# ID and Dates
|
||||||
|
|
||||||
This package will automatically generate `id`, `createdAt`, and `updatedAt` fields for you,
|
This package will automatically generate `id`, `createdAt`, and `updatedAt` fields for you,
|
||||||
in the style of an Angel `Model`. To disable this, set `autoIdAndDateFields` to `false` in the
|
in the style of an Angel `Model`. This will automatically be generated, **only** for classes
|
||||||
builder constructor.
|
extending `Model`.
|
||||||
|
|
||||||
You can also override `autoIdAndDateFields` per model:
|
|
||||||
|
|
||||||
```dart
|
|
||||||
@Serializable(autoIdAndDateFields: false)
|
|
||||||
abstract class _Skinny extends Model {}
|
|
||||||
```
|
|
||||||
|
|
||||||
# Binary Data
|
# Binary Data
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# 2.2.1
|
||||||
|
* Add `serializesTo`.
|
||||||
|
|
||||||
# 2.2.0
|
# 2.2.0
|
||||||
* Add `@SerializableField`.
|
* Add `@SerializableField`.
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,14 @@ class SerializableField {
|
||||||
/// Whether this field can be serialized, if [exclude] is `true`. Defaults to `false`.
|
/// Whether this field can be serialized, if [exclude] is `true`. Defaults to `false`.
|
||||||
final bool canSerialize;
|
final bool canSerialize;
|
||||||
|
|
||||||
|
/// May be used with [serializer] and [deserializer].
|
||||||
|
///
|
||||||
|
/// Specifies the [Type] that this field serializes to.
|
||||||
|
///
|
||||||
|
/// Ex. If you have a field that serializes to a JSON string,
|
||||||
|
/// specify `serializesTo: String`.
|
||||||
|
final Type serializesTo;
|
||||||
|
|
||||||
const SerializableField(
|
const SerializableField(
|
||||||
{this.alias,
|
{this.alias,
|
||||||
this.defaultValue,
|
this.defaultValue,
|
||||||
|
@ -61,7 +69,8 @@ class SerializableField {
|
||||||
this.isNullable: true,
|
this.isNullable: true,
|
||||||
this.exclude: false,
|
this.exclude: false,
|
||||||
this.canDeserialize: false,
|
this.canDeserialize: false,
|
||||||
this.canSerialize: false});
|
this.canSerialize: false,
|
||||||
|
this.serializesTo});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Marks a class as eligible for serialization.
|
/// Marks a class as eligible for serialization.
|
||||||
|
@ -69,7 +78,7 @@ class Serializable {
|
||||||
const Serializable(
|
const Serializable(
|
||||||
{this.serializers: const [Serializers.map, Serializers.json],
|
{this.serializers: const [Serializers.map, Serializers.json],
|
||||||
this.autoSnakeCaseNames: true,
|
this.autoSnakeCaseNames: true,
|
||||||
this.autoIdAndDateFields: true,
|
@deprecated this.autoIdAndDateFields: true,
|
||||||
this.includeAnnotations: const []});
|
this.includeAnnotations: const []});
|
||||||
|
|
||||||
/// A list of enabled serialization modes.
|
/// A list of enabled serialization modes.
|
||||||
|
@ -81,6 +90,7 @@ class Serializable {
|
||||||
final bool autoSnakeCaseNames;
|
final bool autoSnakeCaseNames;
|
||||||
|
|
||||||
/// Overrides the setting in `JsonModelGenerator`.
|
/// Overrides the setting in `JsonModelGenerator`.
|
||||||
|
@deprecated
|
||||||
final bool autoIdAndDateFields;
|
final bool autoIdAndDateFields;
|
||||||
|
|
||||||
/// A list of constant members to affix to the generated class.
|
/// A list of constant members to affix to the generated class.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel_serialize
|
name: angel_serialize
|
||||||
version: 2.2.0
|
version: 2.2.1+2
|
||||||
description: Static annotations powering Angel model serialization. Combine with angel_serialize_generator for flexible modeling.
|
description: Static annotations powering Angel model serialization. Combine with angel_serialize_generator for flexible modeling.
|
||||||
author: Tobe O <thosakwe@gmail.com>
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
homepage: https://github.com/angel-dart/serialize
|
homepage: https://github.com/angel-dart/serialize
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
# 2.4.1
|
||||||
|
* Support `serializesTo`.
|
||||||
|
* Don't emit `@required` if there is a default value.
|
||||||
|
* Deprecate `autoIdAndDateFields`.
|
||||||
|
|
||||||
# 2.4.0
|
# 2.4.0
|
||||||
* Introduce `@SerializableField`, and say goodbye to annotation hell.
|
* Introduce `@SerializableField`, and say goodbye to annotation hell.
|
||||||
* Support custom (de)serializers.
|
* Support custom (de)serializers.
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:analyzer/dart/constant/value.dart';
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:analyzer/dart/element/type.dart';
|
import 'package:analyzer/dart/element/type.dart';
|
||||||
import 'package:analyzer/src/dart/element/element.dart';
|
import 'package:analyzer/src/dart/element/element.dart';
|
||||||
|
import 'package:angel_model/angel_model.dart';
|
||||||
import 'package:angel_serialize/angel_serialize.dart';
|
import 'package:angel_serialize/angel_serialize.dart';
|
||||||
import 'package:build/build.dart';
|
import 'package:build/build.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
@ -37,7 +38,6 @@ Future<BuildContext> buildContext(
|
||||||
BuildStep buildStep,
|
BuildStep buildStep,
|
||||||
Resolver resolver,
|
Resolver resolver,
|
||||||
bool autoSnakeCaseNames,
|
bool autoSnakeCaseNames,
|
||||||
bool autoIdAndDateFields,
|
|
||||||
{bool heedExclude: true}) async {
|
{bool heedExclude: true}) async {
|
||||||
var id = clazz.location.components.join('-');
|
var id = clazz.location.components.join('-');
|
||||||
if (_cache.containsKey(id)) {
|
if (_cache.containsKey(id)) {
|
||||||
|
@ -45,8 +45,6 @@ Future<BuildContext> buildContext(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for autoIdAndDateFields, autoSnakeCaseNames
|
// Check for autoIdAndDateFields, autoSnakeCaseNames
|
||||||
autoIdAndDateFields =
|
|
||||||
annotation.peek('autoIdAndDateFields')?.boolValue ?? autoIdAndDateFields;
|
|
||||||
autoSnakeCaseNames =
|
autoSnakeCaseNames =
|
||||||
annotation.peek('autoSnakeCaseNames')?.boolValue ?? autoSnakeCaseNames;
|
annotation.peek('autoSnakeCaseNames')?.boolValue ?? autoSnakeCaseNames;
|
||||||
|
|
||||||
|
@ -55,7 +53,6 @@ Future<BuildContext> buildContext(
|
||||||
clazz,
|
clazz,
|
||||||
originalClassName: clazz.name,
|
originalClassName: clazz.name,
|
||||||
sourceFilename: p.basename(buildStep.inputId.path),
|
sourceFilename: p.basename(buildStep.inputId.path),
|
||||||
autoIdAndDateFields: autoIdAndDateFields,
|
|
||||||
autoSnakeCaseNames: autoSnakeCaseNames,
|
autoSnakeCaseNames: autoSnakeCaseNames,
|
||||||
includeAnnotations:
|
includeAnnotations:
|
||||||
annotation.peek('includeAnnotations')?.listValue ?? <DartObject>[],
|
annotation.peek('includeAnnotations')?.listValue ?? <DartObject>[],
|
||||||
|
@ -79,7 +76,7 @@ Future<BuildContext> buildContext(
|
||||||
|
|
||||||
if (fieldAnn != null) {
|
if (fieldAnn != null) {
|
||||||
var cr = ConstantReader(fieldAnn);
|
var cr = ConstantReader(fieldAnn);
|
||||||
var sField = SerializableField(
|
var sField = SerializableFieldMirror(
|
||||||
alias: cr.peek('alias')?.stringValue,
|
alias: cr.peek('alias')?.stringValue,
|
||||||
defaultValue: cr.peek('defaultValue')?.objectValue,
|
defaultValue: cr.peek('defaultValue')?.objectValue,
|
||||||
serializer: cr.peek('serializer')?.symbolValue,
|
serializer: cr.peek('serializer')?.symbolValue,
|
||||||
|
@ -89,12 +86,13 @@ Future<BuildContext> buildContext(
|
||||||
canDeserialize: cr.peek('canDeserialize')?.boolValue ?? false,
|
canDeserialize: cr.peek('canDeserialize')?.boolValue ?? false,
|
||||||
canSerialize: cr.peek('canSerialize')?.boolValue ?? false,
|
canSerialize: cr.peek('canSerialize')?.boolValue ?? false,
|
||||||
exclude: cr.peek('exclude')?.boolValue ?? false,
|
exclude: cr.peek('exclude')?.boolValue ?? false,
|
||||||
|
serializesTo: cr.peek('serializesTo')?.typeValue,
|
||||||
);
|
);
|
||||||
|
|
||||||
ctx.fieldInfo[field.name] = sField;
|
ctx.fieldInfo[field.name] = sField;
|
||||||
|
|
||||||
if (sField.defaultValue != null) {
|
if (sField.defaultValue != null) {
|
||||||
ctx.defaults[field.name] = sField.defaultValue as DartObject;
|
ctx.defaults[field.name] = sField.defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sField.alias != null) {
|
if (sField.alias != null) {
|
||||||
|
@ -175,7 +173,7 @@ Future<BuildContext> buildContext(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (autoIdAndDateFields != false) {
|
if (const TypeChecker.fromRuntime(Model).isAssignableFromType(clazz.type)) {
|
||||||
if (!fieldNames.contains('id')) {
|
if (!fieldNames.contains('id')) {
|
||||||
var idField =
|
var idField =
|
||||||
new ShimFieldImpl('id', lib.context.typeProvider.stringType);
|
new ShimFieldImpl('id', lib.context.typeProvider.stringType);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:analyzer/dart/constant/value.dart';
|
import 'package:analyzer/dart/constant/value.dart';
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
|
import 'package:analyzer/dart/element/type.dart';
|
||||||
import 'package:angel_serialize/angel_serialize.dart';
|
import 'package:angel_serialize/angel_serialize.dart';
|
||||||
import 'package:code_builder/code_builder.dart';
|
import 'package:code_builder/code_builder.dart';
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
|
@ -20,7 +21,7 @@ class BuildContext {
|
||||||
final Map<String, DartObject> defaults = {};
|
final Map<String, DartObject> defaults = {};
|
||||||
|
|
||||||
/// A map of fields to their related information.
|
/// A map of fields to their related information.
|
||||||
final Map<String, SerializableField> fieldInfo = {};
|
final Map<String, SerializableFieldMirror> fieldInfo = {};
|
||||||
|
|
||||||
/// A map of fields that have been marked as to be excluded from serialization.
|
/// A map of fields that have been marked as to be excluded from serialization.
|
||||||
// ignore: deprecated_member_use
|
// ignore: deprecated_member_use
|
||||||
|
@ -78,4 +79,31 @@ class BuildContext {
|
||||||
/// Get the aliased name (if one is defined) for a field.
|
/// Get the aliased name (if one is defined) for a field.
|
||||||
String resolveFieldName(String name) =>
|
String resolveFieldName(String name) =>
|
||||||
aliases.containsKey(name) ? aliases[name] : name;
|
aliases.containsKey(name) ? aliases[name] : name;
|
||||||
|
|
||||||
|
/// Finds the type that the field [name] should serialize to.
|
||||||
|
DartType resolveSerializedFieldType(String name) {
|
||||||
|
return fieldInfo[name]?.serializesTo ??
|
||||||
|
fields.firstWhere((f) => f.name == name).type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SerializableFieldMirror {
|
||||||
|
final String alias;
|
||||||
|
final DartObject defaultValue;
|
||||||
|
final Symbol serializer, deserializer;
|
||||||
|
final String errorMessage;
|
||||||
|
final bool isNullable, canDeserialize, canSerialize, exclude;
|
||||||
|
final DartType serializesTo;
|
||||||
|
|
||||||
|
SerializableFieldMirror(
|
||||||
|
{this.alias,
|
||||||
|
this.defaultValue,
|
||||||
|
this.serializer,
|
||||||
|
this.deserializer,
|
||||||
|
this.errorMessage,
|
||||||
|
this.isNullable,
|
||||||
|
this.canDeserialize,
|
||||||
|
this.canSerialize,
|
||||||
|
this.exclude,
|
||||||
|
this.serializesTo});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
part of angel_serialize_generator;
|
part of angel_serialize_generator;
|
||||||
|
|
||||||
class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
|
class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
|
||||||
final bool autoIdAndDateFields;
|
const JsonModelGenerator();
|
||||||
|
|
||||||
const JsonModelGenerator({this.autoIdAndDateFields: true});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<String> generateForAnnotatedElement(
|
Future<String> generateForAnnotatedElement(
|
||||||
|
@ -12,7 +10,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
|
||||||
throw 'Only classes can be annotated with a @Serializable() annotation.';
|
throw 'Only classes can be annotated with a @Serializable() annotation.';
|
||||||
|
|
||||||
var ctx = await buildContext(element as ClassElement, annotation, buildStep,
|
var ctx = await buildContext(element as ClassElement, annotation, buildStep,
|
||||||
await buildStep.resolver, true, autoIdAndDateFields != false);
|
await buildStep.resolver, true);
|
||||||
|
|
||||||
var lib = new Library((b) {
|
var lib = new Library((b) {
|
||||||
generateClass(ctx, b, annotation);
|
generateClass(ctx, b, annotation);
|
||||||
|
|
|
@ -12,7 +12,7 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
|
||||||
throw 'Only classes can be annotated with a @Serializable() annotation.';
|
throw 'Only classes can be annotated with a @Serializable() annotation.';
|
||||||
|
|
||||||
var ctx = await buildContext(element as ClassElement, annotation, buildStep,
|
var ctx = await buildContext(element as ClassElement, annotation, buildStep,
|
||||||
await buildStep.resolver, true, autoSnakeCaseNames != false);
|
await buildStep.resolver, autoSnakeCaseNames != false);
|
||||||
|
|
||||||
var serializers = annotation.peek('serializers')?.listValue ?? [];
|
var serializers = annotation.peek('serializers')?.listValue ?? [];
|
||||||
|
|
||||||
|
@ -80,6 +80,8 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
|
||||||
|
|
||||||
// Add named parameters
|
// Add named parameters
|
||||||
for (var field in ctx.fields) {
|
for (var field in ctx.fields) {
|
||||||
|
var type = ctx.resolveSerializedFieldType(field.name);
|
||||||
|
|
||||||
// Skip excluded fields
|
// Skip excluded fields
|
||||||
if (ctx.excluded[field.name]?.canSerialize == false) continue;
|
if (ctx.excluded[field.name]?.canSerialize == false) continue;
|
||||||
|
|
||||||
|
@ -102,19 +104,17 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize dates
|
// Serialize dates
|
||||||
else if (dateTimeTypeChecker.isAssignableFromType(field.type))
|
else if (dateTimeTypeChecker.isAssignableFromType(type))
|
||||||
serializedRepresentation = 'model.${field.name}?.toIso8601String()';
|
serializedRepresentation = 'model.${field.name}?.toIso8601String()';
|
||||||
|
|
||||||
// Serialize model classes via `XSerializer.toMap`
|
// Serialize model classes via `XSerializer.toMap`
|
||||||
else if (isModelClass(field.type)) {
|
else if (isModelClass(type)) {
|
||||||
var rc = new ReCase(field.type.name);
|
var rc = new ReCase(type.name);
|
||||||
serializedRepresentation =
|
serializedRepresentation =
|
||||||
'${serializerToMap(rc, 'model.${field.name}')}';
|
'${serializerToMap(rc, 'model.${field.name}')}';
|
||||||
} else if (field.type is InterfaceType) {
|
} else if (type is InterfaceType) {
|
||||||
var t = field.type as InterfaceType;
|
if (isListOfModelType(type)) {
|
||||||
|
var name = type.typeArguments[0].name;
|
||||||
if (isListOfModelType(t)) {
|
|
||||||
var name = t.typeArguments[0].name;
|
|
||||||
if (name.startsWith('_')) name = name.substring(1);
|
if (name.startsWith('_')) name = name.substring(1);
|
||||||
var rc = new ReCase(name);
|
var rc = new ReCase(name);
|
||||||
var m = serializerToMap(rc, 'm');
|
var m = serializerToMap(rc, 'm');
|
||||||
|
@ -122,21 +122,21 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
|
||||||
model.${field.name}
|
model.${field.name}
|
||||||
?.map((m) => $m)
|
?.map((m) => $m)
|
||||||
?.toList()''';
|
?.toList()''';
|
||||||
} else if (isMapToModelType(t)) {
|
} else if (isMapToModelType(type)) {
|
||||||
var rc = new ReCase(t.typeArguments[1].name);
|
var rc = new ReCase(type.typeArguments[1].name);
|
||||||
serializedRepresentation =
|
serializedRepresentation =
|
||||||
'''model.${field.name}.keys?.fold({}, (map, key) {
|
'''model.${field.name}.keys?.fold({}, (map, key) {
|
||||||
return map..[key] =
|
return map..[key] =
|
||||||
${serializerToMap(rc, 'model.${field.name}[key]')};
|
${serializerToMap(rc, 'model.${field.name}[key]')};
|
||||||
})''';
|
})''';
|
||||||
} else if (t.element.isEnum) {
|
} else if (type.element.isEnum) {
|
||||||
serializedRepresentation = '''
|
serializedRepresentation = '''
|
||||||
model.${field.name} == null ?
|
model.${field.name} == null ?
|
||||||
null
|
null
|
||||||
: ${t.name}.values.indexOf(model.${field.name})
|
: ${type.name}.values.indexOf(model.${field.name})
|
||||||
''';
|
''';
|
||||||
} else if (const TypeChecker.fromRuntime(Uint8List)
|
} else if (const TypeChecker.fromRuntime(Uint8List)
|
||||||
.isAssignableFromType(t)) {
|
.isAssignableFromType(type)) {
|
||||||
serializedRepresentation = '''
|
serializedRepresentation = '''
|
||||||
model.${field.name} == null ?
|
model.${field.name} == null ?
|
||||||
null
|
null
|
||||||
|
@ -199,6 +199,8 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var field in ctx.fields) {
|
for (var field in ctx.fields) {
|
||||||
|
var type = ctx.resolveSerializedFieldType(field.name);
|
||||||
|
|
||||||
if (ctx.excluded[field.name]?.canDeserialize == false) continue;
|
if (ctx.excluded[field.name]?.canDeserialize == false) continue;
|
||||||
|
|
||||||
var alias = ctx.resolveFieldName(field.name);
|
var alias = ctx.resolveFieldName(field.name);
|
||||||
|
@ -206,7 +208,7 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
|
||||||
if (i++ > 0) buf.write(', ');
|
if (i++ > 0) buf.write(', ');
|
||||||
|
|
||||||
String deserializedRepresentation =
|
String deserializedRepresentation =
|
||||||
"map['$alias'] as ${typeToString(field.type)}";
|
"map['$alias'] as ${typeToString(type)}";
|
||||||
|
|
||||||
var defaultValue = 'null';
|
var defaultValue = 'null';
|
||||||
var existingDefault = ctx.defaults[field.name];
|
var existingDefault = ctx.defaults[field.name];
|
||||||
|
@ -221,29 +223,27 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
|
||||||
var name =
|
var name =
|
||||||
MirrorSystem.getName(ctx.fieldInfo[field.name].deserializer);
|
MirrorSystem.getName(ctx.fieldInfo[field.name].deserializer);
|
||||||
deserializedRepresentation = "$name(map['$alias'])";
|
deserializedRepresentation = "$name(map['$alias'])";
|
||||||
} else if (dateTimeTypeChecker.isAssignableFromType(field.type))
|
} else if (dateTimeTypeChecker.isAssignableFromType(type))
|
||||||
deserializedRepresentation = "map['$alias'] != null ? "
|
deserializedRepresentation = "map['$alias'] != null ? "
|
||||||
"(map['$alias'] is DateTime ? (map['$alias'] as DateTime) : DateTime.parse(map['$alias'].toString()))"
|
"(map['$alias'] is DateTime ? (map['$alias'] as DateTime) : DateTime.parse(map['$alias'].toString()))"
|
||||||
" : $defaultValue";
|
" : $defaultValue";
|
||||||
|
|
||||||
// Serialize model classes via `XSerializer.toMap`
|
// Serialize model classes via `XSerializer.toMap`
|
||||||
else if (isModelClass(field.type)) {
|
else if (isModelClass(type)) {
|
||||||
var rc = new ReCase(field.type.name);
|
var rc = new ReCase(type.name);
|
||||||
deserializedRepresentation = "map['$alias'] != null"
|
deserializedRepresentation = "map['$alias'] != null"
|
||||||
" ? ${rc.pascalCase}Serializer.fromMap(map['$alias'] as Map)"
|
" ? ${rc.pascalCase}Serializer.fromMap(map['$alias'] as Map)"
|
||||||
" : $defaultValue";
|
" : $defaultValue";
|
||||||
} else if (field.type is InterfaceType) {
|
} else if (type is InterfaceType) {
|
||||||
var t = field.type as InterfaceType;
|
if (isListOfModelType(type)) {
|
||||||
|
var rc = new ReCase(type.typeArguments[0].name);
|
||||||
if (isListOfModelType(t)) {
|
|
||||||
var rc = new ReCase(t.typeArguments[0].name);
|
|
||||||
deserializedRepresentation = "map['$alias'] is Iterable"
|
deserializedRepresentation = "map['$alias'] is Iterable"
|
||||||
" ? new List.unmodifiable(((map['$alias'] as Iterable)"
|
" ? new List.unmodifiable(((map['$alias'] as Iterable)"
|
||||||
".where((x) => x is Map) as Iterable<Map>)"
|
".where((x) => x is Map) as Iterable<Map>)"
|
||||||
".map(${rc.pascalCase}Serializer.fromMap))"
|
".map(${rc.pascalCase}Serializer.fromMap))"
|
||||||
" : $defaultValue";
|
" : $defaultValue";
|
||||||
} else if (isMapToModelType(t)) {
|
} else if (isMapToModelType(type)) {
|
||||||
var rc = new ReCase(t.typeArguments[1].name);
|
var rc = new ReCase(type.typeArguments[1].name);
|
||||||
deserializedRepresentation = '''
|
deserializedRepresentation = '''
|
||||||
map['$alias'] is Map
|
map['$alias'] is Map
|
||||||
? new Map.unmodifiable((map['$alias'] as Map).keys.fold({}, (out, key) {
|
? new Map.unmodifiable((map['$alias'] as Map).keys.fold({}, (out, key) {
|
||||||
|
@ -252,21 +252,21 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
|
||||||
}))
|
}))
|
||||||
: $defaultValue
|
: $defaultValue
|
||||||
''';
|
''';
|
||||||
} else if (t.element.isEnum) {
|
} else if (type.element.isEnum) {
|
||||||
deserializedRepresentation = '''
|
deserializedRepresentation = '''
|
||||||
map['$alias'] is ${t.name}
|
map['$alias'] is ${type.name}
|
||||||
? (map['$alias'] as ${t.name})
|
? (map['$alias'] as ${type.name})
|
||||||
:
|
:
|
||||||
(
|
(
|
||||||
map['$alias'] is int
|
map['$alias'] is int
|
||||||
? ${t.name}.values[map['$alias'] as int]
|
? ${type.name}.values[map['$alias'] as int]
|
||||||
: $defaultValue
|
: $defaultValue
|
||||||
)
|
)
|
||||||
''';
|
''';
|
||||||
} else if (const TypeChecker.fromRuntime(List)
|
} else if (const TypeChecker.fromRuntime(List)
|
||||||
.isAssignableFromType(t) &&
|
.isAssignableFromType(type) &&
|
||||||
t.typeArguments.length == 1) {
|
type.typeArguments.length == 1) {
|
||||||
var arg = convertTypeReference(t.typeArguments[0])
|
var arg = convertTypeReference(type.typeArguments[0])
|
||||||
.accept(new DartEmitter());
|
.accept(new DartEmitter());
|
||||||
deserializedRepresentation = '''
|
deserializedRepresentation = '''
|
||||||
map['$alias'] is Iterable
|
map['$alias'] is Iterable
|
||||||
|
@ -274,11 +274,11 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
|
||||||
: $defaultValue
|
: $defaultValue
|
||||||
''';
|
''';
|
||||||
} else if (const TypeChecker.fromRuntime(Map)
|
} else if (const TypeChecker.fromRuntime(Map)
|
||||||
.isAssignableFromType(t) &&
|
.isAssignableFromType(type) &&
|
||||||
t.typeArguments.length == 2) {
|
type.typeArguments.length == 2) {
|
||||||
var key = convertTypeReference(t.typeArguments[0])
|
var key = convertTypeReference(type.typeArguments[0])
|
||||||
.accept(new DartEmitter());
|
.accept(new DartEmitter());
|
||||||
var value = convertTypeReference(t.typeArguments[1])
|
var value = convertTypeReference(type.typeArguments[1])
|
||||||
.accept(new DartEmitter());
|
.accept(new DartEmitter());
|
||||||
deserializedRepresentation = '''
|
deserializedRepresentation = '''
|
||||||
map['$alias'] is Map
|
map['$alias'] is Map
|
||||||
|
@ -286,7 +286,7 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
|
||||||
: $defaultValue
|
: $defaultValue
|
||||||
''';
|
''';
|
||||||
} else if (const TypeChecker.fromRuntime(Uint8List)
|
} else if (const TypeChecker.fromRuntime(Uint8List)
|
||||||
.isAssignableFromType(t)) {
|
.isAssignableFromType(type)) {
|
||||||
deserializedRepresentation = '''
|
deserializedRepresentation = '''
|
||||||
map['$alias'] is Uint8List
|
map['$alias'] is Uint8List
|
||||||
? (map['$alias'] as Uint8List)
|
? (map['$alias'] as Uint8List)
|
||||||
|
|
|
@ -109,7 +109,6 @@ class TypeScriptDefinitionBuilder implements Builder {
|
||||||
buildStep,
|
buildStep,
|
||||||
buildStep.resolver,
|
buildStep.resolver,
|
||||||
autoSnakeCaseNames,
|
autoSnakeCaseNames,
|
||||||
true,
|
|
||||||
);
|
);
|
||||||
typeScriptType = ctx.modelClassNameRecase.pascalCase;
|
typeScriptType = ctx.modelClassNameRecase.pascalCase;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +151,6 @@ class TypeScriptDefinitionBuilder implements Builder {
|
||||||
element.annotation,
|
element.annotation,
|
||||||
buildStep,
|
buildStep,
|
||||||
await buildStep.resolver,
|
await buildStep.resolver,
|
||||||
true,
|
|
||||||
autoSnakeCaseNames != false));
|
autoSnakeCaseNames != false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,8 +182,8 @@ class TypeScriptDefinitionBuilder implements Builder {
|
||||||
if (ctx.excluded[field.name]?.canSerialize == false) continue;
|
if (ctx.excluded[field.name]?.canSerialize == false) continue;
|
||||||
|
|
||||||
var alias = ctx.resolveFieldName(field.name);
|
var alias = ctx.resolveFieldName(field.name);
|
||||||
var typeScriptType = await compileToTypeScriptType(
|
var typeScriptType = await compileToTypeScriptType(ctx, field.name,
|
||||||
ctx, field.name, field.type, refs, ext, buildStep);
|
ctx.resolveSerializedFieldType(field.name), refs, ext, buildStep);
|
||||||
|
|
||||||
// foo: string;
|
// foo: string;
|
||||||
if (!ctx.requiredFields.containsKey(field.name)) alias += '?';
|
if (!ctx.requiredFields.containsKey(field.name)) alias += '?';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel_serialize_generator
|
name: angel_serialize_generator
|
||||||
version: 2.4.0
|
version: 2.4.1
|
||||||
description: Model serialization generators, designed for use with Angel. Combine with angel_serialize for flexible modeling.
|
description: Model serialization generators, designed for use with Angel. Combine with angel_serialize for flexible modeling.
|
||||||
author: Tobe O <thosakwe@gmail.com>
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
homepage: https://github.com/angel-dart/serialize
|
homepage: https://github.com/angel-dart/serialize
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'package:collection/collection.dart';
|
||||||
import 'game_pad_button.dart';
|
import 'game_pad_button.dart';
|
||||||
part 'game_pad.g.dart';
|
part 'game_pad.g.dart';
|
||||||
|
|
||||||
@Serializable(autoIdAndDateFields: false)
|
@serializable
|
||||||
class _Gamepad {
|
class _Gamepad {
|
||||||
List<GamepadButton> buttons;
|
List<GamepadButton> buttons;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:angel_serialize/angel_serialize.dart';
|
import 'package:angel_serialize/angel_serialize.dart';
|
||||||
part 'game_pad_button.g.dart';
|
part 'game_pad_button.g.dart';
|
||||||
|
|
||||||
@Serializable(autoIdAndDateFields: false)
|
@serializable
|
||||||
abstract class _GamepadButton {
|
abstract class _GamepadButton {
|
||||||
String get name;
|
String get name;
|
||||||
int get radius;
|
int get radius;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'package:angel_serialize/angel_serialize.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
part 'goat.g.dart';
|
part 'goat.g.dart';
|
||||||
|
|
||||||
@Serializable(autoIdAndDateFields: false)
|
@serializable
|
||||||
abstract class _Goat {
|
abstract class _Goat {
|
||||||
@SerializableField(defaultValue: 34)
|
@SerializableField(defaultValue: 34)
|
||||||
int get integer;
|
int get integer;
|
||||||
|
|
|
@ -8,9 +8,12 @@ Map _fromString(v) => json.decode(v.toString()) as Map;
|
||||||
|
|
||||||
String _toString(Map v) => json.encode(v);
|
String _toString(Map v) => json.encode(v);
|
||||||
|
|
||||||
@Serializable(autoIdAndDateFields: false)
|
@serializable
|
||||||
abstract class _HasMap {
|
abstract class _HasMap {
|
||||||
@SerializableField(
|
@SerializableField(
|
||||||
serializer: #_toString, deserializer: #_fromString, isNullable: false)
|
serializer: #_toString,
|
||||||
|
deserializer: #_fromString,
|
||||||
|
isNullable: false,
|
||||||
|
serializesTo: String)
|
||||||
Map get value;
|
Map get value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import 'package:angel_serialize/angel_serialize.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
part 'with_enum.g.dart';
|
part 'with_enum.g.dart';
|
||||||
|
|
||||||
@Serializable(autoIdAndDateFields: false)
|
@serializable
|
||||||
abstract class _WithEnum {
|
abstract class _WithEnum {
|
||||||
WithEnumType get type;
|
WithEnumType get type;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue