Finish subclass
This commit is contained in:
parent
a4b56e7885
commit
642a7d98a8
8 changed files with 482 additions and 184 deletions
31
README.md
31
README.md
|
@ -9,6 +9,7 @@ the time you spend writing boilerplate serialization code for your models.
|
|||
|
||||
- [Usage](#usage)
|
||||
- [Models](#models)
|
||||
- [Subclasses](#subclasses)
|
||||
- [Field Aliases](#aliases)
|
||||
- [Excluding Keys](#excluding-keys)
|
||||
- [Required Fields](#required-fields)
|
||||
|
@ -158,6 +159,36 @@ You can customize these by means of `serializers`:
|
|||
class _MyClass extends Model {}
|
||||
```
|
||||
|
||||
## Subclasses
|
||||
`angel_serialize` pulls in fields from parent classes, as well as
|
||||
implemented interfaces, so it is extremely easy to share attributes among
|
||||
model classes:
|
||||
|
||||
```dart
|
||||
import 'package:angel_serialize/angel_serialize.dart';
|
||||
part 'subclass.g.dart';
|
||||
|
||||
@serializable
|
||||
class _Animal {
|
||||
@notNull
|
||||
String genus;
|
||||
@notNull
|
||||
String species;
|
||||
}
|
||||
|
||||
@serializable
|
||||
class _Bird extends _Animal {
|
||||
@DefaultsTo(false)
|
||||
bool isSparrow;
|
||||
}
|
||||
|
||||
var saxaulSparrow = Bird(
|
||||
genus: 'Passer',
|
||||
species: 'ammodendri',
|
||||
isSparrow: true,
|
||||
);
|
||||
```
|
||||
|
||||
## Aliases
|
||||
|
||||
Whereas Dart fields conventionally are camelCased, most database columns
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
# 2.5.0
|
||||
* Support mutable models (again).
|
||||
* Use `whereType()` instead of chaining `where()` and `cast()`.
|
||||
* Support pulling fields from parent classes and interfaces.
|
||||
* Only generate `const` constructors if *all*
|
||||
fields lack a setter.
|
||||
|
||||
# 2.4.4
|
||||
* Remove unnecessary `new` and `const`.
|
||||
|
|
|
@ -53,10 +53,22 @@ Future<BuildContext> buildContext(ClassElement clazz, ConstantReader annotation,
|
|||
includeAnnotations:
|
||||
annotation.peek('includeAnnotations')?.listValue ?? <DartObject>[],
|
||||
);
|
||||
var lib = await resolver.libraryFor(buildStep.inputId);
|
||||
// var lib = await resolver.libraryFor(buildStep.inputId);
|
||||
List<String> fieldNames = [];
|
||||
var fields = <FieldElement>[];
|
||||
|
||||
for (var field in clazz.fields) {
|
||||
// Crawl for classes from parent classes.
|
||||
void crawlClass(InterfaceType t) {
|
||||
while (t != null) {
|
||||
fields.insertAll(0, t.element.fields);
|
||||
t.interfaces.forEach(crawlClass);
|
||||
t = t.superclass;
|
||||
}
|
||||
}
|
||||
|
||||
crawlClass(clazz.type);
|
||||
|
||||
for (var field in fields) {
|
||||
// Skip private fields
|
||||
if (field.name.startsWith('_')) {
|
||||
continue;
|
||||
|
@ -196,30 +208,31 @@ Future<BuildContext> buildContext(ClassElement clazz, ConstantReader annotation,
|
|||
}
|
||||
}
|
||||
|
||||
if (const TypeChecker.fromRuntime(Model).isAssignableFromType(clazz.type)) {
|
||||
if (!fieldNames.contains('id')) {
|
||||
var idField = ShimFieldImpl('id', lib.context.typeProvider.stringType);
|
||||
ctx.fields.insert(0, idField);
|
||||
ctx.shimmed['id'] = true;
|
||||
}
|
||||
// ShimFields are no longer used.
|
||||
// if (const TypeChecker.fromRuntime(Model).isAssignableFromType(clazz.type)) {
|
||||
// if (!fieldNames.contains('id')) {
|
||||
// var idField = ShimFieldImpl('id', lib.context.typeProvider.stringType);
|
||||
// ctx.fields.insert(0, idField);
|
||||
// ctx.shimmed['id'] = true;
|
||||
// }
|
||||
|
||||
DartType dateTime;
|
||||
for (var key in ['createdAt', 'updatedAt']) {
|
||||
if (!fieldNames.contains(key)) {
|
||||
if (dateTime == null) {
|
||||
var coreLib =
|
||||
await resolver.libraries.singleWhere((lib) => lib.isDartCore);
|
||||
var dt = coreLib.getType('DateTime');
|
||||
dateTime = dt.type;
|
||||
}
|
||||
// DartType dateTime;
|
||||
// for (var key in ['createdAt', 'updatedAt']) {
|
||||
// if (!fieldNames.contains(key)) {
|
||||
// if (dateTime == null) {
|
||||
// var coreLib =
|
||||
// await resolver.libraries.singleWhere((lib) => lib.isDartCore);
|
||||
// var dt = coreLib.getType('DateTime');
|
||||
// dateTime = dt.type;
|
||||
// }
|
||||
|
||||
var field = ShimFieldImpl(key, dateTime);
|
||||
ctx.aliases[key] = ReCase(key).snakeCase;
|
||||
ctx.fields.add(field);
|
||||
ctx.shimmed[key] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// var field = ShimFieldImpl(key, dateTime);
|
||||
// ctx.aliases[key] = ReCase(key).snakeCase;
|
||||
// ctx.fields.add(field);
|
||||
// ctx.shimmed[key] = true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Get constructor params, if any
|
||||
ctx.constructorParameters.addAll(clazz.unnamedConstructor.parameters);
|
||||
|
|
|
@ -94,8 +94,11 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
|
|||
BuildContext ctx, ClassBuilder clazz, LibraryBuilder file) {
|
||||
clazz.constructors.add(Constructor((constructor) {
|
||||
// Add all `super` params
|
||||
constructor.constant = ctx.clazz.unnamedConstructor?.isConst == true ||
|
||||
shouldBeConstant(ctx);
|
||||
constructor.constant = (ctx.clazz.unnamedConstructor?.isConst == true ||
|
||||
shouldBeConstant(ctx)) &&
|
||||
ctx.fields.every((f) {
|
||||
return f.setter == null && f is! ShimFieldImpl;
|
||||
});
|
||||
|
||||
for (var param in ctx.constructorParameters) {
|
||||
constructor.requiredParameters.add(Parameter((b) => b
|
||||
|
|
14
angel_serialize_generator/test/models/book.d.ts
vendored
14
angel_serialize_generator/test/models/book.d.ts
vendored
|
@ -2,39 +2,39 @@
|
|||
declare module 'angel_serialize_generator' {
|
||||
interface Book {
|
||||
id?: string;
|
||||
created_at?: any;
|
||||
updated_at?: any;
|
||||
author?: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
page_count?: number;
|
||||
not_models?: number[];
|
||||
camelCase?: string;
|
||||
created_at?: any;
|
||||
updated_at?: any;
|
||||
}
|
||||
interface Author {
|
||||
id?: string;
|
||||
created_at?: any;
|
||||
updated_at?: any;
|
||||
name: string;
|
||||
age: number;
|
||||
books?: Book[];
|
||||
newest_book?: Book;
|
||||
created_at?: any;
|
||||
updated_at?: any;
|
||||
}
|
||||
interface Library {
|
||||
id?: string;
|
||||
collection?: LibraryCollection;
|
||||
created_at?: any;
|
||||
updated_at?: any;
|
||||
collection?: LibraryCollection;
|
||||
}
|
||||
interface LibraryCollection {
|
||||
[key: string]: Book;
|
||||
}
|
||||
interface Bookmark {
|
||||
id?: string;
|
||||
created_at?: any;
|
||||
updated_at?: any;
|
||||
history?: number[];
|
||||
page: number;
|
||||
comment?: string;
|
||||
created_at?: any;
|
||||
updated_at?: any;
|
||||
}
|
||||
}
|
|
@ -12,19 +12,28 @@ part of angel_serialize.test.models.book;
|
|||
class Book extends _Book {
|
||||
Book(
|
||||
{this.id,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.author,
|
||||
this.title,
|
||||
this.description,
|
||||
this.pageCount,
|
||||
List<double> notModels,
|
||||
this.camelCaseString,
|
||||
this.createdAt,
|
||||
this.updatedAt})
|
||||
this.camelCaseString})
|
||||
: this.notModels = List.unmodifiable(notModels ?? []);
|
||||
|
||||
/// A unique identifier corresponding to this item.
|
||||
@override
|
||||
String id;
|
||||
|
||||
/// The time at which this item was created.
|
||||
@override
|
||||
DateTime createdAt;
|
||||
|
||||
/// The last time at which this item was updated.
|
||||
@override
|
||||
DateTime updatedAt;
|
||||
|
||||
@override
|
||||
String author;
|
||||
|
||||
|
@ -44,66 +53,60 @@ class Book extends _Book {
|
|||
@override
|
||||
String camelCaseString;
|
||||
|
||||
@override
|
||||
DateTime createdAt;
|
||||
|
||||
@override
|
||||
DateTime updatedAt;
|
||||
|
||||
Book copyWith(
|
||||
{String id,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt,
|
||||
String author,
|
||||
String title,
|
||||
String description,
|
||||
int pageCount,
|
||||
List<double> notModels,
|
||||
String camelCaseString,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt}) {
|
||||
String camelCaseString}) {
|
||||
return Book(
|
||||
id: id ?? this.id,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
author: author ?? this.author,
|
||||
title: title ?? this.title,
|
||||
description: description ?? this.description,
|
||||
pageCount: pageCount ?? this.pageCount,
|
||||
notModels: notModels ?? this.notModels,
|
||||
camelCaseString: camelCaseString ?? this.camelCaseString,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt);
|
||||
camelCaseString: camelCaseString ?? this.camelCaseString);
|
||||
}
|
||||
|
||||
bool operator ==(other) {
|
||||
return other is _Book &&
|
||||
other.id == id &&
|
||||
other.createdAt == createdAt &&
|
||||
other.updatedAt == updatedAt &&
|
||||
other.author == author &&
|
||||
other.title == title &&
|
||||
other.description == description &&
|
||||
other.pageCount == pageCount &&
|
||||
ListEquality<double>(DefaultEquality<double>())
|
||||
.equals(other.notModels, notModels) &&
|
||||
other.camelCaseString == camelCaseString &&
|
||||
other.createdAt == createdAt &&
|
||||
other.updatedAt == updatedAt;
|
||||
other.camelCaseString == camelCaseString;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hashObjects([
|
||||
id,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
author,
|
||||
title,
|
||||
description,
|
||||
pageCount,
|
||||
notModels,
|
||||
camelCaseString,
|
||||
createdAt,
|
||||
updatedAt
|
||||
camelCaseString
|
||||
]);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "Book(id=$id, author=$author, title=$title, description=$description, pageCount=$pageCount, notModels=$notModels, camelCaseString=$camelCaseString, createdAt=$createdAt, updatedAt=$updatedAt)";
|
||||
return "Book(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, author=$author, title=$title, description=$description, pageCount=$pageCount, notModels=$notModels, camelCaseString=$camelCaseString)";
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
|
@ -115,19 +118,28 @@ class Book extends _Book {
|
|||
class Author extends _Author {
|
||||
Author(
|
||||
{this.id,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
@required this.name,
|
||||
@required this.age,
|
||||
List<_Book> books,
|
||||
this.newestBook,
|
||||
this.secret,
|
||||
this.obscured,
|
||||
this.createdAt,
|
||||
this.updatedAt})
|
||||
this.obscured})
|
||||
: this.books = List.unmodifiable(books ?? []);
|
||||
|
||||
/// A unique identifier corresponding to this item.
|
||||
@override
|
||||
String id;
|
||||
|
||||
/// The time at which this item was created.
|
||||
@override
|
||||
DateTime createdAt;
|
||||
|
||||
/// The last time at which this item was updated.
|
||||
@override
|
||||
DateTime updatedAt;
|
||||
|
||||
@override
|
||||
final String name;
|
||||
|
||||
|
@ -147,66 +159,60 @@ class Author extends _Author {
|
|||
@override
|
||||
final String obscured;
|
||||
|
||||
@override
|
||||
DateTime createdAt;
|
||||
|
||||
@override
|
||||
DateTime updatedAt;
|
||||
|
||||
Author copyWith(
|
||||
{String id,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt,
|
||||
String name,
|
||||
int age,
|
||||
List<_Book> books,
|
||||
_Book newestBook,
|
||||
String secret,
|
||||
String obscured,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt}) {
|
||||
String obscured}) {
|
||||
return Author(
|
||||
id: id ?? this.id,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
name: name ?? this.name,
|
||||
age: age ?? this.age,
|
||||
books: books ?? this.books,
|
||||
newestBook: newestBook ?? this.newestBook,
|
||||
secret: secret ?? this.secret,
|
||||
obscured: obscured ?? this.obscured,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt);
|
||||
obscured: obscured ?? this.obscured);
|
||||
}
|
||||
|
||||
bool operator ==(other) {
|
||||
return other is _Author &&
|
||||
other.id == id &&
|
||||
other.createdAt == createdAt &&
|
||||
other.updatedAt == updatedAt &&
|
||||
other.name == name &&
|
||||
other.age == age &&
|
||||
ListEquality<_Book>(DefaultEquality<_Book>())
|
||||
.equals(other.books, books) &&
|
||||
other.newestBook == newestBook &&
|
||||
other.secret == secret &&
|
||||
other.obscured == obscured &&
|
||||
other.createdAt == createdAt &&
|
||||
other.updatedAt == updatedAt;
|
||||
other.obscured == obscured;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hashObjects([
|
||||
id,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
name,
|
||||
age,
|
||||
books,
|
||||
newestBook,
|
||||
secret,
|
||||
obscured,
|
||||
createdAt,
|
||||
updatedAt
|
||||
obscured
|
||||
]);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "Author(id=$id, name=$name, age=$age, books=$books, newestBook=$newestBook, secret=$secret, obscured=$obscured, createdAt=$createdAt, updatedAt=$updatedAt)";
|
||||
return "Author(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, name=$name, age=$age, books=$books, newestBook=$newestBook, secret=$secret, obscured=$obscured)";
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
|
@ -217,52 +223,55 @@ class Author extends _Author {
|
|||
@generatedSerializable
|
||||
class Library extends _Library {
|
||||
Library(
|
||||
{this.id, Map<String, _Book> collection, this.createdAt, this.updatedAt})
|
||||
{this.id, this.createdAt, this.updatedAt, Map<String, _Book> collection})
|
||||
: this.collection = Map.unmodifiable(collection ?? {});
|
||||
|
||||
/// A unique identifier corresponding to this item.
|
||||
@override
|
||||
String id;
|
||||
|
||||
/// The time at which this item was created.
|
||||
@override
|
||||
DateTime createdAt;
|
||||
|
||||
/// The last time at which this item was updated.
|
||||
@override
|
||||
DateTime updatedAt;
|
||||
|
||||
@override
|
||||
final Map<String, _Book> collection;
|
||||
|
||||
@override
|
||||
DateTime createdAt;
|
||||
|
||||
@override
|
||||
DateTime updatedAt;
|
||||
|
||||
Library copyWith(
|
||||
{String id,
|
||||
Map<String, _Book> collection,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt}) {
|
||||
DateTime updatedAt,
|
||||
Map<String, _Book> collection}) {
|
||||
return Library(
|
||||
id: id ?? this.id,
|
||||
collection: collection ?? this.collection,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt);
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
collection: collection ?? this.collection);
|
||||
}
|
||||
|
||||
bool operator ==(other) {
|
||||
return other is _Library &&
|
||||
other.id == id &&
|
||||
other.createdAt == createdAt &&
|
||||
other.updatedAt == updatedAt &&
|
||||
MapEquality<String, _Book>(
|
||||
keys: DefaultEquality<String>(),
|
||||
values: DefaultEquality<_Book>())
|
||||
.equals(other.collection, collection) &&
|
||||
other.createdAt == createdAt &&
|
||||
other.updatedAt == updatedAt;
|
||||
.equals(other.collection, collection);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hashObjects([id, collection, createdAt, updatedAt]);
|
||||
return hashObjects([id, createdAt, updatedAt, collection]);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "Library(id=$id, collection=$collection, createdAt=$createdAt, updatedAt=$updatedAt)";
|
||||
return "Library(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, collection=$collection)";
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
|
@ -274,17 +283,26 @@ class Library extends _Library {
|
|||
class Bookmark extends _Bookmark {
|
||||
Bookmark(_Book book,
|
||||
{this.id,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
List<int> history,
|
||||
@required this.page,
|
||||
this.comment,
|
||||
this.createdAt,
|
||||
this.updatedAt})
|
||||
this.comment})
|
||||
: this.history = List.unmodifiable(history ?? []),
|
||||
super(book);
|
||||
|
||||
/// A unique identifier corresponding to this item.
|
||||
@override
|
||||
String id;
|
||||
|
||||
/// The time at which this item was created.
|
||||
@override
|
||||
DateTime createdAt;
|
||||
|
||||
/// The last time at which this item was updated.
|
||||
@override
|
||||
DateTime updatedAt;
|
||||
|
||||
@override
|
||||
final List<int> history;
|
||||
|
||||
|
@ -294,47 +312,41 @@ class Bookmark extends _Bookmark {
|
|||
@override
|
||||
final String comment;
|
||||
|
||||
@override
|
||||
DateTime createdAt;
|
||||
|
||||
@override
|
||||
DateTime updatedAt;
|
||||
|
||||
Bookmark copyWith(_Book book,
|
||||
{String id,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt,
|
||||
List<int> history,
|
||||
int page,
|
||||
String comment,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt}) {
|
||||
String comment}) {
|
||||
return Bookmark(book,
|
||||
id: id ?? this.id,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
history: history ?? this.history,
|
||||
page: page ?? this.page,
|
||||
comment: comment ?? this.comment,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt);
|
||||
comment: comment ?? this.comment);
|
||||
}
|
||||
|
||||
bool operator ==(other) {
|
||||
return other is _Bookmark &&
|
||||
other.id == id &&
|
||||
other.createdAt == createdAt &&
|
||||
other.updatedAt == updatedAt &&
|
||||
ListEquality<int>(DefaultEquality<int>())
|
||||
.equals(other.history, history) &&
|
||||
other.page == page &&
|
||||
other.comment == comment &&
|
||||
other.createdAt == createdAt &&
|
||||
other.updatedAt == updatedAt;
|
||||
other.comment == comment;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hashObjects([id, history, page, comment, createdAt, updatedAt]);
|
||||
return hashObjects([id, createdAt, updatedAt, history, page, comment]);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "Bookmark(id=$id, history=$history, page=$page, comment=$comment, createdAt=$createdAt, updatedAt=$updatedAt)";
|
||||
return "Bookmark(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, history=$history, page=$page, comment=$comment)";
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
|
@ -372,14 +384,6 @@ class BookSerializer extends Codec<Book, Map> {
|
|||
static Book fromMap(Map map) {
|
||||
return Book(
|
||||
id: map['id'] as String,
|
||||
author: map['author'] as String,
|
||||
title: map['title'] as String,
|
||||
description: map['description'] as String,
|
||||
pageCount: map['page_count'] as int,
|
||||
notModels: map['not_models'] is Iterable
|
||||
? (map['not_models'] as Iterable).cast<double>().toList()
|
||||
: null,
|
||||
camelCaseString: map['camelCase'] as String,
|
||||
createdAt: map['created_at'] != null
|
||||
? (map['created_at'] is DateTime
|
||||
? (map['created_at'] as DateTime)
|
||||
|
@ -389,7 +393,15 @@ class BookSerializer extends Codec<Book, Map> {
|
|||
? (map['updated_at'] is DateTime
|
||||
? (map['updated_at'] as DateTime)
|
||||
: DateTime.parse(map['updated_at'].toString()))
|
||||
: null);
|
||||
: null,
|
||||
author: map['author'] as String,
|
||||
title: map['title'] as String,
|
||||
description: map['description'] as String,
|
||||
pageCount: map['page_count'] as int,
|
||||
notModels: map['not_models'] is Iterable
|
||||
? (map['not_models'] as Iterable).cast<double>().toList()
|
||||
: null,
|
||||
camelCaseString: map['camelCase'] as String);
|
||||
}
|
||||
|
||||
static Map<String, dynamic> toMap(_Book model) {
|
||||
|
@ -398,14 +410,14 @@ class BookSerializer extends Codec<Book, Map> {
|
|||
}
|
||||
return {
|
||||
'id': model.id,
|
||||
'created_at': model.createdAt?.toIso8601String(),
|
||||
'updated_at': model.updatedAt?.toIso8601String(),
|
||||
'author': model.author,
|
||||
'title': model.title,
|
||||
'description': model.description,
|
||||
'page_count': model.pageCount,
|
||||
'not_models': model.notModels,
|
||||
'camelCase': model.camelCaseString,
|
||||
'created_at': model.createdAt?.toIso8601String(),
|
||||
'updated_at': model.updatedAt?.toIso8601String()
|
||||
'camelCase': model.camelCaseString
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -413,18 +425,22 @@ class BookSerializer extends Codec<Book, Map> {
|
|||
abstract class BookFields {
|
||||
static const List<String> allFields = <String>[
|
||||
id,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
author,
|
||||
title,
|
||||
description,
|
||||
pageCount,
|
||||
notModels,
|
||||
camelCaseString,
|
||||
createdAt,
|
||||
updatedAt
|
||||
camelCaseString
|
||||
];
|
||||
|
||||
static const String id = 'id';
|
||||
|
||||
static const String createdAt = 'created_at';
|
||||
|
||||
static const String updatedAt = 'updated_at';
|
||||
|
||||
static const String author = 'author';
|
||||
|
||||
static const String title = 'title';
|
||||
|
@ -436,10 +452,6 @@ abstract class BookFields {
|
|||
static const String notModels = 'not_models';
|
||||
|
||||
static const String camelCaseString = 'camelCase';
|
||||
|
||||
static const String createdAt = 'created_at';
|
||||
|
||||
static const String updatedAt = 'updated_at';
|
||||
}
|
||||
|
||||
const AuthorSerializer authorSerializer = AuthorSerializer();
|
||||
|
@ -476,16 +488,6 @@ class AuthorSerializer extends Codec<Author, Map> {
|
|||
|
||||
return Author(
|
||||
id: map['id'] as String,
|
||||
name: map['name'] as String,
|
||||
age: map['age'] as int,
|
||||
books: map['books'] is Iterable
|
||||
? List.unmodifiable(((map['books'] as Iterable).whereType<Map>())
|
||||
.map(BookSerializer.fromMap))
|
||||
: null,
|
||||
newestBook: map['newest_book'] != null
|
||||
? BookSerializer.fromMap(map['newest_book'] as Map)
|
||||
: null,
|
||||
obscured: map['obscured'] as String,
|
||||
createdAt: map['created_at'] != null
|
||||
? (map['created_at'] is DateTime
|
||||
? (map['created_at'] as DateTime)
|
||||
|
@ -495,7 +497,17 @@ class AuthorSerializer extends Codec<Author, Map> {
|
|||
? (map['updated_at'] is DateTime
|
||||
? (map['updated_at'] as DateTime)
|
||||
: DateTime.parse(map['updated_at'].toString()))
|
||||
: null);
|
||||
: null,
|
||||
name: map['name'] as String,
|
||||
age: map['age'] as int,
|
||||
books: map['books'] is Iterable
|
||||
? List.unmodifiable(((map['books'] as Iterable).whereType<Map>())
|
||||
.map(BookSerializer.fromMap))
|
||||
: null,
|
||||
newestBook: map['newest_book'] != null
|
||||
? BookSerializer.fromMap(map['newest_book'] as Map)
|
||||
: null,
|
||||
obscured: map['obscured'] as String);
|
||||
}
|
||||
|
||||
static Map<String, dynamic> toMap(_Author model) {
|
||||
|
@ -512,12 +524,12 @@ class AuthorSerializer extends Codec<Author, Map> {
|
|||
|
||||
return {
|
||||
'id': model.id,
|
||||
'created_at': model.createdAt?.toIso8601String(),
|
||||
'updated_at': model.updatedAt?.toIso8601String(),
|
||||
'name': model.name,
|
||||
'age': model.age,
|
||||
'books': model.books?.map((m) => BookSerializer.toMap(m))?.toList(),
|
||||
'newest_book': BookSerializer.toMap(model.newestBook),
|
||||
'created_at': model.createdAt?.toIso8601String(),
|
||||
'updated_at': model.updatedAt?.toIso8601String()
|
||||
'newest_book': BookSerializer.toMap(model.newestBook)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -525,18 +537,22 @@ class AuthorSerializer extends Codec<Author, Map> {
|
|||
abstract class AuthorFields {
|
||||
static const List<String> allFields = <String>[
|
||||
id,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
name,
|
||||
age,
|
||||
books,
|
||||
newestBook,
|
||||
secret,
|
||||
obscured,
|
||||
createdAt,
|
||||
updatedAt
|
||||
obscured
|
||||
];
|
||||
|
||||
static const String id = 'id';
|
||||
|
||||
static const String createdAt = 'created_at';
|
||||
|
||||
static const String updatedAt = 'updated_at';
|
||||
|
||||
static const String name = 'name';
|
||||
|
||||
static const String age = 'age';
|
||||
|
@ -548,10 +564,6 @@ abstract class AuthorFields {
|
|||
static const String secret = 'secret';
|
||||
|
||||
static const String obscured = 'obscured';
|
||||
|
||||
static const String createdAt = 'created_at';
|
||||
|
||||
static const String updatedAt = 'updated_at';
|
||||
}
|
||||
|
||||
const LibrarySerializer librarySerializer = LibrarySerializer();
|
||||
|
@ -580,14 +592,6 @@ class LibrarySerializer extends Codec<Library, Map> {
|
|||
static Library fromMap(Map map) {
|
||||
return Library(
|
||||
id: map['id'] as String,
|
||||
collection: map['collection'] is Map
|
||||
? Map.unmodifiable(
|
||||
(map['collection'] as Map).keys.fold({}, (out, key) {
|
||||
return out
|
||||
..[key] = BookSerializer.fromMap(
|
||||
((map['collection'] as Map)[key]) as Map);
|
||||
}))
|
||||
: null,
|
||||
createdAt: map['created_at'] != null
|
||||
? (map['created_at'] is DateTime
|
||||
? (map['created_at'] as DateTime)
|
||||
|
@ -597,6 +601,14 @@ class LibrarySerializer extends Codec<Library, Map> {
|
|||
? (map['updated_at'] is DateTime
|
||||
? (map['updated_at'] as DateTime)
|
||||
: DateTime.parse(map['updated_at'].toString()))
|
||||
: null,
|
||||
collection: map['collection'] is Map
|
||||
? Map.unmodifiable(
|
||||
(map['collection'] as Map).keys.fold({}, (out, key) {
|
||||
return out
|
||||
..[key] = BookSerializer.fromMap(
|
||||
((map['collection'] as Map)[key]) as Map);
|
||||
}))
|
||||
: null);
|
||||
}
|
||||
|
||||
|
@ -606,11 +618,11 @@ class LibrarySerializer extends Codec<Library, Map> {
|
|||
}
|
||||
return {
|
||||
'id': model.id,
|
||||
'created_at': model.createdAt?.toIso8601String(),
|
||||
'updated_at': model.updatedAt?.toIso8601String(),
|
||||
'collection': model.collection.keys?.fold({}, (map, key) {
|
||||
return map..[key] = BookSerializer.toMap(model.collection[key]);
|
||||
}),
|
||||
'created_at': model.createdAt?.toIso8601String(),
|
||||
'updated_at': model.updatedAt?.toIso8601String()
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -618,18 +630,18 @@ class LibrarySerializer extends Codec<Library, Map> {
|
|||
abstract class LibraryFields {
|
||||
static const List<String> allFields = <String>[
|
||||
id,
|
||||
collection,
|
||||
createdAt,
|
||||
updatedAt
|
||||
updatedAt,
|
||||
collection
|
||||
];
|
||||
|
||||
static const String id = 'id';
|
||||
|
||||
static const String collection = 'collection';
|
||||
|
||||
static const String createdAt = 'created_at';
|
||||
|
||||
static const String updatedAt = 'updated_at';
|
||||
|
||||
static const String collection = 'collection';
|
||||
}
|
||||
|
||||
abstract class BookmarkSerializer {
|
||||
|
@ -640,11 +652,6 @@ abstract class BookmarkSerializer {
|
|||
|
||||
return Bookmark(book,
|
||||
id: map['id'] as String,
|
||||
history: map['history'] is Iterable
|
||||
? (map['history'] as Iterable).cast<int>().toList()
|
||||
: null,
|
||||
page: map['page'] as int,
|
||||
comment: map['comment'] as String,
|
||||
createdAt: map['created_at'] != null
|
||||
? (map['created_at'] is DateTime
|
||||
? (map['created_at'] as DateTime)
|
||||
|
@ -654,7 +661,12 @@ abstract class BookmarkSerializer {
|
|||
? (map['updated_at'] is DateTime
|
||||
? (map['updated_at'] as DateTime)
|
||||
: DateTime.parse(map['updated_at'].toString()))
|
||||
: null);
|
||||
: null,
|
||||
history: map['history'] is Iterable
|
||||
? (map['history'] as Iterable).cast<int>().toList()
|
||||
: null,
|
||||
page: map['page'] as int,
|
||||
comment: map['comment'] as String);
|
||||
}
|
||||
|
||||
static Map<String, dynamic> toMap(_Bookmark model) {
|
||||
|
@ -667,11 +679,11 @@ abstract class BookmarkSerializer {
|
|||
|
||||
return {
|
||||
'id': model.id,
|
||||
'created_at': model.createdAt?.toIso8601String(),
|
||||
'updated_at': model.updatedAt?.toIso8601String(),
|
||||
'history': model.history,
|
||||
'page': model.page,
|
||||
'comment': model.comment,
|
||||
'created_at': model.createdAt?.toIso8601String(),
|
||||
'updated_at': model.updatedAt?.toIso8601String()
|
||||
'comment': model.comment
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -679,22 +691,22 @@ abstract class BookmarkSerializer {
|
|||
abstract class BookmarkFields {
|
||||
static const List<String> allFields = <String>[
|
||||
id,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
history,
|
||||
page,
|
||||
comment,
|
||||
createdAt,
|
||||
updatedAt
|
||||
comment
|
||||
];
|
||||
|
||||
static const String id = 'id';
|
||||
|
||||
static const String createdAt = 'created_at';
|
||||
|
||||
static const String updatedAt = 'updated_at';
|
||||
|
||||
static const String history = 'history';
|
||||
|
||||
static const String page = 'page';
|
||||
|
||||
static const String comment = 'comment';
|
||||
|
||||
static const String createdAt = 'created_at';
|
||||
|
||||
static const String updatedAt = 'updated_at';
|
||||
}
|
||||
|
|
22
angel_serialize_generator/test/models/subclass.dart
Normal file
22
angel_serialize_generator/test/models/subclass.dart
Normal file
|
@ -0,0 +1,22 @@
|
|||
import 'package:angel_serialize/angel_serialize.dart';
|
||||
part 'subclass.g.dart';
|
||||
|
||||
@serializable
|
||||
class _Animal {
|
||||
@notNull
|
||||
String genus;
|
||||
@notNull
|
||||
String species;
|
||||
}
|
||||
|
||||
@serializable
|
||||
class _Bird extends _Animal {
|
||||
@DefaultsTo(false)
|
||||
bool isSparrow;
|
||||
}
|
||||
|
||||
var saxaulSparrow = Bird(
|
||||
genus: 'Passer',
|
||||
species: 'ammodendri',
|
||||
isSparrow: true,
|
||||
);
|
214
angel_serialize_generator/test/models/subclass.g.dart
Normal file
214
angel_serialize_generator/test/models/subclass.g.dart
Normal file
|
@ -0,0 +1,214 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'subclass.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
||||
@generatedSerializable
|
||||
class Animal extends _Animal {
|
||||
Animal({@required this.genus, @required this.species});
|
||||
|
||||
@override
|
||||
String genus;
|
||||
|
||||
@override
|
||||
String species;
|
||||
|
||||
Animal copyWith({String genus, String species}) {
|
||||
return Animal(genus: genus ?? this.genus, species: species ?? this.species);
|
||||
}
|
||||
|
||||
bool operator ==(other) {
|
||||
return other is _Animal && other.genus == genus && other.species == species;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hashObjects([genus, species]);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "Animal(genus=$genus, species=$species)";
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return AnimalSerializer.toMap(this);
|
||||
}
|
||||
}
|
||||
|
||||
@generatedSerializable
|
||||
class Bird extends _Bird {
|
||||
Bird({@required this.genus, @required this.species, this.isSparrow = false});
|
||||
|
||||
@override
|
||||
String genus;
|
||||
|
||||
@override
|
||||
String species;
|
||||
|
||||
@override
|
||||
bool isSparrow;
|
||||
|
||||
Bird copyWith({String genus, String species, bool isSparrow}) {
|
||||
return Bird(
|
||||
genus: genus ?? this.genus,
|
||||
species: species ?? this.species,
|
||||
isSparrow: isSparrow ?? this.isSparrow);
|
||||
}
|
||||
|
||||
bool operator ==(other) {
|
||||
return other is _Bird &&
|
||||
other.genus == genus &&
|
||||
other.species == species &&
|
||||
other.isSparrow == isSparrow;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hashObjects([genus, species, isSparrow]);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "Bird(genus=$genus, species=$species, isSparrow=$isSparrow)";
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return BirdSerializer.toMap(this);
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// SerializerGenerator
|
||||
// **************************************************************************
|
||||
|
||||
const AnimalSerializer animalSerializer = AnimalSerializer();
|
||||
|
||||
class AnimalEncoder extends Converter<Animal, Map> {
|
||||
const AnimalEncoder();
|
||||
|
||||
@override
|
||||
Map convert(Animal model) => AnimalSerializer.toMap(model);
|
||||
}
|
||||
|
||||
class AnimalDecoder extends Converter<Map, Animal> {
|
||||
const AnimalDecoder();
|
||||
|
||||
@override
|
||||
Animal convert(Map map) => AnimalSerializer.fromMap(map);
|
||||
}
|
||||
|
||||
class AnimalSerializer extends Codec<Animal, Map> {
|
||||
const AnimalSerializer();
|
||||
|
||||
@override
|
||||
get encoder => const AnimalEncoder();
|
||||
@override
|
||||
get decoder => const AnimalDecoder();
|
||||
static Animal fromMap(Map map) {
|
||||
if (map['genus'] == null) {
|
||||
throw FormatException("Missing required field 'genus' on Animal.");
|
||||
}
|
||||
|
||||
if (map['species'] == null) {
|
||||
throw FormatException("Missing required field 'species' on Animal.");
|
||||
}
|
||||
|
||||
return Animal(
|
||||
genus: map['genus'] as String, species: map['species'] as String);
|
||||
}
|
||||
|
||||
static Map<String, dynamic> toMap(_Animal model) {
|
||||
if (model == null) {
|
||||
return null;
|
||||
}
|
||||
if (model.genus == null) {
|
||||
throw FormatException("Missing required field 'genus' on Animal.");
|
||||
}
|
||||
|
||||
if (model.species == null) {
|
||||
throw FormatException("Missing required field 'species' on Animal.");
|
||||
}
|
||||
|
||||
return {'genus': model.genus, 'species': model.species};
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AnimalFields {
|
||||
static const List<String> allFields = <String>[genus, species];
|
||||
|
||||
static const String genus = 'genus';
|
||||
|
||||
static const String species = 'species';
|
||||
}
|
||||
|
||||
const BirdSerializer birdSerializer = BirdSerializer();
|
||||
|
||||
class BirdEncoder extends Converter<Bird, Map> {
|
||||
const BirdEncoder();
|
||||
|
||||
@override
|
||||
Map convert(Bird model) => BirdSerializer.toMap(model);
|
||||
}
|
||||
|
||||
class BirdDecoder extends Converter<Map, Bird> {
|
||||
const BirdDecoder();
|
||||
|
||||
@override
|
||||
Bird convert(Map map) => BirdSerializer.fromMap(map);
|
||||
}
|
||||
|
||||
class BirdSerializer extends Codec<Bird, Map> {
|
||||
const BirdSerializer();
|
||||
|
||||
@override
|
||||
get encoder => const BirdEncoder();
|
||||
@override
|
||||
get decoder => const BirdDecoder();
|
||||
static Bird fromMap(Map map) {
|
||||
if (map['genus'] == null) {
|
||||
throw FormatException("Missing required field 'genus' on Bird.");
|
||||
}
|
||||
|
||||
if (map['species'] == null) {
|
||||
throw FormatException("Missing required field 'species' on Bird.");
|
||||
}
|
||||
|
||||
return Bird(
|
||||
genus: map['genus'] as String,
|
||||
species: map['species'] as String,
|
||||
isSparrow: map['is_sparrow'] as bool ?? false);
|
||||
}
|
||||
|
||||
static Map<String, dynamic> toMap(_Bird model) {
|
||||
if (model == null) {
|
||||
return null;
|
||||
}
|
||||
if (model.genus == null) {
|
||||
throw FormatException("Missing required field 'genus' on Bird.");
|
||||
}
|
||||
|
||||
if (model.species == null) {
|
||||
throw FormatException("Missing required field 'species' on Bird.");
|
||||
}
|
||||
|
||||
return {
|
||||
'genus': model.genus,
|
||||
'species': model.species,
|
||||
'is_sparrow': model.isSparrow
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
abstract class BirdFields {
|
||||
static const List<String> allFields = <String>[genus, species, isSparrow];
|
||||
|
||||
static const String genus = 'genus';
|
||||
|
||||
static const String species = 'species';
|
||||
|
||||
static const String isSparrow = 'is_sparrow';
|
||||
}
|
Loading…
Reference in a new issue