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

@ -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);
} }
// 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 []'); 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
}; };
} }
} }