diff --git a/angel_serialize/lib/angel_serialize.dart b/angel_serialize/lib/angel_serialize.dart index bb4f6965..a9a31415 100644 --- a/angel_serialize/lib/angel_serialize.dart +++ b/angel_serialize/lib/angel_serialize.dart @@ -9,8 +9,13 @@ class Exclude extends SerializableField { : super(canDeserialize: canDeserialize, canSerialize: canSerialize); } +/// No longer necessary, as this is the default. +@deprecated const SerializableField nullable = const SerializableField(isNullable: true); +/// Marks a field as not accepting `null` values. +const SerializableField notNull = const SerializableField(isNullable: false); + const Exclude exclude = const Exclude(); /// Shorthand for [SerializableField]. @@ -66,7 +71,7 @@ class SerializableField { this.serializer, this.deserializer, this.errorMessage, - this.isNullable: false, + this.isNullable: true, this.exclude: false, this.canDeserialize: false, this.canSerialize: false, diff --git a/angel_serialize_generator/build.yaml b/angel_serialize_generator/build.yaml index cbe43107..3405b999 100644 --- a/angel_serialize_generator/build.yaml +++ b/angel_serialize_generator/build.yaml @@ -1,6 +1,5 @@ builders: angel_serialize: - # target: "angel_serialize_generator" import: "package:angel_serialize_generator/angel_serialize_generator.dart" builder_factories: - jsonModelBuilder @@ -9,12 +8,11 @@ builders: build_to: cache build_extensions: .dart: - - "angel_serialize.g.part" - - "angel_serialize_serializer.g.part" + - ".angel_serialize.g.part" + - ".angel_serialize_serializer.g.part" applies_builders: ["source_gen|combining_builder", "source_gen|part_cleanup"] runs_before: ["angel_orm_generator|angel_orm"] typescript: - # target: "angel_serialize_generator" import: "package:angel_serialize_generator/angel_serialize_generator.dart" builder_factories: - typescriptDefinitionBuilder @@ -23,23 +21,17 @@ builders: build_extensions: .dart: - ".d.ts" -targets: - _book: - sources: - - "test/models/book.dart" - - "test/models/has_map.dart" - - "test/models/goat.dart" - - "test/models/game_pad_button.dart" - - "test/models/with_enum.dart" - _typescript_definition: - sources: - - "test/*.dart" - $default: - dependencies: - - ":_book" - sources: - - "bin/**" - - "lib/**" - - "web/**" - - "test/models/author.dart" - - "test/models/game_pad.dart" +# targets: +# _book: +# sources: +# - "test/models/book.dart" +# - "test/models/has_map.dart" +# - "test/models/goat.dart" +# - "test/models/game_pad_button.dart" +# - "test/models/with_enum.dart" +# $default: +# dependencies: +# - "angel_serialize_generator:_book" +# sources: +# - "test/models/author.dart" +# - "test/models/game_pad.dart" diff --git a/angel_serialize_generator/example/main.dart b/angel_serialize_generator/example/main.dart index c1131cdc..52c46706 100644 --- a/angel_serialize_generator/example/main.dart +++ b/angel_serialize_generator/example/main.dart @@ -1,5 +1,6 @@ // ignore_for_file: unused_element import 'package:angel_serialize/angel_serialize.dart'; +part 'main.g.dart'; @serializable class _Todo { diff --git a/angel_serialize_generator/example/main.g.dart b/angel_serialize_generator/example/main.g.dart new file mode 100644 index 00000000..d30ff1cb --- /dev/null +++ b/angel_serialize_generator/example/main.g.dart @@ -0,0 +1,62 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'main.dart'; + +// ************************************************************************** +// JsonModelGenerator +// ************************************************************************** + +@generatedSerializable +class Todo extends _Todo { + Todo({this.text, this.completed}); + + @override + final String text; + + @override + final bool completed; + + Todo copyWith({String text, bool completed}) { + return new Todo( + text: text ?? this.text, completed: completed ?? this.completed); + } + + bool operator ==(other) { + return other is _Todo && other.text == text && other.completed == completed; + } + + @override + int get hashCode { + return hashObjects([text, completed]); + } + + Map toJson() { + return TodoSerializer.toMap(this); + } +} + +// ************************************************************************** +// SerializerGenerator +// ************************************************************************** + +abstract class TodoSerializer { + static Todo fromMap(Map map) { + return new Todo( + text: map['text'] as String, completed: map['completed'] as bool); + } + + static Map toMap(_Todo model) { + if (model == null) { + return null; + } + return {'text': model.text, 'completed': model.completed}; + } +} + +abstract class TodoFields { + static const List allFields = [text, completed]; + + static const String text = 'text'; + + static const String completed = 'completed'; +} diff --git a/angel_serialize_generator/lib/angel_serialize_generator.dart b/angel_serialize_generator/lib/angel_serialize_generator.dart index 7441a8a6..4b1cc755 100644 --- a/angel_serialize_generator/lib/angel_serialize_generator.dart +++ b/angel_serialize_generator/lib/angel_serialize_generator.dart @@ -11,6 +11,7 @@ import 'package:angel_serialize/angel_serialize.dart'; import 'package:build/build.dart'; import 'package:code_buffer/code_buffer.dart'; import 'package:code_builder/code_builder.dart'; +import 'package:dart_style/dart_style.dart'; import 'package:path/path.dart' as p; import 'package:recase/recase.dart'; import 'package:source_gen/source_gen.dart' hide LibraryBuilder; diff --git a/angel_serialize_generator/pubspec.yaml b/angel_serialize_generator/pubspec.yaml index 1775fd74..394c3017 100644 --- a/angel_serialize_generator/pubspec.yaml +++ b/angel_serialize_generator/pubspec.yaml @@ -22,6 +22,6 @@ dev_dependencies: build_runner: ^1.0.0 collection: ^1.0.0 test: ^1.0.0 -# dependency_overrides: -# angel_serialize: -# path: ../angel_serialize \ No newline at end of file +dependency_overrides: + angel_serialize: + path: ../angel_serialize \ No newline at end of file diff --git a/angel_serialize_generator/test/book_test.dart b/angel_serialize_generator/test/book_test.dart index 044312b9..b3b169e8 100644 --- a/angel_serialize_generator/test/book_test.dart +++ b/angel_serialize_generator/test/book_test.dart @@ -1,5 +1,4 @@ import 'package:test/test.dart'; -import 'models/author.dart'; import 'models/book.dart'; const String deathlyHallowsIsbn = '0-545-01022-5'; diff --git a/angel_serialize_generator/test/enum_test.dart b/angel_serialize_generator/test/enum_test.dart index 403804c1..39b14d5d 100644 --- a/angel_serialize_generator/test/enum_test.dart +++ b/angel_serialize_generator/test/enum_test.dart @@ -17,10 +17,10 @@ void main() { expect(w[WithEnumFields.type], null); }); - test('enum deserializes to null from null', () { + test('enum deserializes to default value from null', () { var map = {WithEnumFields.type: null}; var w = WithEnumSerializer.fromMap(map); - expect(w.type, isNull); + expect(w.type, WithEnumType.b); }); test('enum deserializes from int', () { diff --git a/angel_serialize_generator/test/models/author.d.ts b/angel_serialize_generator/test/models/author.d.ts deleted file mode 100644 index 48453ab9..00000000 --- a/angel_serialize_generator/test/models/author.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND -declare module 'angel_serialize_generator' { - interface Author { - id?: string; - name: string; - age: number; - books?: any[]; - newest_book?: any; - created_at?: any; - updated_at?: any; - } - interface Library { - id?: string; - collection: LibraryCollection; - created_at?: any; - updated_at?: any; - } - interface LibraryCollection { - [key: string]: any; - } - interface Bookmark { - id?: string; - history: number[]; - page: number; - comment: string; - created_at?: any; - updated_at?: any; - } -} \ No newline at end of file diff --git a/angel_serialize_generator/test/models/author.dart b/angel_serialize_generator/test/models/author.dart deleted file mode 100644 index 3d80f378..00000000 --- a/angel_serialize_generator/test/models/author.dart +++ /dev/null @@ -1,52 +0,0 @@ -library angel_serialize.test.models.author; - -import 'package:angel_model/angel_model.dart'; -import 'package:angel_serialize/angel_serialize.dart'; -import 'package:collection/collection.dart'; -import 'package:meta/meta.dart'; -import 'book.dart'; -part 'author.g.dart'; - -@Serializable(serializers: Serializers.all) -abstract class _Author extends Model { - @SerializableField(isNullable: false) - String get name; - - String get customMethod => 'hey!'; - - @SerializableField( - isNullable: false, errorMessage: 'Custom message for missing `age`') - int get age; - - @nullable - List get books; - - @nullable - Book get newestBook; - - @SerializableField(exclude: true, isNullable: true) - String get secret; - - @SerializableField(exclude: true, canDeserialize: true, isNullable: true) - String get obscured; -} - -@Serializable(serializers: Serializers.all) -abstract class _Library extends Model { - Map get collection; -} - -@Serializable(serializers: Serializers.all) -abstract class _Bookmark extends Model { - @SerializableField(exclude: true) - final Book book; - - List get history; - - @SerializableField(isNullable: false) - int get page; - - String get comment; - - _Bookmark(this.book); -} diff --git a/angel_serialize_generator/test/models/author.g.dart b/angel_serialize_generator/test/models/author.g.dart deleted file mode 100644 index d70e5d9c..00000000 --- a/angel_serialize_generator/test/models/author.g.dart +++ /dev/null @@ -1,462 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of angel_serialize.test.models.author; - -// ************************************************************************** -// JsonModelGenerator -// ************************************************************************** - -@generatedSerializable -class Author extends _Author { - Author( - {this.id, - @required this.name, - @required this.age, - List books, - this.newestBook, - this.secret, - this.obscured, - this.createdAt, - this.updatedAt}) - : this.books = new List.unmodifiable(books ?? []); - - @override - final String id; - - @override - final String name; - - @override - final int age; - - @override - final List books; - - @override - final dynamic newestBook; - - @override - final String secret; - - @override - final String obscured; - - @override - final DateTime createdAt; - - @override - final DateTime updatedAt; - - Author copyWith( - {String id, - String name, - int age, - List books, - dynamic newestBook, - String secret, - String obscured, - DateTime createdAt, - DateTime updatedAt}) { - return new Author( - id: id ?? this.id, - 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); - } - - bool operator ==(other) { - return other is _Author && - other.id == id && - other.name == name && - other.age == age && - const ListEquality(const DefaultEquality()) - .equals(other.books, books) && - other.newestBook == newestBook && - other.secret == secret && - other.obscured == obscured && - other.createdAt == createdAt && - other.updatedAt == updatedAt; - } - - @override - int get hashCode { - return hashObjects([ - id, - name, - age, - books, - newestBook, - secret, - obscured, - createdAt, - updatedAt - ]); - } - - Map toJson() { - return AuthorSerializer.toMap(this); - } -} - -@generatedSerializable -class Library extends _Library { - Library( - {this.id, - @required Map collection, - this.createdAt, - this.updatedAt}) - : this.collection = new Map.unmodifiable(collection ?? {}); - - @override - final String id; - - @override - final Map collection; - - @override - final DateTime createdAt; - - @override - final DateTime updatedAt; - - Library copyWith( - {String id, - Map collection, - DateTime createdAt, - DateTime updatedAt}) { - return new Library( - id: id ?? this.id, - collection: collection ?? this.collection, - createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt); - } - - bool operator ==(other) { - return other is _Library && - other.id == id && - const MapEquality( - keys: const DefaultEquality(), - values: const DefaultEquality()) - .equals(other.collection, collection) && - other.createdAt == createdAt && - other.updatedAt == updatedAt; - } - - @override - int get hashCode { - return hashObjects([id, collection, createdAt, updatedAt]); - } - - Map toJson() { - return LibrarySerializer.toMap(this); - } -} - -@generatedSerializable -class Bookmark extends _Bookmark { - Bookmark(dynamic book, - {this.id, - @required List history, - @required this.page, - @required this.comment, - this.createdAt, - this.updatedAt}) - : this.history = new List.unmodifiable(history ?? []), - super(book); - - @override - final String id; - - @override - final List history; - - @override - final int page; - - @override - final String comment; - - @override - final DateTime createdAt; - - @override - final DateTime updatedAt; - - Bookmark copyWith(dynamic book, - {String id, - List history, - int page, - String comment, - DateTime createdAt, - DateTime updatedAt}) { - return new Bookmark(book, - id: id ?? this.id, - history: history ?? this.history, - page: page ?? this.page, - comment: comment ?? this.comment, - createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt); - } - - bool operator ==(other) { - return other is _Bookmark && - other.id == id && - const ListEquality(const DefaultEquality()) - .equals(other.history, history) && - other.page == page && - other.comment == comment && - other.createdAt == createdAt && - other.updatedAt == updatedAt; - } - - @override - int get hashCode { - return hashObjects([id, history, page, comment, createdAt, updatedAt]); - } - - Map toJson() { - return BookmarkSerializer.toMap(this); - } -} - -// ************************************************************************** -// SerializerGenerator -// ************************************************************************** - -abstract class AuthorSerializer { - static Author fromMap(Map map) { - if (map['name'] == null) { - throw new FormatException("Missing required field 'name' on Author."); - } - - if (map['age'] == null) { - throw new FormatException("Custom message for missing `age`"); - } - - return new Author( - id: map['id'] as String, - name: map['name'] as String, - age: map['age'] as int, - books: map['books'] is Iterable - ? (map['books'] as Iterable).cast().toList() - : null, - newestBook: map['newest_book'] as dynamic, - obscured: map['obscured'] as String, - createdAt: map['created_at'] != null - ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime) - : DateTime.parse(map['created_at'].toString())) - : null, - updatedAt: map['updated_at'] != null - ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime) - : DateTime.parse(map['updated_at'].toString())) - : null); - } - - static Map toMap(_Author model) { - if (model == null) { - return null; - } - if (model.name == null) { - throw new FormatException("Missing required field 'name' on Author."); - } - - if (model.age == null) { - throw new FormatException("Custom message for missing `age`"); - } - - return { - 'id': model.id, - 'name': model.name, - 'age': model.age, - 'books': model.books, - 'newest_book': model.newestBook, - 'created_at': model.createdAt?.toIso8601String(), - 'updated_at': model.updatedAt?.toIso8601String() - }; - } -} - -abstract class AuthorFields { - static const List allFields = [ - id, - name, - age, - books, - newestBook, - secret, - obscured, - createdAt, - updatedAt - ]; - - static const String id = 'id'; - - static const String name = 'name'; - - static const String age = 'age'; - - static const String books = 'books'; - - static const String newestBook = 'newest_book'; - - static const String secret = 'secret'; - - static const String obscured = 'obscured'; - - static const String createdAt = 'created_at'; - - static const String updatedAt = 'updated_at'; -} - -abstract class LibrarySerializer { - static Library fromMap(Map map) { - if (map['collection'] == null) { - throw new FormatException( - "Missing required field 'collection' on Library."); - } - - return new Library( - id: map['id'] as String, - collection: map['collection'] is Map - ? (map['collection'] as Map).cast() - : null, - createdAt: map['created_at'] != null - ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime) - : DateTime.parse(map['created_at'].toString())) - : null, - updatedAt: map['updated_at'] != null - ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime) - : DateTime.parse(map['updated_at'].toString())) - : null); - } - - static Map toMap(_Library model) { - if (model == null) { - return null; - } - if (model.collection == null) { - throw new FormatException( - "Missing required field 'collection' on Library."); - } - - return { - 'id': model.id, - 'collection': model.collection, - 'created_at': model.createdAt?.toIso8601String(), - 'updated_at': model.updatedAt?.toIso8601String() - }; - } -} - -abstract class LibraryFields { - static const List allFields = [ - id, - collection, - createdAt, - updatedAt - ]; - - static const String id = 'id'; - - static const String collection = 'collection'; - - static const String createdAt = 'created_at'; - - static const String updatedAt = 'updated_at'; -} - -abstract class BookmarkSerializer { - static Bookmark fromMap(Map map, dynamic book) { - if (map['history'] == null) { - throw new FormatException( - "Missing required field 'history' on Bookmark."); - } - - if (map['page'] == null) { - throw new FormatException("Missing required field 'page' on Bookmark."); - } - - if (map['comment'] == null) { - throw new FormatException( - "Missing required field 'comment' on Bookmark."); - } - - return new Bookmark(book, - id: map['id'] as String, - history: map['history'] is Iterable - ? (map['history'] as Iterable).cast().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) - : DateTime.parse(map['created_at'].toString())) - : null, - updatedAt: map['updated_at'] != null - ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime) - : DateTime.parse(map['updated_at'].toString())) - : null); - } - - static Map toMap(_Bookmark model) { - if (model == null) { - return null; - } - if (model.history == null) { - throw new FormatException( - "Missing required field 'history' on Bookmark."); - } - - if (model.page == null) { - throw new FormatException("Missing required field 'page' on Bookmark."); - } - - if (model.comment == null) { - throw new FormatException( - "Missing required field 'comment' on Bookmark."); - } - - return { - 'id': model.id, - 'history': model.history, - 'page': model.page, - 'comment': model.comment, - 'created_at': model.createdAt?.toIso8601String(), - 'updated_at': model.updatedAt?.toIso8601String() - }; - } -} - -abstract class BookmarkFields { - static const List allFields = [ - id, - history, - page, - comment, - createdAt, - updatedAt - ]; - - static const String id = 'id'; - - 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'; -} diff --git a/angel_serialize_generator/test/models/book.d.ts b/angel_serialize_generator/test/models/book.d.ts index f02447f0..64ff06e2 100644 --- a/angel_serialize_generator/test/models/book.d.ts +++ b/angel_serialize_generator/test/models/book.d.ts @@ -2,13 +2,39 @@ declare module 'angel_serialize_generator' { interface Book { id?: string; - author: string; - title: string; - description: string; - page_count: number; - not_models: number[]; + author?: string; + title?: string; + description?: string; + page_count?: number; + not_models?: number[]; camelCase?: string; created_at?: any; updated_at?: any; } + interface Author { + id?: string; + 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; + } + interface LibraryCollection { + [key: string]: Book; + } + interface Bookmark { + id?: string; + history?: number[]; + page: number; + comment?: string; + created_at?: any; + updated_at?: any; + } } \ No newline at end of file diff --git a/angel_serialize_generator/test/models/book.dart b/angel_serialize_generator/test/models/book.dart index 55735878..fc09731b 100644 --- a/angel_serialize_generator/test/models/book.dart +++ b/angel_serialize_generator/test/models/book.dart @@ -3,6 +3,7 @@ library angel_serialize.test.models.book; import 'package:angel_model/angel_model.dart'; import 'package:angel_serialize/angel_serialize.dart'; import 'package:collection/collection.dart'; +import 'package:meta/meta.dart'; part 'book.g.dart'; @Serializable( @@ -20,3 +21,45 @@ abstract class _Book extends Model { @SerializableField(alias: 'camelCase', isNullable: true) String camelCaseString; } + +@Serializable(serializers: Serializers.all) +abstract class _Author extends Model { + @SerializableField(isNullable: false) + String get name; + + String get customMethod => 'hey!'; + + @SerializableField( + isNullable: false, errorMessage: 'Custom message for missing `age`') + int get age; + + List<_Book> get books; + + _Book get newestBook; + + @SerializableField(exclude: true, isNullable: true) + String get secret; + + @SerializableField(exclude: true, canDeserialize: true, isNullable: true) + String get obscured; +} + +@Serializable(serializers: Serializers.all) +abstract class _Library extends Model { + Map get collection; +} + +@Serializable(serializers: Serializers.all) +abstract class _Bookmark extends Model { + @SerializableField(exclude: true) + final _Book book; + + List get history; + + @SerializableField(isNullable: false) + int get page; + + String get comment; + + _Bookmark(this.book); +} diff --git a/angel_serialize_generator/test/models/book.g.dart b/angel_serialize_generator/test/models/book.g.dart index ef6fbb81..a5163786 100644 --- a/angel_serialize_generator/test/models/book.g.dart +++ b/angel_serialize_generator/test/models/book.g.dart @@ -12,11 +12,11 @@ part of angel_serialize.test.models.book; class Book extends _Book { Book( {this.id, - @required this.author, - @required this.title, - @required this.description, - @required this.pageCount, - @required List notModels, + this.author, + this.title, + this.description, + this.pageCount, + List notModels, this.camelCaseString, this.createdAt, this.updatedAt}) @@ -105,33 +105,227 @@ class Book extends _Book { } } +@generatedSerializable +class Author extends _Author { + Author( + {this.id, + @required this.name, + @required this.age, + List<_Book> books, + this.newestBook, + this.secret, + this.obscured, + this.createdAt, + this.updatedAt}) + : this.books = new List.unmodifiable(books ?? []); + + @override + final String id; + + @override + final String name; + + @override + final int age; + + @override + final List<_Book> books; + + @override + final _Book newestBook; + + @override + final String secret; + + @override + final String obscured; + + @override + final DateTime createdAt; + + @override + final DateTime updatedAt; + + Author copyWith( + {String id, + String name, + int age, + List<_Book> books, + _Book newestBook, + String secret, + String obscured, + DateTime createdAt, + DateTime updatedAt}) { + return new Author( + id: id ?? this.id, + 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); + } + + bool operator ==(other) { + return other is _Author && + other.id == id && + other.name == name && + other.age == age && + const ListEquality<_Book>(const DefaultEquality<_Book>()) + .equals(other.books, books) && + other.newestBook == newestBook && + other.secret == secret && + other.obscured == obscured && + other.createdAt == createdAt && + other.updatedAt == updatedAt; + } + + @override + int get hashCode { + return hashObjects([ + id, + name, + age, + books, + newestBook, + secret, + obscured, + createdAt, + updatedAt + ]); + } + + Map toJson() { + return AuthorSerializer.toMap(this); + } +} + +@generatedSerializable +class Library extends _Library { + Library( + {this.id, Map collection, this.createdAt, this.updatedAt}) + : this.collection = new Map.unmodifiable(collection ?? {}); + + @override + final String id; + + @override + final Map collection; + + @override + final DateTime createdAt; + + @override + final DateTime updatedAt; + + Library copyWith( + {String id, + Map collection, + DateTime createdAt, + DateTime updatedAt}) { + return new Library( + id: id ?? this.id, + collection: collection ?? this.collection, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt); + } + + bool operator ==(other) { + return other is _Library && + other.id == id && + const MapEquality( + keys: const DefaultEquality(), + values: const DefaultEquality<_Book>()) + .equals(other.collection, collection) && + other.createdAt == createdAt && + other.updatedAt == updatedAt; + } + + @override + int get hashCode { + return hashObjects([id, collection, createdAt, updatedAt]); + } + + Map toJson() { + return LibrarySerializer.toMap(this); + } +} + +@generatedSerializable +class Bookmark extends _Bookmark { + Bookmark(_Book book, + {this.id, + List history, + @required this.page, + this.comment, + this.createdAt, + this.updatedAt}) + : this.history = new List.unmodifiable(history ?? []), + super(book); + + @override + final String id; + + @override + final List history; + + @override + final int page; + + @override + final String comment; + + @override + final DateTime createdAt; + + @override + final DateTime updatedAt; + + Bookmark copyWith(_Book book, + {String id, + List history, + int page, + String comment, + DateTime createdAt, + DateTime updatedAt}) { + return new Bookmark(book, + id: id ?? this.id, + history: history ?? this.history, + page: page ?? this.page, + comment: comment ?? this.comment, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt); + } + + bool operator ==(other) { + return other is _Bookmark && + other.id == id && + const ListEquality(const DefaultEquality()) + .equals(other.history, history) && + other.page == page && + other.comment == comment && + other.createdAt == createdAt && + other.updatedAt == updatedAt; + } + + @override + int get hashCode { + return hashObjects([id, history, page, comment, createdAt, updatedAt]); + } + + Map toJson() { + return BookmarkSerializer.toMap(this); + } +} + // ************************************************************************** // SerializerGenerator // ************************************************************************** abstract class BookSerializer { static Book fromMap(Map map) { - if (map['author'] == null) { - throw new FormatException("Missing required field 'author' on Book."); - } - - if (map['title'] == null) { - throw new FormatException("Missing required field 'title' on Book."); - } - - if (map['description'] == null) { - throw new FormatException( - "Missing required field 'description' on Book."); - } - - if (map['page_count'] == null) { - throw new FormatException("Missing required field 'page_count' on Book."); - } - - if (map['not_models'] == null) { - throw new FormatException("Missing required field 'not_models' on Book."); - } - return new Book( id: map['id'] as String, author: map['author'] as String, @@ -158,27 +352,6 @@ abstract class BookSerializer { if (model == null) { return null; } - if (model.author == null) { - throw new FormatException("Missing required field 'author' on Book."); - } - - if (model.title == null) { - throw new FormatException("Missing required field 'title' on Book."); - } - - if (model.description == null) { - throw new FormatException( - "Missing required field 'description' on Book."); - } - - if (model.pageCount == null) { - throw new FormatException("Missing required field 'page_count' on Book."); - } - - if (model.notModels == null) { - throw new FormatException("Missing required field 'not_models' on Book."); - } - return { 'id': model.id, 'author': model.author, @@ -224,3 +397,218 @@ abstract class BookFields { static const String updatedAt = 'updated_at'; } + +abstract class AuthorSerializer { + static Author fromMap(Map map) { + if (map['name'] == null) { + throw new FormatException("Missing required field 'name' on Author."); + } + + if (map['age'] == null) { + throw new FormatException("Custom message for missing `age`"); + } + + return new Author( + id: map['id'] as String, + name: map['name'] as String, + age: map['age'] as int, + books: map['books'] is Iterable + ? new List.unmodifiable( + ((map['books'] as Iterable).where((x) => x is Map)) + .cast() + .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) + : DateTime.parse(map['created_at'].toString())) + : null, + updatedAt: map['updated_at'] != null + ? (map['updated_at'] is DateTime + ? (map['updated_at'] as DateTime) + : DateTime.parse(map['updated_at'].toString())) + : null); + } + + static Map toMap(_Author model) { + if (model == null) { + return null; + } + if (model.name == null) { + throw new FormatException("Missing required field 'name' on Author."); + } + + if (model.age == null) { + throw new FormatException("Custom message for missing `age`"); + } + + return { + 'id': model.id, + '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() + }; + } +} + +abstract class AuthorFields { + static const List allFields = [ + id, + name, + age, + books, + newestBook, + secret, + obscured, + createdAt, + updatedAt + ]; + + static const String id = 'id'; + + static const String name = 'name'; + + static const String age = 'age'; + + static const String books = 'books'; + + static const String newestBook = 'newest_book'; + + static const String secret = 'secret'; + + static const String obscured = 'obscured'; + + static const String createdAt = 'created_at'; + + static const String updatedAt = 'updated_at'; +} + +abstract class LibrarySerializer { + static Library fromMap(Map map) { + return new Library( + id: map['id'] as String, + collection: map['collection'] is Map + ? new 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) + : DateTime.parse(map['created_at'].toString())) + : null, + updatedAt: map['updated_at'] != null + ? (map['updated_at'] is DateTime + ? (map['updated_at'] as DateTime) + : DateTime.parse(map['updated_at'].toString())) + : null); + } + + static Map toMap(_Library model) { + if (model == null) { + return null; + } + return { + 'id': model.id, + '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() + }; + } +} + +abstract class LibraryFields { + static const List allFields = [ + id, + collection, + createdAt, + updatedAt + ]; + + static const String id = 'id'; + + static const String collection = 'collection'; + + static const String createdAt = 'created_at'; + + static const String updatedAt = 'updated_at'; +} + +abstract class BookmarkSerializer { + static Bookmark fromMap(Map map, _Book book) { + if (map['page'] == null) { + throw new FormatException("Missing required field 'page' on Bookmark."); + } + + return new Bookmark(book, + id: map['id'] as String, + history: map['history'] is Iterable + ? (map['history'] as Iterable).cast().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) + : DateTime.parse(map['created_at'].toString())) + : null, + updatedAt: map['updated_at'] != null + ? (map['updated_at'] is DateTime + ? (map['updated_at'] as DateTime) + : DateTime.parse(map['updated_at'].toString())) + : null); + } + + static Map toMap(_Bookmark model) { + if (model == null) { + return null; + } + if (model.page == null) { + throw new FormatException("Missing required field 'page' on Bookmark."); + } + + return { + 'id': model.id, + 'history': model.history, + 'page': model.page, + 'comment': model.comment, + 'created_at': model.createdAt?.toIso8601String(), + 'updated_at': model.updatedAt?.toIso8601String() + }; + } +} + +abstract class BookmarkFields { + static const List allFields = [ + id, + history, + page, + comment, + createdAt, + updatedAt + ]; + + static const String id = 'id'; + + 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'; +} diff --git a/angel_serialize_generator/test/models/game_pad.dart b/angel_serialize_generator/test/models/game_pad.dart deleted file mode 100644 index cf2290ea..00000000 --- a/angel_serialize_generator/test/models/game_pad.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:angel_serialize/angel_serialize.dart'; -import 'package:collection/collection.dart'; -import 'game_pad_button.dart'; -part 'game_pad.g.dart'; - -@serializable -class _Gamepad { - List buttons; - - Map dynamicMap; - - // ignore: unused_field - String _somethingPrivate; -} diff --git a/angel_serialize_generator/test/models/game_pad.g.dart b/angel_serialize_generator/test/models/game_pad.g.dart deleted file mode 100644 index 33359fb2..00000000 --- a/angel_serialize_generator/test/models/game_pad.g.dart +++ /dev/null @@ -1,96 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'game_pad.dart'; - -// ************************************************************************** -// JsonModelGenerator -// ************************************************************************** - -@generatedSerializable -class Gamepad extends _Gamepad { - Gamepad( - {@required List buttons, - @required Map dynamicMap}) - : this.buttons = new List.unmodifiable(buttons ?? []), - this.dynamicMap = new Map.unmodifiable(dynamicMap ?? {}); - - @override - final List buttons; - - @override - final Map dynamicMap; - - Gamepad copyWith({List buttons, Map dynamicMap}) { - return new Gamepad( - buttons: buttons ?? this.buttons, - dynamicMap: dynamicMap ?? this.dynamicMap); - } - - bool operator ==(other) { - return other is _Gamepad && - const ListEquality(const DefaultEquality()) - .equals(other.buttons, buttons) && - const MapEquality( - keys: const DefaultEquality(), - values: const DefaultEquality()) - .equals(other.dynamicMap, dynamicMap); - } - - @override - int get hashCode { - return hashObjects([buttons, dynamicMap]); - } - - Map toJson() { - return GamepadSerializer.toMap(this); - } -} - -// ************************************************************************** -// SerializerGenerator -// ************************************************************************** - -abstract class GamepadSerializer { - static Gamepad fromMap(Map map) { - if (map['buttons'] == null) { - throw new FormatException("Missing required field 'buttons' on Gamepad."); - } - - if (map['dynamic_map'] == null) { - throw new FormatException( - "Missing required field 'dynamic_map' on Gamepad."); - } - - return new Gamepad( - buttons: map['buttons'] is Iterable - ? (map['buttons'] as Iterable).cast().toList() - : null, - dynamicMap: map['dynamic_map'] is Map - ? (map['dynamic_map'] as Map).cast() - : null); - } - - static Map toMap(_Gamepad model) { - if (model == null) { - return null; - } - if (model.buttons == null) { - throw new FormatException("Missing required field 'buttons' on Gamepad."); - } - - if (model.dynamicMap == null) { - throw new FormatException( - "Missing required field 'dynamic_map' on Gamepad."); - } - - return {'buttons': model.buttons, 'dynamic_map': model.dynamicMap}; - } -} - -abstract class GamepadFields { - static const List allFields = [buttons, dynamicMap]; - - static const String buttons = 'buttons'; - - static const String dynamicMap = 'dynamic_map'; -} diff --git a/angel_serialize_generator/test/models/game_pad_button.dart b/angel_serialize_generator/test/models/game_pad_button.dart index cf31f0f3..bb23fa54 100644 --- a/angel_serialize_generator/test/models/game_pad_button.dart +++ b/angel_serialize_generator/test/models/game_pad_button.dart @@ -6,3 +6,13 @@ abstract class _GamepadButton { String get name; int get radius; } + +@serializable +class _Gamepad { + List<_GamepadButton> buttons; + + Map dynamicMap; + + // ignore: unused_field + String _somethingPrivate; +} diff --git a/angel_serialize_generator/test/models/game_pad_button.g.dart b/angel_serialize_generator/test/models/game_pad_button.g.dart index 4f63c12e..4ebb3e48 100644 --- a/angel_serialize_generator/test/models/game_pad_button.g.dart +++ b/angel_serialize_generator/test/models/game_pad_button.g.dart @@ -8,7 +8,7 @@ part of 'game_pad_button.dart'; @generatedSerializable class GamepadButton implements _GamepadButton { - const GamepadButton({@required this.name, @required this.radius}); + const GamepadButton({this.name, this.radius}); @override final String name; @@ -37,22 +37,52 @@ class GamepadButton implements _GamepadButton { } } +@generatedSerializable +class Gamepad extends _Gamepad { + Gamepad({List<_GamepadButton> buttons, Map dynamicMap}) + : this.buttons = new List.unmodifiable(buttons ?? []), + this.dynamicMap = new Map.unmodifiable(dynamicMap ?? {}); + + @override + final List<_GamepadButton> buttons; + + @override + final Map dynamicMap; + + Gamepad copyWith( + {List<_GamepadButton> buttons, Map 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( + keys: const DefaultEquality(), + values: const DefaultEquality()) + .equals(other.dynamicMap, dynamicMap); + } + + @override + int get hashCode { + return hashObjects([buttons, dynamicMap]); + } + + Map toJson() { + return GamepadSerializer.toMap(this); + } +} + // ************************************************************************** // SerializerGenerator // ************************************************************************** abstract class GamepadButtonSerializer { static GamepadButton fromMap(Map map) { - if (map['name'] == null) { - throw new FormatException( - "Missing required field 'name' on GamepadButton."); - } - - if (map['radius'] == null) { - throw new FormatException( - "Missing required field 'radius' on GamepadButton."); - } - return new GamepadButton( name: map['name'] as String, radius: map['radius'] as int); } @@ -61,16 +91,6 @@ abstract class GamepadButtonSerializer { if (model == null) { return null; } - if (model.name == null) { - throw new FormatException( - "Missing required field 'name' on GamepadButton."); - } - - if (model.radius == null) { - throw new FormatException( - "Missing required field 'radius' on GamepadButton."); - } - return {'name': model.name, 'radius': model.radius}; } } @@ -82,3 +102,37 @@ abstract class GamepadButtonFields { static const String radius = 'radius'; } + +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)) + .cast() + .map(GamepadButtonSerializer.fromMap)) + : null, + dynamicMap: map['dynamic_map'] is Map + ? (map['dynamic_map'] as Map).cast() + : null); + } + + static Map toMap(_Gamepad model) { + if (model == null) { + return null; + } + return { + 'buttons': + model.buttons?.map((m) => GamepadButtonSerializer.toMap(m))?.toList(), + 'dynamic_map': model.dynamicMap + }; + } +} + +abstract class GamepadFields { + static const List allFields = [buttons, dynamicMap]; + + static const String buttons = 'buttons'; + + static const String dynamicMap = 'dynamic_map'; +} diff --git a/angel_serialize_generator/test/models/goat.g.dart b/angel_serialize_generator/test/models/goat.g.dart index 410c6821..985261bc 100644 --- a/angel_serialize_generator/test/models/goat.g.dart +++ b/angel_serialize_generator/test/models/goat.g.dart @@ -43,14 +43,6 @@ class Goat implements _Goat { abstract class GoatSerializer { static Goat fromMap(Map map) { - if (map['integer'] == null) { - throw new FormatException("Missing required field 'integer' on Goat."); - } - - if (map['list'] == null) { - throw new FormatException("Missing required field 'list' on Goat."); - } - return new Goat( integer: map['integer'] as int ?? 34, list: map['list'] is Iterable @@ -62,14 +54,6 @@ abstract class GoatSerializer { if (model == null) { return null; } - if (model.integer == null) { - throw new FormatException("Missing required field 'integer' on Goat."); - } - - if (model.list == null) { - throw new FormatException("Missing required field 'list' on Goat."); - } - return {'integer': model.integer, 'list': model.list}; } } diff --git a/angel_serialize_generator/test/models/with_enum.dart b/angel_serialize_generator/test/models/with_enum.dart index ae79f9f0..cf1c0a90 100644 --- a/angel_serialize_generator/test/models/with_enum.dart +++ b/angel_serialize_generator/test/models/with_enum.dart @@ -9,10 +9,8 @@ abstract class _WithEnum { @DefaultsTo(WithEnumType.b) WithEnumType get type; - @nullable List get finalList; - @nullable Uint8List get imageBytes; } diff --git a/angel_serialize_generator/test/models/with_enum.g.dart b/angel_serialize_generator/test/models/with_enum.g.dart index b6e9f7db..b522fb37 100644 --- a/angel_serialize_generator/test/models/with_enum.g.dart +++ b/angel_serialize_generator/test/models/with_enum.g.dart @@ -52,10 +52,6 @@ class WithEnum implements _WithEnum { abstract class WithEnumSerializer { static WithEnum fromMap(Map map) { - if (map['type'] == null) { - throw new FormatException("Missing required field 'type' on WithEnum."); - } - return new WithEnum( type: map['type'] is WithEnumType ? (map['type'] as WithEnumType) @@ -80,10 +76,6 @@ abstract class WithEnumSerializer { if (model == null) { return null; } - if (model.type == null) { - throw new FormatException("Missing required field 'type' on WithEnum."); - } - return { 'type': model.type == null ? null : WithEnumType.values.indexOf(model.type),