Updated serialise

This commit is contained in:
thomashii 2022-02-27 12:16:31 +08:00
parent f5c2598cbd
commit 0dc71df45a
23 changed files with 176 additions and 174 deletions

View file

@ -1,9 +1,12 @@
# Change Log # Change Log
## 6.0.0
* Updated to min SDK 2.15.x
## 5.0.0 ## 5.0.0
* Updated `analyzer` to version 3.x * Skipped release
* Updated min SDK to 2.14.x
## 4.1.1 ## 4.1.1

View file

@ -38,7 +38,7 @@ class SerializableField {
final String? alias; final String? alias;
/// A default for this field. /// A default for this field.
final defaultValue; final dynamic defaultValue;
/// A custom serializer for this field. /// A custom serializer for this field.
final Symbol? serializer; final Symbol? serializer;

View file

@ -1,15 +1,18 @@
name: angel3_serialize name: angel3_serialize
version: 4.1.1 version: 6.0.0
description: Static annotations powering Angel3 model serialization. Combine with angel3_serialize_generator for flexible modeling. description: Static annotations powering Angel3 model serialization. Combine with angel3_serialize_generator for flexible modeling.
homepage: https://angel3-framework.web.app/ homepage: https://angel3-framework.web.app/
repository: https://github.com/dukefirehawk/angel/tree/master/packages/serialize/angel_serialize repository: https://github.com/dukefirehawk/angel/tree/master/packages/serialize/angel_serialize
environment: environment:
sdk: '>=2.12.0 <3.0.0' sdk: '>=2.15.0 <3.0.0'
dependencies: dependencies:
angel3_model: ^3.0.0 angel3_model: ^6.0.0
collection: ^1.15.0 collection: ^1.15.0
meta: ^1.3.0 meta: ^1.3.0
quiver: ^3.0.1 quiver: ^3.0.1
dev_dependencies: dev_dependencies:
lints: ^1.0.0 lints: ^1.0.0
dependency_overrides:
angel3_model:
path: ../../model

View file

@ -3,7 +3,7 @@ Primary Authors
* __[Thomas Hii](dukefirehawk.apps@gmail.com)__ * __[Thomas Hii](dukefirehawk.apps@gmail.com)__
Thomas is the current maintainer of the code base. He has refactored and migrated the Thomas is the current maintainer of the code base. He has refactored and migrated the
code base to support NNBD. code base to support NNBD.
* __[Tobe O](thosakwe@gmail.com)__ * __[Tobe O](thosakwe@gmail.com)__

View file

@ -1,9 +1,14 @@
# Change Log # Change Log
## 6.0.0
* Updated to min SDK 2.15.x
* Updated to `analyzer` 3.x.x
* Fixed default value for `List` and `Enum`
## 5.0.0 ## 5.0.0
* Updated `analyzer` to version 3.x * Skipped release
* Updated min SDK to 2.14.x
## 4.3.0 ## 4.3.0

View file

@ -66,16 +66,17 @@ class TodoSerializer extends Codec<Todo, Map> {
@override @override
TodoEncoder get encoder => const TodoEncoder(); TodoEncoder get encoder => const TodoEncoder();
@override @override
TodoDecoder get decoder => const TodoDecoder(); TodoDecoder get decoder => const TodoDecoder();
static Todo fromMap(Map map) { static Todo fromMap(Map map) {
return Todo( return Todo(
text: map['text'] as String?, completed: map['completed'] as bool?); text: map['text'] as String?, completed: map['completed'] as bool?);
} }
static Map<String, dynamic> toMap(_Todo model) { static Map<String, dynamic> toMap(_Todo? model) {
if (model == null) {
throw FormatException("Required field [model] cannot be null");
}
return {'text': model.text, 'completed': model.completed}; return {'text': model.text, 'completed': model.completed};
} }
} }

View file

@ -215,32 +215,6 @@ Future<BuildContext?> buildContext(
} }
} }
// 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;
// }
// var field = ShimFieldImpl(key, dateTime);
// ctx.aliases[key] = ReCase(key).snakeCase;
// ctx.fields.add(field);
// ctx.shimmed[key] = true;
// }
// }
// }
// Get constructor params, if any // Get constructor params, if any
ctx.constructorParameters.addAll(clazz.unnamedConstructor!.parameters); ctx.constructorParameters.addAll(clazz.unnamedConstructor!.parameters);

View file

@ -14,7 +14,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
buildStep.resolver, true); buildStep.resolver, true);
if (ctx == null) { if (ctx == null) {
log.severe('Invalid builder context'); log.fine('Invalid builder context');
throw 'Invalid builder context'; throw 'Invalid builder context';
} }
@ -128,8 +128,8 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
? 'List' ? 'List'
: 'Map'; : 'Map';
String? defaultValue = typeName == 'List' ? '[]' : '{}'; String? defaultValue = typeName == 'List' ? '[]' : '{}';
var existingDefault = ctx.defaults[field.name];
var existingDefault = ctx.defaults[field.name];
if (existingDefault != null) { if (existingDefault != null) {
defaultValue = dartObjectToString(existingDefault); defaultValue = dartObjectToString(existingDefault);
} }
@ -173,7 +173,15 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
if (!b.toThis) { if (!b.toThis) {
b.type = convertTypeReference(field.type); b.type = convertTypeReference(field.type);
} }
b.defaultTo = Code('const []');
// Get the default if presence
var existingDefault = ctx.defaults[field.name];
if (existingDefault != null) {
var defaultValue = dartObjectToString(existingDefault);
b.defaultTo = Code('$defaultValue');
} else {
b.defaultTo = Code('const []');
}
} else if (!b.toThis) { } else if (!b.toThis) {
b.type = convertTypeReference(field.type); b.type = convertTypeReference(field.type);
} else { } else {

View file

@ -8,14 +8,14 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
@override @override
Future<String?> generateForAnnotatedElement( Future<String?> generateForAnnotatedElement(
Element element, ConstantReader annotation, BuildStep buildStep) async { Element element, ConstantReader annotation, BuildStep buildStep) async {
//log.fine('Running SerializerGenerator'); log.fine('Running SerializerGenerator');
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 as ClassElement, annotation, buildStep, var ctx = await buildContext(element as ClassElement, annotation, buildStep,
buildStep.resolver, autoSnakeCaseNames != false); buildStep.resolver, !autoSnakeCaseNames);
if (ctx == null) { if (ctx == null) {
log.severe('Invalid builder context'); log.severe('Invalid builder context');
@ -25,11 +25,13 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
var serializers = annotation.peek('serializers')?.listValue ?? []; var serializers = annotation.peek('serializers')?.listValue ?? [];
if (serializers.isEmpty) { if (serializers.isEmpty) {
log.severe("No Serializers");
return null; return null;
} }
// Check if any serializer is recognized // Check if any serializer is recognized
if (!serializers.any((s) => Serializers.all.contains(s.toIntValue()))) { if (!serializers.any((s) => Serializers.all.contains(s.toIntValue()))) {
log.severe("No recognizable Serializers");
return null; return null;
} }
@ -46,15 +48,17 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
/// Generate a serializer class. /// Generate a serializer class.
void generateClass( void generateClass(
List<int> serializers, BuildContext ctx, LibraryBuilder file) { List<int> serializers, BuildContext ctx, LibraryBuilder file) {
//log.fine('Generate serializer class'); log.fine('Generate serializer class');
// Generate canonical codecs, etc. // Generate canonical codecs, etc.
var pascal = ctx.modelClassNameRecase.pascalCase.replaceAll('?', ''); var pascal = ctx.modelClassNameRecase.pascalCase.replaceAll('?', '');
var camel = ctx.modelClassNameRecase.camelCase.replaceAll('?', ''); var camel = ctx.modelClassNameRecase.camelCase.replaceAll('?', '');
log.info('Generating ${pascal}Serializer'); log.fine('Generating ${pascal}Serializer');
if (ctx.constructorParameters.isEmpty) { if (ctx.constructorParameters.isEmpty) {
log.fine("Constructor is empty");
file.body.add(Code(''' file.body.add(Code('''
const ${pascal}Serializer ${camel}Serializer = ${pascal}Serializer(); const ${pascal}Serializer ${camel}Serializer = ${pascal}Serializer();
@ -201,7 +205,7 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
type.typeArguments[1].getDisplayString(withNullability: true)); type.typeArguments[1].getDisplayString(withNullability: true));
serializedRepresentation = serializedRepresentation =
'''model.${field.name}.keys.fold({}, (map, key) { '''model.${field.name}.keys.fold({}, (map, key) {
return (map as Map<String,dynamic>?)?..[key] = return (map as Map<dynamic,dynamic>?)?..[key] =
${serializerToMap(rc, 'model.${field.name}[key]')}; ${serializerToMap(rc, 'model.${field.name}[key]')};
})'''; })''';
} else if (type.element.isEnum) { } else if (type.element.isEnum) {
@ -235,7 +239,8 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
buf.write('};'); buf.write('};');
method.body = Block.of([ method.body = Block.of([
Code('if (model == null) { return {}; }'), Code(
'if (model == null) { throw FormatException("Required field [model] cannot be null"); }'),
Code(buf.toString()), Code(buf.toString()),
]); ]);
})); }));
@ -305,13 +310,11 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
var deserializedRepresentation = var deserializedRepresentation =
"map['$alias'] as ${typeToString(type)}"; "map['$alias'] as ${typeToString(type)}";
if (type.nullabilitySuffix == NullabilitySuffix.question) { if (type.nullabilitySuffix == NullabilitySuffix.question) {
deserializedRepresentation += '?'; deserializedRepresentation += '?';
} }
//log.fine(
// 'deserializedRepresentation => $deserializedRepresentation, type => $type, nullcheck => ${type.nullabilitySuffix}');
var defaultValue = 'null'; var defaultValue = 'null';
var existingDefault = ctx.defaults[field.name]; var existingDefault = ctx.defaults[field.name];
@ -319,6 +322,10 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
var d = dartObjectToString(existingDefault); var d = dartObjectToString(existingDefault);
if (d != null) { if (d != null) {
defaultValue = d; defaultValue = d;
if (!deserializedRepresentation.endsWith("?")) {
deserializedRepresentation += "?";
}
} }
deserializedRepresentation = deserializedRepresentation =
'$deserializedRepresentation ?? $defaultValue'; '$deserializedRepresentation ?? $defaultValue';
@ -372,7 +379,7 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
} else if (type.element.isEnum) { } else if (type.element.isEnum) {
deserializedRepresentation = ''' deserializedRepresentation = '''
map['$alias'] is ${type.getDisplayString(withNullability: true)} map['$alias'] is ${type.getDisplayString(withNullability: true)}
? (map['$alias'] as ${type.getDisplayString(withNullability: true)}) ? (map['$alias'] as ${type.getDisplayString(withNullability: true)}) ?? $defaultValue
: :
( (
map['$alias'] is int map['$alias'] is int

View file

@ -1,14 +1,14 @@
name: angel3_serialize_generator name: angel3_serialize_generator
version: 5.0.0 version: 6.0.0
description: Angel3 model serialization generators, designed for use with Angel. Combine with angel_serialize for flexible modeling. description: Angel3 model serialization generators, designed for use with Angel. Combine with angel_serialize for flexible modeling.
homepage: https://angel3-framework.web.app/ homepage: https://angel3-framework.web.app/
repository: https://github.com/dukefirehawk/angel/tree/master/packages/serialize/angel_serialize_generator repository: https://github.com/dukefirehawk/angel/tree/master/packages/serialize/angel_serialize_generator
environment: environment:
sdk: '>=2.14.0 <3.0.0' sdk: '>=2.15.0 <3.0.0'
dependencies: dependencies:
analyzer: ^3.0.0 analyzer: ^3.0.0
angel3_model: ^3.0.0 angel3_model: ^6.0.0
angel3_serialize: ^4.1.0 angel3_serialize: ^6.0.0
belatuk_code_buffer: ^3.0.0 belatuk_code_buffer: ^3.0.0
build: ^2.0.1 build: ^2.0.1
build_config: ^1.0.0 build_config: ^1.0.0
@ -24,3 +24,8 @@ dev_dependencies:
collection: ^1.15.0 collection: ^1.15.0
lints: ^1.0.0 lints: ^1.0.0
test: ^1.17.4 test: ^1.17.4
dependency_overrides:
angel3_model:
path: ../../model
angel3_serialize:
path: ../angel_serialize

View file

@ -31,30 +31,30 @@ void main() {
group('serialization', () { group('serialization', () {
test('serialization sets proper fields', () { test('serialization sets proper fields', () {
expect(serializedDeathlyHallows!['id'], deathlyHallows.id); expect(serializedDeathlyHallows['id'], deathlyHallows.id);
expect(serializedDeathlyHallows['author'], deathlyHallows.author); expect(serializedDeathlyHallows['author'], deathlyHallows.author);
expect( expect(
serializedDeathlyHallows['description'], deathlyHallows.description); serializedDeathlyHallows['description'], deathlyHallows.description);
expect(serializedDeathlyHallows['page_count'], deathlyHallows.pageCount); expect(serializedDeathlyHallows['page_count'], deathlyHallows.pageCount);
expect(serializedDeathlyHallows['created_at'], isNull); expect(serializedDeathlyHallows['created_at'], isNull);
expect(serializedDeathlyHallows['updated_at'], expect(serializedDeathlyHallows['updated_at'],
deathlyHallows.updatedAt!.toIso8601String()); deathlyHallows.updatedAt?.toIso8601String());
}); });
test('can be mutated', () { test('can be mutated', () {
var b = deathlyHallows.copyWith(); var b = deathlyHallows.copyWith();
b.author = 'Hey'; b.author = 'Hey';
expect(b.author, 'Hey'); expect(b.author, 'Hey');
expect(b.toJson()![BookFields.author], 'Hey'); expect(b.toJson()[BookFields.author], 'Hey');
}); });
test('heeds @Alias', () { test('heeds @Alias', () {
expect(serializedDeathlyHallows!['page_count'], deathlyHallows.pageCount); expect(serializedDeathlyHallows['page_count'], deathlyHallows.pageCount);
expect(serializedDeathlyHallows.keys, isNot(contains('pageCount'))); expect(serializedDeathlyHallows.keys, isNot(contains('pageCount')));
}); });
test('standard list', () { test('standard list', () {
expect(serializedDeathlyHallows!['not_models'], deathlyHallows.notModels); expect(serializedDeathlyHallows['not_models'], deathlyHallows.notModels);
}); });
test('heeds @exclude', () { test('heeds @exclude', () {
@ -112,7 +112,7 @@ void main() {
group('deserialization', () { group('deserialization', () {
test('deserialization sets proper fields', () { test('deserialization sets proper fields', () {
var book = BookSerializer.fromMap(deathlyHallowsMap!); var book = BookSerializer.fromMap(deathlyHallowsMap);
expect(book.id, deathlyHallows.id); expect(book.id, deathlyHallows.id);
expect(book.author, deathlyHallows.author); expect(book.author, deathlyHallows.author);
expect(book.description, deathlyHallows.description); expect(book.description, deathlyHallows.description);

View file

@ -3,8 +3,8 @@ import 'dart:typed_data';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'models/with_enum.dart'; import 'models/with_enum.dart';
const WithEnum aWithEnum = WithEnum(type: WithEnumType.a); WithEnum aWithEnum = WithEnum(type: WithEnumType.a);
const WithEnum aWithEnum2 = WithEnum(type: WithEnumType.a); WithEnum aWithEnum2 = WithEnum(type: WithEnumType.a);
void main() { void main() {
test('enum serializes to int', () { test('enum serializes to int', () {
@ -44,7 +44,11 @@ void main() {
}); });
test('const', () { test('const', () {
expect(identical(aWithEnum, aWithEnum2), true); print('aWithEnum ${aWithEnum.hashCode}');
print('aWithEnum2 ${aWithEnum2.hashCode}');
//expect(identical(aWithEnum, aWithEnum2), true);
expect(aWithEnum == aWithEnum2, true);
}); });
test('uint8list', () { test('uint8list', () {

View file

@ -1,5 +1,5 @@
// GENERATED CODE - DO NOT MODIFY BY HAND // GENERATED CODE - DO NOT MODIFY BY HAND
declare module 'angel_serialize_generator' { declare module 'angel3_serialize_generator' {
interface Book { interface Book {
id?: string; id?: string;
created_at?: any; created_at?: any;

View file

@ -1,8 +1,6 @@
library angel_serialize.test.models.book; library angel_serialize.test.models.book;
import 'package:angel3_model/angel3_model.dart';
import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:angel3_serialize/angel3_serialize.dart';
import 'package:collection/collection.dart';
part 'book.g.dart'; part 'book.g.dart';
@Serializable( @Serializable(

View file

@ -18,7 +18,7 @@ class Book extends _Book {
this.title, this.title,
this.description, this.description,
this.pageCount, this.pageCount,
List<double>? notModels, List<double>? notModels = const [],
this.camelCaseString}) this.camelCaseString})
: notModels = List.unmodifiable(notModels ?? []); : notModels = List.unmodifiable(notModels ?? []);
@ -110,7 +110,7 @@ class Book extends _Book {
return 'Book(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, author=$author, title=$title, description=$description, pageCount=$pageCount, notModels=$notModels, camelCaseString=$camelCaseString)'; return 'Book(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, author=$author, title=$title, description=$description, pageCount=$pageCount, notModels=$notModels, camelCaseString=$camelCaseString)';
} }
Map<String, dynamic>? toJson() { Map<String, dynamic> toJson() {
return BookSerializer.toMap(this); return BookSerializer.toMap(this);
} }
} }
@ -123,11 +123,11 @@ class Author extends _Author {
this.updatedAt, this.updatedAt,
required this.name, required this.name,
required this.age, required this.age,
List<_Book>? books, List<_Book> books = const [],
this.newestBook, this.newestBook,
this.secret, this.secret,
this.obscured}) this.obscured})
: books = List.unmodifiable(books ?? []); : books = List.unmodifiable(books);
/// A unique identifier corresponding to this item. /// A unique identifier corresponding to this item.
@override @override
@ -142,23 +142,23 @@ class Author extends _Author {
DateTime? updatedAt; DateTime? updatedAt;
@override @override
final String? name; String? name;
@override @override
final int? age; int? age;
@override @override
final List<_Book> books; List<_Book> books;
/// The newest book. /// The newest book.
@override @override
final _Book? newestBook; _Book? newestBook;
@override @override
final String? secret; String? secret;
@override @override
final String? obscured; String? obscured;
Author copyWith( Author copyWith(
{String? id, {String? id,
@ -225,8 +225,11 @@ class Author extends _Author {
@generatedSerializable @generatedSerializable
class Library extends _Library { class Library extends _Library {
Library( Library(
{this.id, this.createdAt, this.updatedAt, Map<String, _Book>? collection}) {this.id,
: collection = Map.unmodifiable(collection ?? {}); this.createdAt,
this.updatedAt,
required Map<String, _Book> collection})
: collection = Map.unmodifiable(collection);
/// A unique identifier corresponding to this item. /// A unique identifier corresponding to this item.
@override @override
@ -241,7 +244,7 @@ class Library extends _Library {
DateTime? updatedAt; DateTime? updatedAt;
@override @override
final Map<String, _Book> collection; Map<String, _Book> collection;
Library copyWith( Library copyWith(
{String? id, {String? id,
@ -288,10 +291,10 @@ class Bookmark extends _Bookmark {
{this.id, {this.id,
this.createdAt, this.createdAt,
this.updatedAt, this.updatedAt,
List<int>? history, List<int> history = const [],
required this.page, required this.page,
this.comment}) this.comment})
: history = List.unmodifiable(history ?? []), : history = List.unmodifiable(history),
super(book); super(book);
/// A unique identifier corresponding to this item. /// A unique identifier corresponding to this item.
@ -307,13 +310,13 @@ class Bookmark extends _Bookmark {
DateTime? updatedAt; DateTime? updatedAt;
@override @override
final List<int> history; List<int> history;
@override @override
final int? page; int? page;
@override @override
final String? comment; String? comment;
Bookmark copyWith(_Book book, Bookmark copyWith(_Book book,
{String? id, {String? id,
@ -364,11 +367,11 @@ class Bookmark extends _Bookmark {
const BookSerializer bookSerializer = BookSerializer(); const BookSerializer bookSerializer = BookSerializer();
class BookEncoder extends Converter<Book, Map?> { class BookEncoder extends Converter<Book, Map> {
const BookEncoder(); const BookEncoder();
@override @override
Map? convert(Book model) => BookSerializer.toMap(model); Map convert(Book model) => BookSerializer.toMap(model);
} }
class BookDecoder extends Converter<Map, Book> { class BookDecoder extends Converter<Map, Book> {
@ -378,26 +381,24 @@ class BookDecoder extends Converter<Map, Book> {
Book convert(Map map) => BookSerializer.fromMap(map); Book convert(Map map) => BookSerializer.fromMap(map);
} }
class BookSerializer extends Codec<Book, Map?> { class BookSerializer extends Codec<Book, Map> {
const BookSerializer(); const BookSerializer();
@override @override
BookEncoder get encoder => const BookEncoder(); BookEncoder get encoder => const BookEncoder();
@override @override
BookDecoder get decoder => const BookDecoder(); BookDecoder get decoder => const BookDecoder();
static Book fromMap(Map map) { static Book fromMap(Map map) {
return Book( return Book(
id: map['id'] as String?, id: map['id'] as String?,
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'].toString())) : 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'].toString())) : DateTime.parse(map['updated_at'].toString()))
: null, : null,
author: map['author'] as String?, author: map['author'] as String?,
@ -406,13 +407,13 @@ class BookSerializer extends Codec<Book, Map?> {
pageCount: map['page_count'] as int?, pageCount: map['page_count'] as int?,
notModels: map['not_models'] is Iterable notModels: map['not_models'] is Iterable
? (map['not_models'] as Iterable).cast<double>().toList() ? (map['not_models'] as Iterable).cast<double>().toList()
: null, : [],
camelCaseString: map['camelCase'] as String?); camelCaseString: map['camelCase'] as String?);
} }
static Map<String, dynamic>? toMap(_Book? model) { static Map<String, dynamic> toMap(_Book? model) {
if (model == null) { if (model == null) {
return null; throw FormatException("Required field [model] cannot be null");
} }
return { return {
'id': model.id, 'id': model.id,
@ -481,10 +482,8 @@ class AuthorSerializer extends Codec<Author, Map> {
@override @override
AuthorEncoder get encoder => const AuthorEncoder(); AuthorEncoder get encoder => const AuthorEncoder();
@override @override
AuthorDecoder get decoder => const AuthorDecoder(); AuthorDecoder get decoder => const AuthorDecoder();
static Author fromMap(Map map) { static Author fromMap(Map map) {
if (map['name'] == null) { if (map['name'] == null) {
throw FormatException("Missing required field 'name' on Author."); throw FormatException("Missing required field 'name' on Author.");
@ -498,12 +497,12 @@ class AuthorSerializer extends Codec<Author, Map> {
id: map['id'] as String?, id: map['id'] as String?,
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'].toString())) : 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'].toString())) : DateTime.parse(map['updated_at'].toString()))
: null, : null,
name: map['name'] as String?, name: map['name'] as String?,
@ -511,22 +510,17 @@ class AuthorSerializer extends Codec<Author, Map> {
books: map['books'] is Iterable books: map['books'] is Iterable
? List.unmodifiable(((map['books'] as Iterable).whereType<Map>()) ? List.unmodifiable(((map['books'] as Iterable).whereType<Map>())
.map(BookSerializer.fromMap)) .map(BookSerializer.fromMap))
: null, : [],
newestBook: map['newest_book'] != null newestBook: map['newest_book'] != null
? BookSerializer.fromMap(map['newest_book'] as Map) ? BookSerializer.fromMap(map['newest_book'] as Map)
: null, : null,
obscured: map['obscured'] as String?); obscured: map['obscured'] as String?);
} }
static Map<String, dynamic> toMap(_Author model) { static Map<String, dynamic> toMap(_Author? model) {
if (model.name == null) { if (model == null) {
throw FormatException("Missing required field 'name' on Author."); throw FormatException("Required field [model] cannot be null");
} }
if (model.age == null) {
throw FormatException('Custom message for missing `age`');
}
return { return {
'id': model.id, 'id': model.id,
'created_at': model.createdAt?.toIso8601String(), 'created_at': model.createdAt?.toIso8601String(),
@ -592,21 +586,19 @@ class LibrarySerializer extends Codec<Library, Map> {
@override @override
LibraryEncoder get encoder => const LibraryEncoder(); LibraryEncoder get encoder => const LibraryEncoder();
@override @override
LibraryDecoder get decoder => const LibraryDecoder(); LibraryDecoder get decoder => const LibraryDecoder();
static Library fromMap(Map map) { static Library fromMap(Map map) {
return Library( return Library(
id: map['id'] as String?, id: map['id'] as String?,
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'].toString())) : 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'].toString())) : DateTime.parse(map['updated_at'].toString()))
: null, : null,
collection: map['collection'] is Map collection: map['collection'] is Map
@ -616,16 +608,20 @@ class LibrarySerializer extends Codec<Library, Map> {
..[key] = BookSerializer.fromMap( ..[key] = BookSerializer.fromMap(
((map['collection'] as Map)[key]) as Map); ((map['collection'] as Map)[key]) as Map);
})) }))
: null); : {});
} }
static Map<String, dynamic> toMap(_Library model) { static Map<String, dynamic> toMap(_Library? model) {
if (model == null) {
throw FormatException("Required field [model] cannot be null");
}
return { return {
'id': model.id, 'id': model.id,
'created_at': model.createdAt?.toIso8601String(), 'created_at': model.createdAt?.toIso8601String(),
'updated_at': model.updatedAt?.toIso8601String(), 'updated_at': model.updatedAt?.toIso8601String(),
'collection': model.collection.keys.fold({}, (dynamic map, key) { 'collection': model.collection.keys.fold({}, (map, key) {
return map..[key] = BookSerializer.toMap(model.collection[key]); return (map as Map<dynamic, dynamic>?)
?..[key] = BookSerializer.toMap(model.collection[key]);
}) })
}; };
} }
@ -658,26 +654,25 @@ abstract class BookmarkSerializer {
id: map['id'] as String?, id: map['id'] as String?,
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'].toString())) : 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'].toString())) : DateTime.parse(map['updated_at'].toString()))
: null, : null,
history: map['history'] is Iterable history: map['history'] is Iterable
? (map['history'] as Iterable).cast<int>().toList() ? (map['history'] as Iterable).cast<int>().toList()
: null, : [],
page: map['page'] as int?, page: map['page'] as int?,
comment: map['comment'] as String?); comment: map['comment'] as String?);
} }
static Map<String, dynamic> toMap(_Bookmark model) { static Map<String, dynamic> toMap(_Bookmark? model) {
if (model.page == null) { if (model == null) {
throw FormatException("Missing required field 'page' on Bookmark."); throw FormatException("Required field [model] cannot be null");
} }
return { return {
'id': model.id, 'id': model.id,
'created_at': model.createdAt?.toIso8601String(), 'created_at': model.createdAt?.toIso8601String(),

View file

@ -8,13 +8,13 @@ part of 'game_pad_button.dart';
@generatedSerializable @generatedSerializable
class GamepadButton implements _GamepadButton { class GamepadButton implements _GamepadButton {
const GamepadButton({this.name, this.radius}); GamepadButton({this.name, this.radius});
@override @override
final String? name; String? name;
@override @override
final int? radius; int? radius;
GamepadButton copyWith({String? name, int? radius}) { GamepadButton copyWith({String? name, int? radius}) {
return GamepadButton( return GamepadButton(
@ -45,7 +45,9 @@ class GamepadButton implements _GamepadButton {
@generatedSerializable @generatedSerializable
class Gamepad extends _Gamepad { class Gamepad extends _Gamepad {
Gamepad({List<_GamepadButton>? buttons, Map<String, dynamic>? dynamicMap}) Gamepad(
{List<_GamepadButton>? buttons = const [],
Map<String, dynamic>? dynamicMap})
: buttons = List.unmodifiable(buttons ?? []), : buttons = List.unmodifiable(buttons ?? []),
dynamicMap = Map.unmodifiable(dynamicMap ?? {}); dynamicMap = Map.unmodifiable(dynamicMap ?? {});
@ -120,7 +122,10 @@ class GamepadButtonSerializer extends Codec<GamepadButton, Map> {
name: map['name'] as String?, radius: map['radius'] as int?); name: map['name'] as String?, radius: map['radius'] as int?);
} }
static Map<String, dynamic> toMap(_GamepadButton model) { static Map<String, dynamic> toMap(_GamepadButton? model) {
if (model == null) {
throw FormatException("Required field [model] cannot be null");
}
return {'name': model.name, 'radius': model.radius}; return {'name': model.name, 'radius': model.radius};
} }
} }
@ -161,13 +166,16 @@ class GamepadSerializer extends Codec<Gamepad, Map> {
buttons: map['buttons'] is Iterable buttons: map['buttons'] is Iterable
? List.unmodifiable(((map['buttons'] as Iterable).whereType<Map>()) ? List.unmodifiable(((map['buttons'] as Iterable).whereType<Map>())
.map(GamepadButtonSerializer.fromMap)) .map(GamepadButtonSerializer.fromMap))
: null, : [],
dynamicMap: map['dynamic_map'] is Map dynamicMap: map['dynamic_map'] is Map
? (map['dynamic_map'] as Map).cast<String, dynamic>() ? (map['dynamic_map'] as Map).cast<String, dynamic>()
: null); : {});
} }
static Map<String, dynamic> toMap(_Gamepad model) { static Map<String, dynamic> toMap(_Gamepad? model) {
if (model == null) {
throw FormatException("Required field [model] cannot be null");
}
return { return {
'buttons': 'buttons':
model.buttons?.map((m) => GamepadButtonSerializer.toMap(m)).toList(), model.buttons?.map((m) => GamepadButtonSerializer.toMap(m)).toList(),

View file

@ -1,5 +1,4 @@
import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:angel3_serialize/angel3_serialize.dart';
import 'package:collection/collection.dart';
part 'goat.g.dart'; part 'goat.g.dart';
@serializable @serializable

View file

@ -8,13 +8,13 @@ part of 'goat.dart';
@generatedSerializable @generatedSerializable
class Goat implements _Goat { class Goat implements _Goat {
const Goat({this.integer = 34, this.list = const [34, 35]}); Goat({this.integer = 34, this.list = const [34, 35]});
@override @override
final int integer; int integer;
@override @override
final List<int> list; List<int> list;
Goat copyWith({int? integer, List<int>? list}) { Goat copyWith({int? integer, List<int>? list}) {
return Goat(integer: integer ?? this.integer, list: list ?? this.list); return Goat(integer: integer ?? this.integer, list: list ?? this.list);
@ -77,7 +77,10 @@ class GoatSerializer extends Codec<Goat, Map> {
: const [34, 35]); : const [34, 35]);
} }
static Map<String, dynamic> toMap(_Goat model) { static Map<String, dynamic> toMap(_Goat? model) {
if (model == null) {
throw FormatException("Required field [model] cannot be null");
}
return {'integer': model.integer, 'list': model.list}; return {'integer': model.integer, 'list': model.list};
} }
} }

View file

@ -1,7 +1,4 @@
import 'dart:convert';
import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:angel3_serialize/angel3_serialize.dart';
import 'package:collection/collection.dart';
//import 'package:meta/meta.dart';
part 'has_map.g.dart'; part 'has_map.g.dart';
Map? _fromString(v) => json.decode(v.toString()) as Map?; Map? _fromString(v) => json.decode(v.toString()) as Map?;

View file

@ -8,10 +8,10 @@ part of 'has_map.dart';
@generatedSerializable @generatedSerializable
class HasMap implements _HasMap { class HasMap implements _HasMap {
const HasMap({required this.value}); HasMap({required this.value});
@override @override
final Map<dynamic, dynamic>? value; Map<dynamic, dynamic>? value;
HasMap copyWith({Map<dynamic, dynamic>? value}) { HasMap copyWith({Map<dynamic, dynamic>? value}) {
return HasMap(value: value ?? this.value); return HasMap(value: value ?? this.value);
@ -75,11 +75,10 @@ class HasMapSerializer extends Codec<HasMap, Map> {
return HasMap(value: _fromString(map['value'])); return HasMap(value: _fromString(map['value']));
} }
static Map<String, dynamic> toMap(_HasMap model) { static Map<String, dynamic> toMap(_HasMap? model) {
if (model.value == null) { if (model == null) {
throw FormatException("Missing required field 'value' on HasMap."); throw FormatException("Required field [model] cannot be null");
} }
return {'value': _toString(model.value)}; return {'value': _toString(model.value)};
} }
} }

View file

@ -123,15 +123,10 @@ class AnimalSerializer extends Codec<Animal, Map> {
genus: map['genus'] as String?, species: map['species'] as String?); genus: map['genus'] as String?, species: map['species'] as String?);
} }
static Map<String, dynamic> toMap(_Animal model) { static Map<String, dynamic> toMap(_Animal? model) {
if (model.genus == null) { if (model == null) {
throw FormatException("Missing required field 'genus' on Animal."); throw FormatException("Required field [model] cannot be null");
} }
if (model.species == null) {
throw FormatException("Missing required field 'species' on Animal.");
}
return {'genus': model.genus, 'species': model.species}; return {'genus': model.genus, 'species': model.species};
} }
} }
@ -182,15 +177,10 @@ class BirdSerializer extends Codec<Bird, Map> {
isSparrow: map['is_sparrow'] as bool? ?? false); isSparrow: map['is_sparrow'] as bool? ?? false);
} }
static Map<String, dynamic> toMap(_Bird model) { static Map<String, dynamic> toMap(_Bird? model) {
if (model.genus == null) { if (model == null) {
throw FormatException("Missing required field 'genus' on Bird."); throw FormatException("Required field [model] cannot be null");
} }
if (model.species == null) {
throw FormatException("Missing required field 'species' on Bird.");
}
return { return {
'genus': model.genus, 'genus': model.genus,
'species': model.species, 'species': model.species,

View file

@ -1,7 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:angel3_serialize/angel3_serialize.dart';
import 'package:collection/collection.dart';
part 'with_enum.g.dart'; part 'with_enum.g.dart';
@serializable @serializable

View file

@ -8,16 +8,17 @@ part of 'with_enum.dart';
@generatedSerializable @generatedSerializable
class WithEnum implements _WithEnum { class WithEnum implements _WithEnum {
const WithEnum({this.type = WithEnumType.b, this.finalList, this.imageBytes}); WithEnum(
{this.type = WithEnumType.b, this.finalList = const [], this.imageBytes});
@override @override
final WithEnumType? type; WithEnumType? type;
@override @override
final List<int>? finalList; List<int>? finalList;
@override @override
final Uint8List? imageBytes; Uint8List? imageBytes;
WithEnum copyWith( WithEnum copyWith(
{WithEnumType? type, List<int>? finalList, Uint8List? imageBytes}) { {WithEnumType? type, List<int>? finalList, Uint8List? imageBytes}) {
@ -80,16 +81,16 @@ class WithEnumSerializer extends Codec<WithEnum, Map> {
WithEnumDecoder get decoder => const WithEnumDecoder(); WithEnumDecoder get decoder => const WithEnumDecoder();
static WithEnum fromMap(Map map) { static WithEnum fromMap(Map map) {
return WithEnum( return WithEnum(
type: map['type'] is WithEnumType type: map['type'] is WithEnumType?
? (map['type'] as WithEnumType?) ? (map['type'] as WithEnumType?) ?? WithEnumType.b
: (map['type'] is int : (map['type'] is int
? WithEnumType.values[map['type'] as int] ? WithEnumType?.values[map['type'] as int]
: WithEnumType.b), : WithEnumType.b),
finalList: map['final_list'] is Iterable finalList: map['final_list'] is Iterable
? (map['final_list'] as Iterable).cast<int>().toList() ? (map['final_list'] as Iterable).cast<int>().toList()
: null, : [],
imageBytes: map['image_bytes'] is Uint8List imageBytes: map['image_bytes'] is Uint8List
? (map['image_bytes'] as Uint8List?) ? (map['image_bytes'] as Uint8List)
: (map['image_bytes'] is Iterable<int> : (map['image_bytes'] is Iterable<int>
? Uint8List.fromList( ? Uint8List.fromList(
(map['image_bytes'] as Iterable<int>).toList()) (map['image_bytes'] as Iterable<int>).toList())
@ -99,13 +100,16 @@ class WithEnumSerializer extends Codec<WithEnum, Map> {
: null))); : null)));
} }
static Map<String, dynamic> toMap(_WithEnum model) { static Map<String, dynamic> toMap(_WithEnum? model) {
if (model == null) {
throw FormatException("Required field [model] cannot be null");
}
return { return {
'type': 'type':
model.type == null ? null : WithEnumType.values.indexOf(model.type!), model.type != null ? WithEnumType.values.indexOf(model.type!) : null,
'final_list': model.finalList, 'final_list': model.finalList,
'image_bytes': 'image_bytes':
model.imageBytes == null ? null : base64.encode(model.imageBytes!) model.imageBytes != null ? base64.encode(model.imageBytes!) : null
}; };
} }
} }