Patches for private fields, isModelClass, etc.; bump to 2.0.10

This commit is contained in:
Tobe O 2018-07-11 11:45:45 -04:00
parent c7a5c917df
commit e6f82341d1
25 changed files with 329 additions and 107 deletions

View file

@ -1,2 +1,2 @@
# Generated by pub on 2018-06-29 00:08:13.330472. # Generated by pub on 2018-07-11 11:34:17.168572.
angel_serialize:lib/ angel_serialize:lib/

View file

@ -1,3 +1,6 @@
# 2.0.4
* Added `generatedSerializable`.
# 2.0.3 # 2.0.3
* Increased the upper SDK boundary. * Increased the upper SDK boundary.

View file

@ -1,2 +1,3 @@
analyzer: analyzer:
strong-mode: true strong-mode:
implicit-casts: false

View file

@ -37,6 +37,13 @@ class Serializable {
const Serializable serializable = const Serializable(); const Serializable serializable = const Serializable();
/// Used by `package:angel_serialize_generator` to reliably identify generated models.
class GeneratedSerializable {
const GeneratedSerializable();
}
const GeneratedSerializable generatedSerializable = const GeneratedSerializable();
/// The supported serialization types. /// The supported serialization types.
abstract class Serializers { abstract class Serializers {
/// All supported serialization types. /// All supported serialization types.

View file

@ -1,5 +1,5 @@
name: angel_serialize name: angel_serialize
version: 2.0.3 version: 2.0.4
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

View file

@ -1,3 +1,11 @@
# 2.0.10
* Generate `XFields.allFields` constant.
* No longer breaks in cases where `dynamic` is present.
* Call `toJson` in `toMap` on nested models.
* Never generate named parameters from private fields.
* Use the new `@generatedSerializable` to *always* find generated
models.
# 2.0.9+4 # 2.0.9+4
* Remove `defaults` in `build.yaml`. * Remove `defaults` in `build.yaml`.

View file

@ -1,2 +1,3 @@
analyzer: analyzer:
strong-mode: true strong-mode:
implicit-casts: false

View file

@ -19,13 +19,14 @@ targets:
_book: _book:
sources: sources:
- "test/models/book.dart" - "test/models/book.dart"
- "test/models/game_pad_button.dart"
- "test/models/with_enum.dart" - "test/models/with_enum.dart"
_typescript_definition: _typescript_definition:
sources: sources:
- "lib/*.dart" - "test/*.dart"
$default: $default:
dependencies: dependencies:
- ":_book" - ":_book"
sources: sources:
- "lib/*.dart"
- "test/models/author.dart" - "test/models/author.dart"
- "test/models/game_pad.dart"

View file

@ -53,7 +53,17 @@ TypeReference convertTypeReference(DartType t) {
bool isModelClass(DartType t) { bool isModelClass(DartType t) {
if (t == null) return false; if (t == null) return false;
if (serializableTypeChecker.hasAnnotationOf(t.element)) return true; if (serializableTypeChecker.hasAnnotationOf(t.element)) {
return true;
}
if (generatedSerializableTypeChecker.hasAnnotationOf(t.element)) {
return true;
}
if (const TypeChecker.fromRuntime(Model).isAssignableFromType(t)) {
return true;
}
if (t is InterfaceType) { if (t is InterfaceType) {
return isModelClass(t.superclass); return isModelClass(t.superclass);
@ -76,7 +86,7 @@ bool isEnumType(DartType t) {
} }
/// Determines if a [DartType] is a `List` with the first type argument being a `Model`. /// Determines if a [DartType] is a `List` with the first type argument being a `Model`.
bool isListModelType(InterfaceType t) { bool isListOfModelType(InterfaceType t) {
return const TypeChecker.fromRuntime(List).isAssignableFromType(t) && return const TypeChecker.fromRuntime(List).isAssignableFromType(t) &&
t.typeArguments.length == 1 && t.typeArguments.length == 1 &&
isModelClass(t.typeArguments[0]); isModelClass(t.typeArguments[0]);
@ -89,7 +99,8 @@ bool isMapToModelType(InterfaceType t) {
isModelClass(t.typeArguments[1]); isModelClass(t.typeArguments[1]);
} }
bool isAssignableToModel(DartType type) => const TypeChecker.fromRuntime(Model).isAssignableFromType(type); bool isAssignableToModel(DartType type) =>
const TypeChecker.fromRuntime(Model).isAssignableFromType(type);
/// Compute a [String] representation of a [type]. /// Compute a [String] representation of a [type].
String typeToString(DartType type) { String typeToString(DartType type) {

View file

@ -19,6 +19,9 @@ const TypeChecker excludeTypeChecker = const TypeChecker.fromRuntime(Exclude);
const TypeChecker serializableTypeChecker = const TypeChecker serializableTypeChecker =
const TypeChecker.fromRuntime(Serializable); const TypeChecker.fromRuntime(Serializable);
const TypeChecker generatedSerializableTypeChecker =
const TypeChecker.fromRuntime(GeneratedSerializable);
/// Create a [BuildContext]. /// Create a [BuildContext].
Future<BuildContext> buildContext( Future<BuildContext> buildContext(
ClassElement clazz, ClassElement clazz,
@ -43,6 +46,11 @@ Future<BuildContext> buildContext(
List<String> fieldNames = []; List<String> fieldNames = [];
for (var field in clazz.fields) { for (var field in clazz.fields) {
// Skip private fields
if (field.name.startsWith('_')) {
continue;
}
if (field.getter != null && if (field.getter != null &&
(field.setter != null || field.getter.isAbstract)) { (field.setter != null || field.getter.isAbstract)) {
var el = field.setter == null ? field.getter : field; var el = field.setter == null ? field.getter : field;
@ -80,8 +88,7 @@ Future<BuildContext> buildContext(
if (required != null) { if (required != null) {
var cr = new ConstantReader(required); var cr = new ConstantReader(required);
var reason = cr.peek('reason')?.stringValue ?? var reason = cr.peek('reason')?.stringValue ??
"Missing required field '${ctx.resolveFieldName(field.name)}' on ${ctx "Missing required field '${ctx.resolveFieldName(field.name)}' on ${ctx.modelClassName}.";
.modelClassName}.";
ctx.requiredFields[field.name] = reason; ctx.requiredFields[field.name] = reason;
} }

View file

@ -11,7 +11,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
if (element.kind != ElementKind.CLASS) if (element.kind != ElementKind.CLASS)
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, annotation, buildStep, var ctx = await buildContext(element as ClassElement, annotation, buildStep,
await buildStep.resolver, true, autoIdAndDateFields != false); await buildStep.resolver, true, autoIdAndDateFields != false);
var lib = new Library((b) { var lib = new Library((b) {
@ -26,7 +26,9 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
void generateClass( void generateClass(
BuildContext ctx, LibraryBuilder file, ConstantReader annotation) { BuildContext ctx, LibraryBuilder file, ConstantReader annotation) {
file.body.add(new Class((clazz) { file.body.add(new Class((clazz) {
clazz..name = ctx.modelClassNameRecase.pascalCase; clazz
..name = ctx.modelClassNameRecase.pascalCase
..annotations.add(refer('generatedSerializable'));
if (shouldBeConstant(ctx)) { if (shouldBeConstant(ctx)) {
clazz.implements.add(new Reference(ctx.originalClassName)); clazz.implements.add(new Reference(ctx.originalClassName));
@ -122,8 +124,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
if (!shouldBeConstant(ctx) || if (!shouldBeConstant(ctx) ||
ctx.clazz.unnamedConstructor?.isConst == true) ctx.clazz.unnamedConstructor?.isConst == true)
constructor.initializers.add(new Code( constructor.initializers.add(new Code(
'super(${ctx.constructorParameters.map((p) => p.name).join( 'super(${ctx.constructorParameters.map((p) => p.name).join(',')})'));
',')})'));
} }
})); }));
} }
@ -172,30 +173,32 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
} }
static String generateEquality(DartType type, [bool nullable = false]) { static String generateEquality(DartType type, [bool nullable = false]) {
//if (type is! InterfaceType) return 'const DefaultEquality()'; if (type is InterfaceType) {
var it = type as InterfaceType; if (const TypeChecker.fromRuntime(List).isAssignableFromType(type)) {
if (const TypeChecker.fromRuntime(List).isAssignableFromType(type)) { if (type.typeParameters.length == 1) {
if (it.typeParameters.length == 1) { var eq = generateEquality(type.typeArguments[0]);
var eq = generateEquality(it.typeArguments[0]); return 'const ListEquality<${type.typeArguments[0].name}>($eq)';
return 'const ListEquality<${it.typeArguments[0].name}>($eq)'; } else
} else return 'const ListEquality<${type.typeArguments[0].name}>()';
return 'const ListEquality<${it.typeArguments[0].name}>()'; } else if (const TypeChecker.fromRuntime(Map)
} else if (const TypeChecker.fromRuntime(Map).isAssignableFromType(type)) { .isAssignableFromType(type)) {
if (it.typeParameters.length == 2) { if (type.typeParameters.length == 2) {
var keq = generateEquality(it.typeArguments[0]), var keq = generateEquality(type.typeArguments[0]),
veq = generateEquality(it.typeArguments[1]); veq = generateEquality(type.typeArguments[1]);
return 'const MapEquality<${it.typeArguments[0].name}, ${it return 'const MapEquality<${type.typeArguments[0].name}, ${type.typeArguments[1].name}>(keys: $keq, values: $veq)';
.typeArguments[1].name}>(keys: $keq, values: $veq)'; } else
} else return 'const MapEquality()<${type.typeArguments[0].name}, ${type.typeArguments[1].name}>';
return 'const MapEquality()<${it.typeArguments[0].name}, ${it }
.typeArguments[1].name}>';
}
return nullable ? null : 'const DefaultEquality<${type.name}>()'; return nullable ? null : 'const DefaultEquality<${type.name}>()';
} else {
return 'const DefaultEquality()';
}
} }
static String Function(String, String) generateComparator(DartType type) { static String Function(String, String) generateComparator(DartType type) {
if (type is! InterfaceType) return (a, b) => '$a == $b'; if (type is! InterfaceType || type.name == 'dynamic')
return (a, b) => '$a == $b';
var eq = generateEquality(type, true); var eq = generateEquality(type, true);
if (eq == null) return (a, b) => '$a == $b'; if (eq == null) return (a, b) => '$a == $b';
return (a, b) => '$eq.equals($a, $b)'; return (a, b) => '$eq.equals($a, $b)';

View file

@ -11,7 +11,7 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
if (element.kind != ElementKind.CLASS) if (element.kind != ElementKind.CLASS)
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, annotation, buildStep, var ctx = await buildContext(element as ClassElement, annotation, buildStep,
await buildStep.resolver, true, autoSnakeCaseNames != false); await buildStep.resolver, true, autoSnakeCaseNames != false);
var serializers = annotation.peek('serializers')?.listValue ?? []; var serializers = annotation.peek('serializers')?.listValue ?? [];
@ -109,7 +109,7 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
} else if (field.type is InterfaceType) { } else if (field.type is InterfaceType) {
var t = field.type as InterfaceType; var t = field.type as InterfaceType;
if (isListModelType(t)) { if (isListOfModelType(t)) {
//var rc = new ReCase(t.typeArguments[0].name); //var rc = new ReCase(t.typeArguments[0].name);
serializedRepresentation = ''' serializedRepresentation = '''
model.${field.name} model.${field.name}
@ -191,13 +191,13 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
if (i++ > 0) buf.write(', '); if (i++ > 0) buf.write(', ');
String deserializedRepresentation = "map['$alias'] as ${typeToString( String deserializedRepresentation =
field.type)}"; "map['$alias'] as ${typeToString(field.type)}";
// Deserialize dates // Deserialize dates
if (dateTimeTypeChecker.isAssignableFromType(field.type)) if (dateTimeTypeChecker.isAssignableFromType(field.type))
deserializedRepresentation = "map['$alias'] != null ? " deserializedRepresentation = "map['$alias'] != null ? "
"(map['$alias'] is DateTime ? (map['$alias'] as DateTime) : DateTime.parse(map['$alias']))" "(map['$alias'] is DateTime ? (map['$alias'] as DateTime) : DateTime.parse(map['$alias'].toString()))"
" : null"; " : null";
// Serialize model classes via `XSerializer.toMap` // Serialize model classes via `XSerializer.toMap`
@ -209,7 +209,7 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
} else if (field.type is InterfaceType) { } else if (field.type is InterfaceType) {
var t = field.type as InterfaceType; var t = field.type as InterfaceType;
if (isListModelType(t)) { if (isListOfModelType(t)) {
var rc = new ReCase(t.typeArguments[0].name); 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)"
@ -254,6 +254,20 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
..abstract = true ..abstract = true
..name = '${ctx.modelClassNameRecase.pascalCase}Fields'; ..name = '${ctx.modelClassNameRecase.pascalCase}Fields';
clazz.fields.add(new Field((b) {
b
..static = true
..modifier = FieldModifier.constant
..type = new TypeReference((b) => b
..symbol = 'List'
..types.add(refer('String')))
..name = 'allFields'
..assignment = literalConstList(
ctx.fields.map((f) => refer(f.name)).toList(),
refer('String'))
.code;
}));
for (var field in ctx.fields) { for (var field in ctx.fields) {
clazz.fields.add(new Field((b) { clazz.fields.add(new Field((b) {
b b

View file

@ -15,7 +15,7 @@ class TypeScriptDefinitionBuilder implements Builder {
Future<String> compileToTypeScriptType( Future<String> compileToTypeScriptType(
BuildContext ctx, BuildContext ctx,
String fieldName, String fieldName,
InterfaceType type, DartType type,
List<String> refs, List<String> refs,
List<CodeBuffer> ext, List<CodeBuffer> ext,
BuildStep buildStep) async { BuildStep buildStep) async {
@ -33,18 +33,20 @@ class TypeScriptDefinitionBuilder implements Builder {
typeScriptType = tsType; typeScriptType = tsType;
}); });
if (isListModelType(type)) { if (type is InterfaceType) {
var arg = await compileToTypeScriptType( if (isListOfModelType(type)) {
ctx, fieldName, type.typeArguments[0], refs, ext, buildStep); var arg = await compileToTypeScriptType(
typeScriptType = '$arg[]'; ctx, fieldName, type.typeArguments[0], refs, ext, buildStep);
} else if (const TypeChecker.fromRuntime(Map).isAssignableFromType(type) && typeScriptType = '$arg[]';
type.typeArguments.length == 2) { } else if (const TypeChecker.fromRuntime(Map)
var key = await compileToTypeScriptType( .isAssignableFromType(type) &&
ctx, fieldName, type.typeArguments[0], refs, ext, buildStep); type.typeArguments.length == 2) {
var value = await compileToTypeScriptType( var key = await compileToTypeScriptType(
ctx, fieldName, type.typeArguments[1], refs, ext, buildStep); ctx, fieldName, type.typeArguments[0], refs, ext, buildStep);
//var modelType = type.typeArguments[1]; var value = await compileToTypeScriptType(
/*var innerCtx = await buildContext( ctx, fieldName, type.typeArguments[1], refs, ext, buildStep);
//var modelType = type.typeArguments[1];
/*var innerCtx = await buildContext(
modelType.element, modelType.element,
new ConstantReader( new ConstantReader(
serializableTypeChecker.firstAnnotationOf(modelType.element)), serializableTypeChecker.firstAnnotationOf(modelType.element)),
@ -54,50 +56,52 @@ class TypeScriptDefinitionBuilder implements Builder {
true, true,
);*/ );*/
typeScriptType = ctx.modelClassNameRecase.pascalCase + typeScriptType = ctx.modelClassNameRecase.pascalCase +
new ReCase(fieldName).pascalCase; new ReCase(fieldName).pascalCase;
ext.add(new CodeBuffer() ext.add(new CodeBuffer()
..writeln('interface $typeScriptType {') ..writeln('interface $typeScriptType {')
..indent() ..indent()
..writeln('[key: $key]: $value;') ..writeln('[key: $key]: $value;')
..outdent() ..outdent()
..writeln('}')); ..writeln('}'));
} else if (const TypeChecker.fromRuntime(List).isAssignableFromType(type)) { } else if (const TypeChecker.fromRuntime(List)
if (type.typeArguments.length == 0) .isAssignableFromType(type)) {
typeScriptType = 'any[]'; if (type.typeArguments.length == 0)
else { typeScriptType = 'any[]';
var arg = await compileToTypeScriptType( else {
ctx, fieldName, type.typeArguments[0], refs, ext, buildStep); var arg = await compileToTypeScriptType(
typeScriptType = '$arg[]'; ctx, fieldName, type.typeArguments[0], refs, ext, buildStep);
typeScriptType = '$arg[]';
}
} else if (isModelClass(type)) {
var sourcePath = buildStep.inputId.uri.toString();
var targetPath = type.element.source.uri.toString();
if (!p.equals(sourcePath, targetPath)) {
//var relative = p.relative(targetPath, from: sourcePath);
var relative = (p.dirname(targetPath) == p.dirname(sourcePath))
? p.basename(targetPath)
: p.relative(targetPath, from: sourcePath);
var parent = p.dirname(relative);
var filename =
p.setExtension(p.basenameWithoutExtension(relative), '.d.ts');
relative = p.joinAll(p.split(parent).toList()..add(filename));
var ref = '/// <reference path="$relative" />';
if (!refs.contains(ref)) refs.add(ref);
}
var ctx = await buildContext(
type.element,
new ConstantReader(
serializableTypeChecker.firstAnnotationOf(type.element)),
buildStep,
buildStep.resolver,
autoSnakeCaseNames,
true,
);
typeScriptType = ctx.modelClassNameRecase.pascalCase;
} }
} else if (isModelClass(type)) {
var sourcePath = buildStep.inputId.uri.toString();
var targetPath = type.element.source.uri.toString();
if (!p.equals(sourcePath, targetPath)) {
//var relative = p.relative(targetPath, from: sourcePath);
var relative = (p.dirname(targetPath) == p.dirname(sourcePath))
? p.basename(targetPath)
: p.relative(targetPath, from: sourcePath);
var parent = p.dirname(relative);
var filename =
p.setExtension(p.basenameWithoutExtension(relative), '.d.ts');
relative = p.joinAll(p.split(parent).toList()..add(filename));
var ref = '/// <reference path="$relative" />';
if (!refs.contains(ref)) refs.add(ref);
}
var ctx = await buildContext(
type.element,
new ConstantReader(
serializableTypeChecker.firstAnnotationOf(type.element)),
buildStep,
buildStep.resolver,
autoSnakeCaseNames,
true,
);
typeScriptType = ctx.modelClassNameRecase.pascalCase;
} }
return typeScriptType; return typeScriptType;
@ -133,7 +137,7 @@ class TypeScriptDefinitionBuilder implements Builder {
} }
contexts.add(await buildContext( contexts.add(await buildContext(
element.element, element.element as ClassElement,
element.annotation, element.annotation,
buildStep, buildStep,
await buildStep.resolver, await buildStep.resolver,

View file

@ -1,5 +1,5 @@
name: angel_serialize_generator name: angel_serialize_generator
version: 2.0.9+4 version: 2.0.10
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

View file

@ -6,6 +6,7 @@ part of angel_serialize.test.models.author;
// JsonModelGenerator // JsonModelGenerator
// ************************************************************************** // **************************************************************************
@generatedSerializable
class Author extends _Author { class Author extends _Author {
Author( Author(
{this.id, {this.id,
@ -87,6 +88,7 @@ class Author extends _Author {
} }
} }
@generatedSerializable
class Library extends _Library { class Library extends _Library {
Library( Library(
{this.id, Map<String, Book> collection, this.createdAt, this.updatedAt}) {this.id, Map<String, Book> collection, this.createdAt, this.updatedAt})
@ -132,6 +134,7 @@ class Library extends _Library {
} }
} }
@generatedSerializable
class Bookmark extends _Bookmark { class Bookmark extends _Bookmark {
Bookmark(Book book, Bookmark(Book book,
{this.id, {this.id,

View file

@ -32,12 +32,12 @@ abstract class AuthorSerializer {
createdAt: map['created_at'] != null createdAt: map['created_at'] != null
? (map['created_at'] is DateTime ? (map['created_at'] is DateTime
? (map['created_at'] as DateTime) ? (map['created_at'] as DateTime)
: DateTime.parse(map['created_at'])) : DateTime.parse(map['created_at'].toString()))
: null, : null,
updatedAt: map['updated_at'] != null updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime ? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime) ? (map['updated_at'] as DateTime)
: DateTime.parse(map['updated_at'])) : DateTime.parse(map['updated_at'].toString()))
: null); : null);
} }
@ -100,12 +100,12 @@ abstract class LibrarySerializer {
createdAt: map['created_at'] != null createdAt: map['created_at'] != null
? (map['created_at'] is DateTime ? (map['created_at'] is DateTime
? (map['created_at'] as DateTime) ? (map['created_at'] as DateTime)
: DateTime.parse(map['created_at'])) : DateTime.parse(map['created_at'].toString()))
: null, : null,
updatedAt: map['updated_at'] != null updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime ? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime) ? (map['updated_at'] as DateTime)
: DateTime.parse(map['updated_at'])) : DateTime.parse(map['updated_at'].toString()))
: null); : null);
} }
@ -148,12 +148,12 @@ abstract class BookmarkSerializer {
createdAt: map['created_at'] != null createdAt: map['created_at'] != null
? (map['created_at'] is DateTime ? (map['created_at'] is DateTime
? (map['created_at'] as DateTime) ? (map['created_at'] as DateTime)
: DateTime.parse(map['created_at'])) : DateTime.parse(map['created_at'].toString()))
: null, : null,
updatedAt: map['updated_at'] != null updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime ? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime) ? (map['updated_at'] as DateTime)
: DateTime.parse(map['updated_at'])) : DateTime.parse(map['updated_at'].toString()))
: null); : null);
} }

View file

@ -6,6 +6,7 @@ part of angel_serialize.test.models.book;
// JsonModelGenerator // JsonModelGenerator
// ************************************************************************** // **************************************************************************
@generatedSerializable
class Book extends _Book { class Book extends _Book {
Book( Book(
{this.id, {this.id,

View file

@ -19,12 +19,12 @@ abstract class BookSerializer {
createdAt: map['created_at'] != null createdAt: map['created_at'] != null
? (map['created_at'] is DateTime ? (map['created_at'] is DateTime
? (map['created_at'] as DateTime) ? (map['created_at'] as DateTime)
: DateTime.parse(map['created_at'])) : DateTime.parse(map['created_at'].toString()))
: null, : null,
updatedAt: map['updated_at'] != null updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime ? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime) ? (map['updated_at'] as DateTime)
: DateTime.parse(map['updated_at'])) : DateTime.parse(map['updated_at'].toString()))
: null); : null);
} }

View file

@ -0,0 +1,12 @@
import 'package:angel_serialize/angel_serialize.dart';
import 'package:collection/collection.dart';
import 'game_pad_button.dart';
part 'game_pad.g.dart';
part 'game_pad.serializer.g.dart';
@Serializable(autoIdAndDateFields: false)
abstract class _Gamepad {
List<GamepadButton> get buttons;
Map<String, dynamic> get dynamicMap;
}

View file

@ -0,0 +1,41 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'game_pad.dart';
// **************************************************************************
// JsonModelGenerator
// **************************************************************************
@generatedSerializable
class Gamepad implements _Gamepad {
const Gamepad(
{List<GamepadButton> this.buttons, Map<String, dynamic> this.dynamicMap});
@override
final List<GamepadButton> buttons;
@override
final Map<String, dynamic> dynamicMap;
Gamepad copyWith(
{List<GamepadButton> buttons, Map<String, dynamic> dynamicMap}) {
return new Gamepad(
buttons: buttons ?? this.buttons,
dynamicMap: dynamicMap ?? this.dynamicMap);
}
bool operator ==(other) {
return other is _Gamepad &&
const ListEquality<GamepadButton>(
const DefaultEquality<GamepadButton>())
.equals(other.buttons, buttons) &&
const MapEquality<String, dynamic>(
keys: const DefaultEquality<String>(),
values: const DefaultEquality())
.equals(other.dynamicMap, dynamicMap);
}
Map<String, dynamic> toJson() {
return GamepadSerializer.toMap(this);
}
}

View file

@ -0,0 +1,35 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'game_pad.dart';
// **************************************************************************
// SerializerGenerator
// **************************************************************************
abstract class GamepadSerializer {
static Gamepad fromMap(Map map) {
return new Gamepad(
buttons: map['buttons'] is Iterable
? new List.unmodifiable(((map['buttons'] as Iterable)
.where((x) => x is Map) as Iterable<Map>)
.map(GamepadButtonSerializer.fromMap))
: null,
dynamicMap: map['dynamic_map'] as Map<String, dynamic>);
}
static Map<String, dynamic> toMap(Gamepad model) {
if (model == null) {
return null;
}
return {
'buttons': model.buttons?.map((m) => m.toJson())?.toList(),
'dynamic_map': model.dynamicMap
};
}
}
abstract class GamepadFields {
static const String buttons = 'buttons';
static const String dynamicMap = 'dynamic_map';
}

View file

@ -0,0 +1,9 @@
import 'package:angel_serialize/angel_serialize.dart';
part 'game_pad_button.g.dart';
part 'game_pad_button.serializer.g.dart';
@Serializable(autoIdAndDateFields: false)
abstract class _GamepadButton {
String get name;
int get radius;
}

View file

@ -0,0 +1,33 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'game_pad_button.dart';
// **************************************************************************
// JsonModelGenerator
// **************************************************************************
@generatedSerializable
class GamepadButton implements _GamepadButton {
const GamepadButton({this.name, this.radius});
@override
final String name;
@override
final int radius;
GamepadButton copyWith({String name, int radius}) {
return new GamepadButton(
name: name ?? this.name, radius: radius ?? this.radius);
}
bool operator ==(other) {
return other is _GamepadButton &&
other.name == name &&
other.radius == radius;
}
Map<String, dynamic> toJson() {
return GamepadButtonSerializer.toMap(this);
}
}

View file

@ -0,0 +1,27 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'game_pad_button.dart';
// **************************************************************************
// SerializerGenerator
// **************************************************************************
abstract class GamepadButtonSerializer {
static GamepadButton fromMap(Map map) {
return new GamepadButton(
name: map['name'] as String, radius: map['radius'] as int);
}
static Map<String, dynamic> toMap(GamepadButton model) {
if (model == null) {
return null;
}
return {'name': model.name, 'radius': model.radius};
}
}
abstract class GamepadButtonFields {
static const String name = 'name';
static const String radius = 'radius';
}

View file

@ -3,9 +3,10 @@
part of 'with_enum.dart'; part of 'with_enum.dart';
// ************************************************************************** // **************************************************************************
// Generator: JsonModelGenerator // JsonModelGenerator
// ************************************************************************** // **************************************************************************
@generatedSerializable
class WithEnum implements _WithEnum { class WithEnum implements _WithEnum {
const WithEnum({this.type, List<int> this.finalList}); const WithEnum({this.type, List<int> this.finalList});