Migrated angel_serialize_generator

This commit is contained in:
thomashii@dukefirehawk.com 2021-05-02 14:02:08 +08:00
parent 1d3d10fb4f
commit ed87d48c96
25 changed files with 346 additions and 340 deletions

View file

@ -29,8 +29,15 @@
* Added range_header and migrated to 3.0.0 (12/12 tests passed) * Added range_header and migrated to 3.0.0 (12/12 tests passed)
* Migrated static to 4.0.0 (1/1 test passed) * Migrated static to 4.0.0 (1/1 test passed)
* Created basic-sdk-2.12.x_nnbd template (1/1 test passed) * Created basic-sdk-2.12.x_nnbd template (1/1 test passed)
* Updated angel_serialize to 4.0.0 (in progress) * Migrated angel_serialize to 4.0.0 (0/0 test passed)
* Updated angel_serialize_generator to 4.0.0 (in progress) * Migrated angel_serialize_generator to 4.0.0 (33/33 tests passed)
* Updated angel_orm to 3.0.0 (in progress)
* Updated angel_migration to 3.0.0 (in progress)
* Updated angel_orm_generator to 3.0.0 (in progress, use a fork of postgres)
* Updated angel_migration_runner to 3.0.0 (in progress)
* Updated angel_orm_test to 1.0.0 (in progress)
* Updated angel_orm_postgres to 2.0.0 (in progress)
* Update orm-sdk-2.12.x boilerplate (in progress)
# 3.0.0 (Non NNBD) # 3.0.0 (Non NNBD)
* Changed Dart SDK requirements for all packages to ">=2.10.0 <3.0.0" * Changed Dart SDK requirements for all packages to ">=2.10.0 <3.0.0"
@ -55,9 +62,9 @@
* Updated production to 2.0.0 (0/0 tests passed) * Updated production to 2.0.0 (0/0 tests passed)
* Updated hot to 3.0.0 (0/0 tests passed) * Updated hot to 3.0.0 (0/0 tests passed)
* Updated static to 3.0.0 (12/12 tests passed) * Updated static to 3.0.0 (12/12 tests passed)
* Update basic-sdk-2.12.x boilerplate * Update basic-sdk-2.12.x boilerplate (1/1 tests passed)
* Updated angel_serialize to 3.0.0 * Updated angel_serialize to 3.0.0 (0/0 tests passed)
* Updated angel_serialize_generator to 3.0.0 * Updated angel_serialize_generator to 3.0.0 (33/33 tests passed)
* Updated angel_orm to 3.0.0 * Updated angel_orm to 3.0.0
* Updated angel_migration to 3.0.0 * Updated angel_migration to 3.0.0
* Updated angel_orm_generator to 3.0.0 (use a fork of postgres) * Updated angel_orm_generator to 3.0.0 (use a fork of postgres)

View file

@ -4,6 +4,6 @@ part 'main.g.dart';
@serializable @serializable
class _Todo { class _Todo {
String text; String? text;
bool completed; bool? completed;
} }

View file

@ -11,12 +11,12 @@ class Todo extends _Todo {
Todo({this.text, this.completed}); Todo({this.text, this.completed});
@override @override
String text; String? text;
@override @override
bool completed; bool? completed;
Todo copyWith({String text, bool completed}) { Todo copyWith({String? text, bool? completed}) {
return Todo( return Todo(
text: text ?? this.text, completed: completed ?? this.completed); text: text ?? this.text, completed: completed ?? this.completed);
} }
@ -69,13 +69,10 @@ class TodoSerializer extends Codec<Todo, Map> {
get decoder => const 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) {
return null;
}
return {'text': model.text, 'completed': model.completed}; return {'text': model.text, 'completed': model.completed};
} }
} }

View file

@ -38,9 +38,9 @@ Builder typescriptDefinitionBuilder(_) {
} }
/// Converts a [DartType] to a [TypeReference]. /// Converts a [DartType] to a [TypeReference].
TypeReference convertTypeReference(DartType t) { TypeReference convertTypeReference(DartType? t) {
return TypeReference((b) { return TypeReference((b) {
b..symbol = t.element?.displayName; b.symbol = t!.element?.displayName;
if (t is InterfaceType) { if (t is InterfaceType) {
b.types.addAll(t.typeArguments.map(convertTypeReference)); b.types.addAll(t.typeArguments.map(convertTypeReference));
@ -50,21 +50,21 @@ TypeReference convertTypeReference(DartType t) {
Expression convertObject(DartObject o) { Expression convertObject(DartObject o) {
if (o.isNull) return literalNull; if (o.isNull) return literalNull;
if (o.toBoolValue() != null) return literalBool(o.toBoolValue()); if (o.toBoolValue() != null) return literalBool(o.toBoolValue()!);
if (o.toIntValue() != null) return literalNum(o.toIntValue()); if (o.toIntValue() != null) return literalNum(o.toIntValue()!);
if (o.toDoubleValue() != null) return literalNum(o.toDoubleValue()); if (o.toDoubleValue() != null) return literalNum(o.toDoubleValue()!);
if (o.toSymbolValue() != null) { if (o.toSymbolValue() != null) {
return CodeExpression(Code('#' + o.toSymbolValue())); return CodeExpression(Code('#' + o.toSymbolValue()!));
} }
if (o.toStringValue() != null) return literalString(o.toStringValue()); if (o.toStringValue() != null) return literalString(o.toStringValue()!);
if (o.toTypeValue() != null) return convertTypeReference(o.toTypeValue()); if (o.toTypeValue() != null) return convertTypeReference(o.toTypeValue());
if (o.toListValue() != null) { if (o.toListValue() != null) {
return literalList(o.toListValue().map(convertObject)); return literalList(o.toListValue()!.map(convertObject));
} }
if (o.toMapValue() != null) { if (o.toMapValue() != null) {
return literalMap(o return literalMap(o
.toMapValue() .toMapValue()!
.map((k, v) => MapEntry(convertObject(k), convertObject(v)))); .map((k, v) => MapEntry(convertObject(k!), convertObject(v!))));
} }
var rev = ConstantReader(o).revive(); var rev = ConstantReader(o).revive();
@ -74,36 +74,48 @@ Expression convertObject(DartObject o) {
rev.namedArguments.map((k, v) => MapEntry(k, convertObject(v)))); rev.namedArguments.map((k, v) => MapEntry(k, convertObject(v))));
} }
String dartObjectToString(DartObject v) { String? dartObjectToString(DartObject v) {
var type = v.type; var type = v.type;
if (v.isNull) return 'null'; if (v.isNull) return 'null';
if (v.toBoolValue() != null) return v.toBoolValue().toString(); if (v.toBoolValue() != null) {
if (v.toIntValue() != null) return v.toIntValue().toString(); return v.toBoolValue().toString();
if (v.toDoubleValue() != null) return v.toDoubleValue().toString(); }
if (v.toSymbolValue() != null) return '#' + v.toSymbolValue(); if (v.toIntValue() != null) {
if (v.toTypeValue() != null) return v.toTypeValue().name; return v.toIntValue().toString();
}
if (v.toDoubleValue() != null) {
return v.toDoubleValue().toString();
}
if (v.toSymbolValue() != null) {
return '#' + v.toSymbolValue()!;
}
if (v.toTypeValue() != null) {
return v.toTypeValue()!.getDisplayString(withNullability: true);
}
if (v.toListValue() != null) { if (v.toListValue() != null) {
return 'const [' + v.toListValue().map(dartObjectToString).join(', ') + ']'; return 'const [' +
v.toListValue()!.map(dartObjectToString).join(', ') +
']';
} }
if (v.toMapValue() != null) { if (v.toMapValue() != null) {
return 'const {' + return 'const {' +
v.toMapValue().entries.map((entry) { v.toMapValue()!.entries.map((entry) {
var k = dartObjectToString(entry.key); var k = dartObjectToString(entry.key!);
var v = dartObjectToString(entry.value); var v = dartObjectToString(entry.value!);
return '$k: $v'; return '$k: $v';
}).join(', ') + }).join(', ') +
'}'; '}';
} }
if (v.toStringValue() != null) { if (v.toStringValue() != null) {
return literalString(v.toStringValue()).accept(DartEmitter()).toString(); return literalString(v.toStringValue()!).accept(DartEmitter()).toString();
} }
if (type is InterfaceType && type.element.isEnum) { if (type is InterfaceType && type.element.isEnum) {
// Find the index of the enum, then find the member. // Find the index of the enum, then find the member.
for (var field in type.element.fields) { for (var field in type.element.fields) {
if (field.isEnumConstant && field.isStatic) { if (field.isEnumConstant && field.isStatic) {
var value = type.element.getField(field.name).computeConstantValue(); var value = type.element.getField(field.name)!.computeConstantValue();
if (value == v) { if (value == v) {
return '${type.element?.displayName}.${field.name}'; return '${type.element.displayName}.${field.name}';
} }
} }
} }
@ -113,14 +125,14 @@ String dartObjectToString(DartObject v) {
} }
/// Determines if a type supports `package:angel_serialize`. /// Determines if a type supports `package:angel_serialize`.
bool isModelClass(DartType t) { bool isModelClass(DartType? t) {
if (t == null) return false; if (t == null) return false;
if (serializableTypeChecker.hasAnnotationOf(t.element)) { if (serializableTypeChecker.hasAnnotationOf(t.element!)) {
return true; return true;
} }
if (generatedSerializableTypeChecker.hasAnnotationOf(t.element)) { if (generatedSerializableTypeChecker.hasAnnotationOf(t.element!)) {
return true; return true;
} }
@ -167,13 +179,13 @@ bool isAssignableToModel(DartType type) =>
const TypeChecker.fromRuntime(Model).isAssignableFromType(type); const TypeChecker.fromRuntime(Model).isAssignableFromType(type);
/// Compute a [String] representation of a [type]. /// Compute a [String] representation of a [type].
String typeToString(DartType type) { String? typeToString(DartType type) {
if (type is InterfaceType) { if (type is InterfaceType) {
if (type.typeArguments.isEmpty) { if (type.typeArguments.isEmpty) {
return type.element?.displayName; return type.element.displayName;
} }
var name = type.element?.displayName ?? ''; var name = type.element.displayName;
return name + '<' + type.typeArguments.map(typeToString).join(', ') + '>'; return name + '<' + type.typeArguments.map(typeToString).join(', ') + '>';
} else { } else {

View file

@ -31,10 +31,14 @@ const TypeChecker generatedSerializableTypeChecker =
final Map<String, BuildContext> _cache = {}; final Map<String, BuildContext> _cache = {};
/// Create a [BuildContext]. /// Create a [BuildContext].
Future<BuildContext> buildContext(ClassElement clazz, ConstantReader annotation, Future<BuildContext?> buildContext(
BuildStep buildStep, Resolver resolver, bool autoSnakeCaseNames, ClassElement clazz,
ConstantReader annotation,
BuildStep buildStep,
Resolver resolver,
bool autoSnakeCaseNames,
{bool heedExclude = true}) async { {bool heedExclude = true}) async {
var id = clazz.location.components.join('-'); var id = clazz.location!.components.join('-');
if (_cache.containsKey(id)) { if (_cache.containsKey(id)) {
return _cache[id]; return _cache[id];
} }
@ -53,11 +57,11 @@ Future<BuildContext> buildContext(ClassElement clazz, ConstantReader annotation,
annotation.peek('includeAnnotations')?.listValue ?? <DartObject>[], annotation.peek('includeAnnotations')?.listValue ?? <DartObject>[],
); );
// var lib = await resolver.libraryFor(buildStep.inputId); // var lib = await resolver.libraryFor(buildStep.inputId);
List<String> fieldNames = []; var fieldNames = <String>[];
var fields = <FieldElement>[]; var fields = <FieldElement>[];
// Crawl for classes from parent classes. // Crawl for classes from parent classes.
void crawlClass(InterfaceType t) { void crawlClass(InterfaceType? t) {
while (t != null) { while (t != null) {
fields.insertAll(0, t.element.fields); fields.insertAll(0, t.element.fields);
t.interfaces.forEach(crawlClass); t.interfaces.forEach(crawlClass);
@ -74,8 +78,8 @@ Future<BuildContext> buildContext(ClassElement clazz, ConstantReader annotation,
} }
if (field.getter != null && if (field.getter != null &&
(field.setter != null || field.getter.isAbstract)) { (field.setter != null || field.getter!.isAbstract)) {
var el = field.setter == null ? field.getter : field; var el = field.setter == null ? field.getter! : field;
fieldNames.add(field.name); fieldNames.add(field.name);
// Check for @SerializableField // Check for @SerializableField
@ -100,11 +104,11 @@ Future<BuildContext> buildContext(ClassElement clazz, ConstantReader annotation,
ctx.requiredFields[field.name] = reason; ctx.requiredFields[field.name] = reason;
} }
if (sField.exclude) { if (sField.exclude!) {
// ignore: deprecated_member_use // ignore: deprecated_member_use
ctx.excluded[field.name] = Exclude( ctx.excluded[field.name] = Exclude(
canSerialize: sField.canSerialize, canSerialize: sField.canSerialize!,
canDeserialize: sField.canDeserialize, canDeserialize: sField.canDeserialize!,
); );
} }
} }
@ -156,17 +160,17 @@ Future<BuildContext> buildContext(ClassElement clazz, ConstantReader annotation,
// Check for alias // Check for alias
// ignore: deprecated_member_use // ignore: deprecated_member_use
Alias alias; Alias? alias;
var aliasAnn = aliasTypeChecker.firstAnnotationOf(el); var aliasAnn = aliasTypeChecker.firstAnnotationOf(el);
if (aliasAnn != null) { if (aliasAnn != null) {
// ignore: deprecated_member_use // ignore: deprecated_member_use
alias = Alias(aliasAnn.getField('name').toStringValue()); alias = Alias(aliasAnn.getField('name')!.toStringValue()!);
foundNone = false; foundNone = false;
} }
if (alias?.name?.isNotEmpty == true) { if (alias?.name.isNotEmpty == true) {
ctx.aliases[field.name] = alias.name; ctx.aliases[field.name] = alias!.name;
} else if (autoSnakeCaseNames != false) { } else if (autoSnakeCaseNames != false) {
ctx.aliases[field.name] = ReCase(field.name).snakeCase; ctx.aliases[field.name] = ReCase(field.name).snakeCase;
} }
@ -234,7 +238,7 @@ Future<BuildContext> buildContext(ClassElement clazz, ConstantReader annotation,
// } // }
// Get constructor params, if any // Get constructor params, if any
ctx.constructorParameters.addAll(clazz.unnamedConstructor.parameters); ctx.constructorParameters.addAll(clazz.unnamedConstructor!.parameters);
return ctx; return ctx;
} }

View file

@ -8,17 +8,17 @@ import 'package:source_gen/source_gen.dart';
/// A base context for building serializable classes. /// A base context for building serializable classes.
class BuildContext { class BuildContext {
ReCase _modelClassNameRecase; ReCase? _modelClassNameRecase;
TypeReference _modelClassType; TypeReference? _modelClassType;
/// A map of fields that are absolutely required, and error messages for when they are absent. /// A map of fields that are absolutely required, and error messages for when they are absent.
final Map<String, String> requiredFields = {}; final Map<String, String> requiredFields = {};
/// A map of field names to resolved names from `@Alias()` declarations. /// A map of field names to resolved names from `@Alias()` declarations.
final Map<String, String> aliases = {}; final Map<String, String?> aliases = {};
/// A map of field names to their default values. /// A map of field names to their default values.
final Map<String, DartObject> defaults = {}; final Map<String, DartObject?> defaults = {};
/// A map of fields to their related information. /// A map of fields to their related information.
final Map<String, SerializableFieldMirror> fieldInfo = {}; final Map<String, SerializableFieldMirror> fieldInfo = {};
@ -30,9 +30,9 @@ class BuildContext {
/// A map of "synthetic" fields, i.e. `id` and `created_at` injected automatically. /// A map of "synthetic" fields, i.e. `id` and `created_at` injected automatically.
final Map<String, bool> shimmed = {}; final Map<String, bool> shimmed = {};
final bool autoIdAndDateFields, autoSnakeCaseNames; final bool? autoIdAndDateFields, autoSnakeCaseNames;
final String originalClassName, sourceFilename; final String? originalClassName, sourceFilename;
/// The fields declared on the original class. /// The fields declared on the original class.
final List<FieldElement> fields = []; final List<FieldElement> fields = [];
@ -57,13 +57,13 @@ class BuildContext {
this.includeAnnotations = const <DartObject>[]}); this.includeAnnotations = const <DartObject>[]});
/// The name of the generated class. /// The name of the generated class.
String get modelClassName => originalClassName.startsWith('_') String? get modelClassName => originalClassName!.startsWith('_')
? originalClassName.substring(1) ? originalClassName!.substring(1)
: originalClassName; : originalClassName;
/// A [ReCase] instance reflecting on the [modelClassName]. /// A [ReCase] instance reflecting on the [modelClassName].
ReCase get modelClassNameRecase => ReCase get modelClassNameRecase =>
_modelClassNameRecase ??= ReCase(modelClassName); _modelClassNameRecase ??= ReCase(modelClassName!);
TypeReference get modelClassType => TypeReference get modelClassType =>
_modelClassType ??= TypeReference((b) => b.symbol = modelClassName); _modelClassType ??= TypeReference((b) => b.symbol = modelClassName);
@ -77,7 +77,7 @@ class BuildContext {
} }
/// Get the aliased name (if one is defined) for a field. /// Get the aliased name (if one is defined) for a field.
String resolveFieldName(String name) => String? resolveFieldName(String name) =>
aliases.containsKey(name) ? aliases[name] : name; aliases.containsKey(name) ? aliases[name] : name;
/// Finds the type that the field [name] should serialize to. /// Finds the type that the field [name] should serialize to.
@ -88,12 +88,12 @@ class BuildContext {
} }
class SerializableFieldMirror { class SerializableFieldMirror {
final String alias; final String? alias;
final DartObject defaultValue; final DartObject? defaultValue;
final Symbol serializer, deserializer; final Symbol? serializer, deserializer;
final String errorMessage; final String? errorMessage;
final bool isNullable, canDeserialize, canSerialize, exclude; final bool? isNullable, canDeserialize, canSerialize, exclude;
final DartType serializesTo; final DartType? serializesTo;
SerializableFieldMirror( SerializableFieldMirror(
{this.alias, {this.alias,

View file

@ -23,10 +23,10 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
/// Generate an extended model class. /// Generate an extended model class.
void generateClass( void generateClass(
BuildContext ctx, LibraryBuilder file, ConstantReader annotation) { BuildContext? ctx, LibraryBuilder file, ConstantReader annotation) {
file.body.add(Class((clazz) { file.body.add(Class((clazz) {
clazz clazz
..name = ctx.modelClassNameRecase.pascalCase ..name = ctx!.modelClassNameRecase.pascalCase
..annotations.add(refer('generatedSerializable')); ..annotations.add(refer('generatedSerializable'));
for (var ann in ctx.includeAnnotations) { for (var ann in ctx.includeAnnotations) {
@ -57,7 +57,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
for (var el in [field.getter, field]) { for (var el in [field.getter, field]) {
if (el?.documentationComment != null) { if (el?.documentationComment != null) {
b.docs.addAll(el.documentationComment.split('\n')); b.docs.addAll(el!.documentationComment!.split('\n'));
} }
} }
})); }));
@ -92,10 +92,10 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
/// Generate a constructor with named parameters. /// Generate a constructor with named parameters.
void generateConstructor( void generateConstructor(
BuildContext ctx, ClassBuilder clazz, LibraryBuilder file) { BuildContext? ctx, ClassBuilder clazz, LibraryBuilder file) {
clazz.constructors.add(Constructor((constructor) { clazz.constructors.add(Constructor((constructor) {
// Add all `super` params // Add all `super` params
constructor.constant = (ctx.clazz.unnamedConstructor?.isConst == true || constructor.constant = (ctx!.clazz.unnamedConstructor?.isConst == true ||
shouldBeConstant(ctx)) && shouldBeConstant(ctx)) &&
ctx.fields.every((f) { ctx.fields.every((f) {
return f.setter == null && f is! ShimFieldImpl; return f.setter == null && f is! ShimFieldImpl;
@ -113,7 +113,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
.isAssignableFromType(field.type) .isAssignableFromType(field.type)
? 'List' ? 'List'
: 'Map'; : 'Map';
var 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) {
@ -136,7 +136,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
var existingDefault = ctx.defaults[field.name]; var existingDefault = ctx.defaults[field.name];
if (existingDefault != null) { if (existingDefault != null) {
b.defaultTo = Code(dartObjectToString(existingDefault)); b.defaultTo = Code(dartObjectToString(existingDefault)!);
} }
if (!isListOrMapType(field.type)) { if (!isListOrMapType(field.type)) {
@ -164,11 +164,11 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
/// Generate a `copyWith` method. /// Generate a `copyWith` method.
void generateCopyWithMethod( void generateCopyWithMethod(
BuildContext ctx, ClassBuilder clazz, LibraryBuilder file) { BuildContext? ctx, ClassBuilder clazz, LibraryBuilder file) {
clazz.methods.add(Method((method) { clazz.methods.add(Method((method) {
method method
..name = 'copyWith' ..name = 'copyWith'
..returns = ctx.modelClassType; ..returns = ctx!.modelClassType;
// Add all `super` params // Add all `super` params
if (ctx.constructorParameters.isNotEmpty) { if (ctx.constructorParameters.isNotEmpty) {
@ -204,12 +204,12 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
})); }));
} }
static String generateEquality(DartType type, [bool nullable = false]) { static String? generateEquality(DartType type, [bool nullable = false]) {
if (type is InterfaceType) { if (type is InterfaceType) {
if (const TypeChecker.fromRuntime(List).isAssignableFromType(type)) { if (const TypeChecker.fromRuntime(List).isAssignableFromType(type)) {
if (type.typeArguments.length == 1) { if (type.typeArguments.length == 1) {
var eq = generateEquality(type.typeArguments[0]); var eq = generateEquality(type.typeArguments[0]);
return 'ListEquality<${type.typeArguments[0].element.name}>($eq)'; return 'ListEquality<${type.typeArguments[0].element!.name}>($eq)';
} else { } else {
return 'ListEquality()'; return 'ListEquality()';
} }
@ -218,7 +218,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
if (type.typeArguments.length == 2) { if (type.typeArguments.length == 2) {
var keq = generateEquality(type.typeArguments[0]), var keq = generateEquality(type.typeArguments[0]),
veq = generateEquality(type.typeArguments[1]); veq = generateEquality(type.typeArguments[1]);
return 'MapEquality<${type.typeArguments[0].element.name}, ${type.typeArguments[1].element.name}>(keys: $keq, values: $veq)'; return 'MapEquality<${type.typeArguments[0].element!.name}, ${type.typeArguments[1].element!.name}>(keys: $keq, values: $veq)';
} else { } else {
return 'MapEquality()'; return 'MapEquality()';
} }
@ -239,7 +239,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
return (a, b) => '$eq.equals($a, $b)'; return (a, b) => '$eq.equals($a, $b)';
} }
void generateHashCode(BuildContext ctx, ClassBuilder clazz) { void generateHashCode(BuildContext? ctx, ClassBuilder clazz) {
clazz clazz
..methods.add(Method((method) { ..methods.add(Method((method) {
method method
@ -248,20 +248,20 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
..returns = refer('int') ..returns = refer('int')
..annotations.add(refer('override')) ..annotations.add(refer('override'))
..body = refer('hashObjects') ..body = refer('hashObjects')
.call([literalList(ctx.fields.map((f) => refer(f.name)))]) .call([literalList(ctx!.fields.map((f) => refer(f.name)))])
.returned .returned
.statement; .statement;
})); }));
} }
void generateToString(BuildContext ctx, ClassBuilder clazz) { void generateToString(BuildContext? ctx, ClassBuilder clazz) {
clazz.methods.add(Method((b) { clazz.methods.add(Method((b) {
b b
..name = 'toString' ..name = 'toString'
..returns = refer('String') ..returns = refer('String')
..annotations.add(refer('override')) ..annotations.add(refer('override'))
..body = Block((b) { ..body = Block((b) {
var buf = StringBuffer('\"${ctx.modelClassName}('); var buf = StringBuffer('\"${ctx!.modelClassName}(');
var i = 0; var i = 0;
for (var field in ctx.fields) { for (var field in ctx.fields) {
if (i++ > 0) buf.write(', '); if (i++ > 0) buf.write(', ');
@ -274,14 +274,14 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
} }
void generateEqualsOperator( void generateEqualsOperator(
BuildContext ctx, ClassBuilder clazz, LibraryBuilder file) { BuildContext? ctx, ClassBuilder clazz, LibraryBuilder file) {
clazz.methods.add(Method((method) { clazz.methods.add(Method((method) {
method method
..name = 'operator ==' ..name = 'operator =='
..returns = Reference('bool') ..returns = Reference('bool')
..requiredParameters.add(Parameter((b) => b.name = 'other')); ..requiredParameters.add(Parameter((b) => b.name = 'other'));
var buf = ['other is ${ctx.originalClassName}']; var buf = ['other is ${ctx!.originalClassName}'];
buf.addAll(ctx.fields.map((f) { buf.addAll(ctx.fields.map((f) {
return generateComparator(f.type)('other.${f.name}', f.name); return generateComparator(f.type)('other.${f.name}', f.name);

View file

@ -6,7 +6,7 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
const SerializerGenerator({this.autoSnakeCaseNames = true}); const SerializerGenerator({this.autoSnakeCaseNames = true});
@override @override
Future<String> generateForAnnotatedElement( Future<String?> generateForAnnotatedElement(
Element element, ConstantReader annotation, BuildStep buildStep) async { Element element, ConstantReader annotation, BuildStep buildStep) async {
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.';
@ -25,7 +25,7 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
} }
var lib = Library((b) { var lib = Library((b) {
generateClass(serializers.map((s) => s.toIntValue()).toList(), ctx, b); generateClass(serializers.map((s) => s.toIntValue()).toList(), ctx!, b);
generateFieldsClass(ctx, b); generateFieldsClass(ctx, b);
}); });
@ -35,7 +35,7 @@ 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) {
// Generate canonical codecs, etc. // Generate canonical codecs, etc.
var pascal = ctx.modelClassNameRecase.pascalCase, var pascal = ctx.modelClassNameRecase.pascalCase,
camel = ctx.modelClassNameRecase.camelCase; camel = ctx.modelClassNameRecase.camelCase;
@ -105,7 +105,7 @@ class ${pascal}Decoder extends Converter<Map, ${pascal}> {
..requiredParameters.add(Parameter((b) { ..requiredParameters.add(Parameter((b) {
b b
..name = 'model' ..name = 'model'
..type = refer(ctx.originalClassName); ..type = refer(ctx.originalClassName!);
})); }));
var buf = StringBuffer(); var buf = StringBuffer();
@ -143,7 +143,7 @@ class ${pascal}Decoder extends Converter<Map, ${pascal}> {
} }
if (ctx.fieldInfo[field.name]?.serializer != null) { if (ctx.fieldInfo[field.name]?.serializer != null) {
var name = MirrorSystem.getName(ctx.fieldInfo[field.name].serializer); var name = MirrorSystem.getName(ctx.fieldInfo[field.name]!.serializer!);
serializedRepresentation = '$name(model.${field.name})'; serializedRepresentation = '$name(model.${field.name})';
} }
@ -154,12 +154,12 @@ class ${pascal}Decoder extends Converter<Map, ${pascal}> {
// Serialize model classes via `XSerializer.toMap` // Serialize model classes via `XSerializer.toMap`
else if (isModelClass(type)) { else if (isModelClass(type)) {
var rc = ReCase(type.name); var rc = ReCase(type.name!);
serializedRepresentation = serializedRepresentation =
'${serializerToMap(rc, 'model.${field.name}')}'; '${serializerToMap(rc, 'model.${field.name}')}';
} else if (type is InterfaceType) { } else if (type is InterfaceType) {
if (isListOfModelType(type)) { if (isListOfModelType(type)) {
var name = type.typeArguments[0].name; var name = type.typeArguments[0].name!;
if (name.startsWith('_')) name = name.substring(1); if (name.startsWith('_')) name = name.substring(1);
var rc = ReCase(name); var rc = ReCase(name);
var m = serializerToMap(rc, 'm'); var m = serializerToMap(rc, 'm');
@ -168,7 +168,7 @@ class ${pascal}Decoder extends Converter<Map, ${pascal}> {
?.map((m) => $m) ?.map((m) => $m)
?.toList()'''; ?.toList()''';
} else if (isMapToModelType(type)) { } else if (isMapToModelType(type)) {
var rc = ReCase(type.typeArguments[1].name); var rc = ReCase(type.typeArguments[1].name!);
serializedRepresentation = serializedRepresentation =
'''model.${field.name}.keys?.fold({}, (map, key) { '''model.${field.name}.keys?.fold({}, (map, key) {
return map..[key] = return map..[key] =
@ -255,7 +255,7 @@ class ${pascal}Decoder extends Converter<Map, ${pascal}> {
String deserializedRepresentation = String deserializedRepresentation =
"map['$alias'] as ${typeToString(type)}"; "map['$alias'] as ${typeToString(type)}";
var defaultValue = 'null'; String? defaultValue = 'null';
var existingDefault = ctx.defaults[field.name]; var existingDefault = ctx.defaults[field.name];
if (existingDefault != null) { if (existingDefault != null) {
@ -266,7 +266,7 @@ class ${pascal}Decoder extends Converter<Map, ${pascal}> {
if (ctx.fieldInfo[field.name]?.deserializer != null) { if (ctx.fieldInfo[field.name]?.deserializer != null) {
var name = var name =
MirrorSystem.getName(ctx.fieldInfo[field.name].deserializer); MirrorSystem.getName(ctx.fieldInfo[field.name]!.deserializer!);
deserializedRepresentation = "$name(map['$alias'])"; deserializedRepresentation = "$name(map['$alias'])";
} else if (dateTimeTypeChecker.isAssignableFromType(type)) { } else if (dateTimeTypeChecker.isAssignableFromType(type)) {
deserializedRepresentation = "map['$alias'] != null ? " deserializedRepresentation = "map['$alias'] != null ? "
@ -276,20 +276,20 @@ class ${pascal}Decoder extends Converter<Map, ${pascal}> {
// Serialize model classes via `XSerializer.toMap` // Serialize model classes via `XSerializer.toMap`
else if (isModelClass(type)) { else if (isModelClass(type)) {
var rc = ReCase(type.name); var rc = ReCase(type.name!);
deserializedRepresentation = "map['$alias'] != null" deserializedRepresentation = "map['$alias'] != null"
" ? ${rc.pascalCase}Serializer.fromMap(map['$alias'] as Map)" " ? ${rc.pascalCase}Serializer.fromMap(map['$alias'] as Map)"
" : $defaultValue"; " : $defaultValue";
} else if (type is InterfaceType) { } else if (type is InterfaceType) {
if (isListOfModelType(type)) { if (isListOfModelType(type)) {
var rc = ReCase(type.typeArguments[0].name); var rc = ReCase(type.typeArguments[0].name!);
deserializedRepresentation = "map['$alias'] is Iterable" deserializedRepresentation = "map['$alias'] is Iterable"
" ? List.unmodifiable(((map['$alias'] as Iterable)" " ? List.unmodifiable(((map['$alias'] as Iterable)"
".whereType<Map>())" ".whereType<Map>())"
".map(${rc.pascalCase}Serializer.fromMap))" ".map(${rc.pascalCase}Serializer.fromMap))"
" : $defaultValue"; " : $defaultValue";
} else if (isMapToModelType(type)) { } else if (isMapToModelType(type)) {
var rc = ReCase(type.typeArguments[1].name); var rc = ReCase(type.typeArguments[1].name!);
deserializedRepresentation = ''' deserializedRepresentation = '''
map['$alias'] is Map map['$alias'] is Map
? Map.unmodifiable((map['$alias'] as Map).keys.fold({}, (out, key) { ? Map.unmodifiable((map['$alias'] as Map).keys.fold({}, (out, key) {
@ -359,11 +359,11 @@ class ${pascal}Decoder extends Converter<Map, ${pascal}> {
})); }));
} }
void generateFieldsClass(BuildContext ctx, LibraryBuilder file) { void generateFieldsClass(BuildContext? ctx, LibraryBuilder file) {
file.body.add(Class((clazz) { file.body.add(Class((clazz) {
clazz clazz
..abstract = true ..abstract = true
..name = '${ctx.modelClassNameRecase.pascalCase}Fields'; ..name = '${ctx!.modelClassNameRecase.pascalCase}Fields';
clazz.fields.add(Field((b) { clazz.fields.add(Field((b) {
b b

View file

@ -13,13 +13,13 @@ class TypeScriptDefinitionBuilder implements Builder {
} }
Future<String> compileToTypeScriptType( Future<String> compileToTypeScriptType(
BuildContext ctx, BuildContext? ctx,
String fieldName, String fieldName,
DartType type, DartType type,
List<String> refs, List<String> refs,
List<CodeBuffer> ext, List<CodeBuffer> ext,
BuildStep buildStep) async { BuildStep buildStep) async {
String typeScriptType = 'any'; var typeScriptType = 'any';
var types = const { var types = const {
num: 'number', num: 'number',
@ -58,7 +58,7 @@ class TypeScriptDefinitionBuilder implements Builder {
);*/ );*/
typeScriptType = typeScriptType =
ctx.modelClassNameRecase.pascalCase + ReCase(fieldName).pascalCase; ctx!.modelClassNameRecase.pascalCase + ReCase(fieldName).pascalCase;
ext.add(CodeBuffer() ext.add(CodeBuffer()
..writeln('interface $typeScriptType {') ..writeln('interface $typeScriptType {')
@ -81,10 +81,11 @@ class TypeScriptDefinitionBuilder implements Builder {
if (!p.equals(sourcePath, targetPath)) { if (!p.equals(sourcePath, targetPath)) {
var relative = p.relative(targetPath, from: sourcePath); var relative = p.relative(targetPath, from: sourcePath);
String ref; String? ref;
if (type.element.source.uri.scheme == 'asset') { if (type.element.source.uri.scheme == 'asset') {
var id = AssetId.resolve(type.element.source.uri.toString()); var id =
AssetId.resolve(Uri.parse(type.element.source.uri.toString()));
if (id.package != buildStep.inputId.package) { if (id.package != buildStep.inputId.package) {
ref = '/// <reference types="${id.package}" />'; ref = '/// <reference types="${id.package}" />';
} }
@ -103,14 +104,14 @@ class TypeScriptDefinitionBuilder implements Builder {
if (!refs.contains(ref)) refs.add(ref); if (!refs.contains(ref)) refs.add(ref);
} }
var ctx = await buildContext( var ctx = await (buildContext(
type.element, type.element,
ConstantReader( ConstantReader(
serializableTypeChecker.firstAnnotationOf(type.element)), serializableTypeChecker.firstAnnotationOf(type.element)),
buildStep, buildStep,
buildStep.resolver, buildStep.resolver,
autoSnakeCaseNames, autoSnakeCaseNames,
); ) as FutureOr<BuildContext>);
typeScriptType = ctx.modelClassNameRecase.pascalCase; typeScriptType = ctx.modelClassNameRecase.pascalCase;
} }
} }
@ -120,7 +121,7 @@ class TypeScriptDefinitionBuilder implements Builder {
@override @override
Future build(BuildStep buildStep) async { Future build(BuildStep buildStep) async {
var contexts = <BuildContext>[]; var contexts = <BuildContext?>[];
LibraryReader lib; LibraryReader lib;
try { try {
@ -159,7 +160,7 @@ class TypeScriptDefinitionBuilder implements Builder {
element.element as ClassElement, element.element as ClassElement,
element.annotation, element.annotation,
buildStep, buildStep,
await buildStep.resolver, buildStep.resolver,
autoSnakeCaseNames != false)); autoSnakeCaseNames != false));
} }
@ -181,7 +182,7 @@ class TypeScriptDefinitionBuilder implements Builder {
for (var ctx in contexts) { for (var ctx in contexts) {
// interface Bar { ... } // interface Bar { ... }
buf buf
..writeln('interface ${ctx.modelClassNameRecase.pascalCase} {') ..writeln('interface ${ctx!.modelClassNameRecase.pascalCase} {')
..indent(); ..indent();
var ext = <CodeBuffer>[]; var ext = <CodeBuffer>[];
@ -195,7 +196,11 @@ class TypeScriptDefinitionBuilder implements Builder {
ctx.resolveSerializedFieldType(field.name), refs, ext, buildStep); ctx.resolveSerializedFieldType(field.name), refs, ext, buildStep);
// foo: string; // foo: string;
if (!ctx.requiredFields.containsKey(field.name)) alias += '?'; if (!ctx.requiredFields.containsKey(field.name)) {
if (alias != null) {
alias += '?';
}
}
buf.writeln('$alias: $typeScriptType;'); buf.writeln('$alias: $typeScriptType;');
} }

View file

@ -4,33 +4,37 @@ description: Model serialization generators, designed for use with Angel. Combin
homepage: https://github.com/dukefirehawk/angel homepage: https://github.com/dukefirehawk/angel
publish_to: none publish_to: none
environment: environment:
sdk: '>=2.7.0 <3.0.0' sdk: '>=2.12.0 <3.0.0'
dependencies: dependencies:
analyzer: ">=0.27.1 <2.0.0" analyzer: ^1.5.0
angel_model: angel_model:
git: git:
url: https://github.com/dukefirehawk/angel.git url: https://github.com/dukefirehawk/angel.git
ref: sdk-2.12.x ref: sdk-2.12.x_nnbd
path: packages/model path: packages/model
angel_serialize: angel_serialize:
git: git:
url: https://github.com/dukefirehawk/angel.git url: https://github.com/dukefirehawk/angel.git
ref: sdk-2.12.x ref: sdk-2.12.x_nnbd
path: packages/serialize/angel_serialize path: packages/serialize/angel_serialize
build: ">=0.12.0 <2.0.0" code_buffer:
build_config: ">=0.3.0 <2.0.0" git:
code_buffer: ^1.0.0 url: https://github.com/dukefirehawk/angel.git
code_builder: ^3.0.0 ref: sdk-2.12.x_nnbd
path: packages/code_buffer
build: ^2.0.1
build_config: ^1.0.0
code_builder: ^4.0.0
meta: ^1.3.0 meta: ^1.3.0
path: ^1.8.0 path: ^1.8.0
recase: ^3.0.1 recase: ^4.0.0
source_gen: ^0.9.0 source_gen: ^1.0.0
quiver: ^2.1.5 quiver: ^3.0.1
dev_dependencies: dev_dependencies:
build_runner: ^1.11.5 build_runner: ^2.0.1
collection: ^1.15.0 collection: ^1.15.0
pedantic: ^1.11.0 pedantic: ^1.11.0
test: ^1.16.5 test: ^1.17.3
# dependency_overrides: # dependency_overrides:
# angel_serialize: # angel_serialize:
# path: ../angel_serialize # path: ../angel_serialize

View file

@ -21,8 +21,8 @@ main() {
age: 51, age: 51,
books: [deathlyHallows], books: [deathlyHallows],
newestBook: deathlyHallows); newestBook: deathlyHallows);
var serializedJkRowling = authorSerializer.encode(jkRowling); Map<dynamic, dynamic> serializedJkRowling = authorSerializer.encode(jkRowling);
var deathlyHallowsMap = bookSerializer.encode(deathlyHallows); Map<dynamic, dynamic>? deathlyHallowsMap = bookSerializer.encode(deathlyHallows);
print('J.K. Rowling: $jkRowling'); print('J.K. Rowling: $jkRowling');
var library = Library(collection: {deathlyHallowsIsbn: deathlyHallows}); var library = Library(collection: {deathlyHallowsIsbn: deathlyHallows});
@ -31,30 +31,30 @@ 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', () {
@ -63,7 +63,7 @@ main() {
test('heeds canDeserialize', () { test('heeds canDeserialize', () {
var map = Map.from(serializedJkRowling)..['obscured'] = 'foo'; var map = Map.from(serializedJkRowling)..['obscured'] = 'foo';
var author = authorSerializer.decode(map); Author author = authorSerializer.decode(map);
expect(author.obscured, 'foo'); expect(author.obscured, 'foo');
}); });
@ -112,7 +112,7 @@ 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);
@ -126,7 +126,7 @@ main() {
var author = AuthorSerializer.fromMap(serializedJkRowling); var author = AuthorSerializer.fromMap(serializedJkRowling);
test('nested @serializable class is deserialized', () { test('nested @serializable class is deserialized', () {
var newestBook = author.newestBook; var newestBook = author.newestBook!;
expect(newestBook, isNotNull); expect(newestBook, isNotNull);
expect(newestBook.id, deathlyHallows.id); expect(newestBook.id, deathlyHallows.id);
expect(newestBook.pageCount, deathlyHallows.pageCount); expect(newestBook.pageCount, deathlyHallows.pageCount);
@ -148,7 +148,7 @@ main() {
var lib = LibrarySerializer.fromMap(serializedLibrary); var lib = LibrarySerializer.fromMap(serializedLibrary);
expect(lib.collection, allOf(isNotEmpty, hasLength(1))); expect(lib.collection, allOf(isNotEmpty, hasLength(1)));
expect(lib.collection.keys.first, deathlyHallowsIsbn); expect(lib.collection.keys.first, deathlyHallowsIsbn);
var book = lib.collection[deathlyHallowsIsbn]; var book = lib.collection[deathlyHallowsIsbn]!;
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

@ -14,38 +14,38 @@ part 'book.g.dart';
], ],
) )
abstract class _Book extends Model { abstract class _Book extends Model {
String author, title, description; String? author, title, description;
/// The number of pages the book has. /// The number of pages the book has.
int pageCount; int? pageCount;
List<double> notModels; List<double>? notModels;
@SerializableField(alias: 'camelCase', isNullable: true) @SerializableField(alias: 'camelCase', isNullable: true)
String camelCaseString; String? camelCaseString;
} }
@Serializable(serializers: Serializers.all) @Serializable(serializers: Serializers.all)
abstract class _Author extends Model { abstract class _Author extends Model {
@SerializableField(isNullable: false) @SerializableField(isNullable: false)
String get name; String? get name;
String get customMethod => 'hey!'; String get customMethod => 'hey!';
@SerializableField( @SerializableField(
isNullable: false, errorMessage: 'Custom message for missing `age`') isNullable: false, errorMessage: 'Custom message for missing `age`')
int get age; int? get age;
List<_Book> get books; List<_Book> get books;
/// The newest book. /// The newest book.
_Book get newestBook; _Book? get newestBook;
@SerializableField(exclude: true, isNullable: true) @SerializableField(exclude: true, isNullable: true)
String get secret; String? get secret;
@SerializableField(exclude: true, canDeserialize: true, isNullable: true) @SerializableField(exclude: true, canDeserialize: true, isNullable: true)
String get obscured; String? get obscured;
} }
@Serializable(serializers: Serializers.all) @Serializable(serializers: Serializers.all)
@ -61,9 +61,9 @@ abstract class _Bookmark extends Model {
List<int> get history; List<int> get history;
@SerializableField(isNullable: false) @SerializableField(isNullable: false)
int get page; int? get page;
String get comment; String? get comment;
_Bookmark(this.book); _Bookmark(this.book);
} }

View file

@ -18,51 +18,51 @@ class Book extends _Book {
this.title, this.title,
this.description, this.description,
this.pageCount, this.pageCount,
List<double> notModels, List<double>? notModels,
this.camelCaseString}) this.camelCaseString})
: this.notModels = List.unmodifiable(notModels ?? []); : this.notModels = List.unmodifiable(notModels ?? []);
/// A unique identifier corresponding to this item. /// A unique identifier corresponding to this item.
@override @override
String id; String? id;
/// The time at which this item was created. /// The time at which this item was created.
@override @override
DateTime createdAt; DateTime? createdAt;
/// The last time at which this item was updated. /// The last time at which this item was updated.
@override @override
DateTime updatedAt; DateTime? updatedAt;
@override @override
String author; String? author;
@override @override
String title; String? title;
@override @override
String description; String? description;
/// The number of pages the book has. /// The number of pages the book has.
@override @override
int pageCount; int? pageCount;
@override @override
List<double> notModels; List<double>? notModels;
@override @override
String camelCaseString; String? camelCaseString;
Book copyWith( Book copyWith(
{String id, {String? id,
DateTime createdAt, DateTime? createdAt,
DateTime updatedAt, DateTime? updatedAt,
String author, String? author,
String title, String? title,
String description, String? description,
int pageCount, int? pageCount,
List<double> notModels, List<double>? notModels,
String camelCaseString}) { String? camelCaseString}) {
return Book( return Book(
id: id ?? this.id, id: id ?? this.id,
createdAt: createdAt ?? this.createdAt, createdAt: createdAt ?? this.createdAt,
@ -106,10 +106,10 @@ class Book extends _Book {
@override @override
String toString() { String toString() {
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);
} }
} }
@ -120,9 +120,9 @@ class Author extends _Author {
{this.id, {this.id,
this.createdAt, this.createdAt,
this.updatedAt, this.updatedAt,
@required this.name, required this.name,
@required this.age, required this.age,
List<_Book> books, List<_Book>? books,
this.newestBook, this.newestBook,
this.secret, this.secret,
this.obscured}) this.obscured})
@ -130,45 +130,45 @@ class Author extends _Author {
/// A unique identifier corresponding to this item. /// A unique identifier corresponding to this item.
@override @override
String id; String? id;
/// The time at which this item was created. /// The time at which this item was created.
@override @override
DateTime createdAt; DateTime? createdAt;
/// The last time at which this item was updated. /// The last time at which this item was updated.
@override @override
DateTime updatedAt; DateTime? updatedAt;
@override @override
final String name; final String? name;
@override @override
final int age; final int? age;
@override @override
final List<_Book> books; final List<_Book> books;
/// The newest book. /// The newest book.
@override @override
final _Book newestBook; final _Book? newestBook;
@override @override
final String secret; final String? secret;
@override @override
final String obscured; final String? obscured;
Author copyWith( Author copyWith(
{String id, {String? id,
DateTime createdAt, DateTime? createdAt,
DateTime updatedAt, DateTime? updatedAt,
String name, String? name,
int age, int? age,
List<_Book> books, List<_Book>? books,
_Book newestBook, _Book? newestBook,
String secret, String? secret,
String obscured}) { String? obscured}) {
return Author( return Author(
id: id ?? this.id, id: id ?? this.id,
createdAt: createdAt ?? this.createdAt, createdAt: createdAt ?? this.createdAt,
@ -212,7 +212,7 @@ class Author extends _Author {
@override @override
String toString() { String toString() {
return "Author(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, name=$name, age=$age, books=$books, newestBook=$newestBook, secret=$secret, obscured=$obscured)"; return 'Author(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, name=$name, age=$age, books=$books, newestBook=$newestBook, secret=$secret, obscured=$obscured)';
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -223,29 +223,29 @@ 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, this.createdAt, this.updatedAt, Map<String, _Book>? collection})
: this.collection = Map.unmodifiable(collection ?? {}); : collection = Map.unmodifiable(collection ?? {});
/// A unique identifier corresponding to this item. /// A unique identifier corresponding to this item.
@override @override
String id; String? id;
/// The time at which this item was created. /// The time at which this item was created.
@override @override
DateTime createdAt; DateTime? createdAt;
/// The last time at which this item was updated. /// The last time at which this item was updated.
@override @override
DateTime updatedAt; DateTime? updatedAt;
@override @override
final Map<String, _Book> collection; final Map<String, _Book> collection;
Library copyWith( Library copyWith(
{String id, {String? id,
DateTime createdAt, DateTime? createdAt,
DateTime updatedAt, DateTime? updatedAt,
Map<String, _Book> collection}) { Map<String, _Book>? collection}) {
return Library( return Library(
id: id ?? this.id, id: id ?? this.id,
createdAt: createdAt ?? this.createdAt, createdAt: createdAt ?? this.createdAt,
@ -271,7 +271,7 @@ class Library extends _Library {
@override @override
String toString() { String toString() {
return "Library(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, collection=$collection)"; return 'Library(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, collection=$collection)';
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -285,40 +285,40 @@ class Bookmark extends _Bookmark {
{this.id, {this.id,
this.createdAt, this.createdAt,
this.updatedAt, this.updatedAt,
List<int> history, List<int>? history,
@required this.page, required this.page,
this.comment}) this.comment})
: this.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.
@override @override
String id; String? id;
/// The time at which this item was created. /// The time at which this item was created.
@override @override
DateTime createdAt; DateTime? createdAt;
/// The last time at which this item was updated. /// The last time at which this item was updated.
@override @override
DateTime updatedAt; DateTime? updatedAt;
@override @override
final List<int> history; final List<int> history;
@override @override
final int page; final int? page;
@override @override
final String comment; final String? comment;
Bookmark copyWith(_Book book, Bookmark copyWith(_Book book,
{String id, {String? id,
DateTime createdAt, DateTime? createdAt,
DateTime updatedAt, DateTime? updatedAt,
List<int> history, List<int>? history,
int page, int? page,
String comment}) { String? comment}) {
return Bookmark(book, return Bookmark(book,
id: id ?? this.id, id: id ?? this.id,
createdAt: createdAt ?? this.createdAt, createdAt: createdAt ?? this.createdAt,
@ -346,7 +346,7 @@ class Bookmark extends _Bookmark {
@override @override
String toString() { String toString() {
return "Bookmark(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, history=$history, page=$page, comment=$comment)"; return 'Bookmark(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, history=$history, page=$page, comment=$comment)';
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -360,11 +360,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> {
@ -374,37 +374,39 @@ 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
get encoder => const BookEncoder(); BookEncoder get encoder => const BookEncoder();
@override @override
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?,
title: map['title'] as String, title: map['title'] as String?,
description: map['description'] as String, description: map['description'] as String?,
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, : 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; return null;
} }
@ -474,32 +476,34 @@ class AuthorSerializer extends Codec<Author, Map> {
const AuthorSerializer(); const AuthorSerializer();
@override @override
get encoder => const AuthorEncoder(); AuthorEncoder get encoder => const AuthorEncoder();
@override @override
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.");
} }
if (map['age'] == null) { if (map['age'] == null) {
throw FormatException("Custom message for missing `age`"); throw FormatException('Custom message for missing `age`');
} }
return Author( return Author(
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?,
age: map['age'] as int, age: map['age'] as int?,
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))
@ -507,19 +511,16 @@ class AuthorSerializer extends Codec<Author, Map> {
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 == null) {
return null;
}
if (model.name == null) { if (model.name == null) {
throw FormatException("Missing required field 'name' on Author."); throw FormatException("Missing required field 'name' on Author.");
} }
if (model.age == null) { if (model.age == null) {
throw FormatException("Custom message for missing `age`"); throw FormatException('Custom message for missing `age`');
} }
return { return {
@ -528,7 +529,7 @@ class AuthorSerializer extends Codec<Author, Map> {
'updated_at': model.updatedAt?.toIso8601String(), 'updated_at': model.updatedAt?.toIso8601String(),
'name': model.name, 'name': model.name,
'age': model.age, 'age': model.age,
'books': model.books?.map((m) => BookSerializer.toMap(m))?.toList(), 'books': model.books.map((m) => BookSerializer.toMap(m)).toList(),
'newest_book': BookSerializer.toMap(model.newestBook) 'newest_book': BookSerializer.toMap(model.newestBook)
}; };
} }
@ -586,20 +587,22 @@ class LibrarySerializer extends Codec<Library, Map> {
const LibrarySerializer(); const LibrarySerializer();
@override @override
get encoder => const LibraryEncoder(); LibraryEncoder get encoder => const LibraryEncoder();
@override @override
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
@ -613,14 +616,11 @@ class LibrarySerializer extends Codec<Library, Map> {
} }
static Map<String, dynamic> toMap(_Library model) { static Map<String, dynamic> toMap(_Library model) {
if (model == null) {
return 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({}, (map, key) { 'collection': model.collection.keys.fold({}, (dynamic map, key) {
return map..[key] = BookSerializer.toMap(model.collection[key]); return map..[key] = BookSerializer.toMap(model.collection[key]);
}) })
}; };
@ -651,28 +651,25 @@ abstract class BookmarkSerializer {
} }
return Bookmark(book, return Bookmark(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,
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, : 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 == null) {
return null;
}
if (model.page == null) { if (model.page == null) {
throw FormatException("Missing required field 'page' on Bookmark."); throw FormatException("Missing required field 'page' on Bookmark.");
} }

View file

@ -3,16 +3,16 @@ part 'game_pad_button.g.dart';
@serializable @serializable
abstract class _GamepadButton { abstract class _GamepadButton {
String get name; String? get name;
int get radius; int? get radius;
} }
@serializable @serializable
class _Gamepad { class _Gamepad {
List<_GamepadButton> buttons; List<_GamepadButton>? buttons;
Map<String, dynamic> dynamicMap; Map<String, dynamic>? dynamicMap;
// ignore: unused_field // ignore: unused_field
String _somethingPrivate; String? _somethingPrivate;
} }

View file

@ -11,12 +11,12 @@ class GamepadButton implements _GamepadButton {
const GamepadButton({this.name, this.radius}); const GamepadButton({this.name, this.radius});
@override @override
final String name; final String? name;
@override @override
final int radius; final int? radius;
GamepadButton copyWith({String name, int radius}) { GamepadButton copyWith({String? name, int? radius}) {
return GamepadButton( return GamepadButton(
name: name ?? this.name, radius: radius ?? this.radius); name: name ?? this.name, radius: radius ?? this.radius);
} }
@ -44,18 +44,18 @@ 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, Map<String, dynamic>? dynamicMap})
: this.buttons = List.unmodifiable(buttons ?? []), : this.buttons = List.unmodifiable(buttons ?? []),
this.dynamicMap = Map.unmodifiable(dynamicMap ?? {}); this.dynamicMap = Map.unmodifiable(dynamicMap ?? {});
@override @override
List<_GamepadButton> buttons; List<_GamepadButton>? buttons;
@override @override
Map<String, dynamic> dynamicMap; Map<String, dynamic>? dynamicMap;
Gamepad copyWith( Gamepad copyWith(
{List<_GamepadButton> buttons, Map<String, dynamic> dynamicMap}) { {List<_GamepadButton>? buttons, Map<String, dynamic>? dynamicMap}) {
return Gamepad( return Gamepad(
buttons: buttons ?? this.buttons, buttons: buttons ?? this.buttons,
dynamicMap: dynamicMap ?? this.dynamicMap); dynamicMap: dynamicMap ?? this.dynamicMap);
@ -115,13 +115,10 @@ class GamepadButtonSerializer extends Codec<GamepadButton, Map> {
get decoder => const GamepadButtonDecoder(); get decoder => const GamepadButtonDecoder();
static GamepadButton fromMap(Map map) { static GamepadButton fromMap(Map map) {
return GamepadButton( return GamepadButton(
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) {
return null;
}
return {'name': model.name, 'radius': model.radius}; return {'name': model.name, 'radius': model.radius};
} }
} }
@ -169,12 +166,9 @@ class GamepadSerializer extends Codec<Gamepad, Map> {
} }
static Map<String, dynamic> toMap(_Gamepad model) { static Map<String, dynamic> toMap(_Gamepad model) {
if (model == null) {
return null;
}
return { return {
'buttons': 'buttons':
model.buttons?.map((m) => GamepadButtonSerializer.toMap(m))?.toList(), model.buttons?.map((m) => GamepadButtonSerializer.toMap(m)).toList(),
'dynamic_map': model.dynamicMap 'dynamic_map': model.dynamicMap
}; };
} }

View file

@ -16,7 +16,7 @@ class Goat implements _Goat {
@override @override
final List<int> list; final 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);
} }
@ -70,16 +70,13 @@ class GoatSerializer extends Codec<Goat, Map> {
get decoder => const GoatDecoder(); get decoder => const GoatDecoder();
static Goat fromMap(Map map) { static Goat fromMap(Map map) {
return Goat( return Goat(
integer: map['integer'] as int ?? 34, integer: map['integer'] as int? ?? 34,
list: map['list'] is Iterable list: map['list'] is Iterable
? (map['list'] as Iterable).cast<int>().toList() ? (map['list'] as Iterable).cast<int>().toList()
: const [34, 35]); : const [34, 35]);
} }
static Map<String, dynamic> toMap(_Goat model) { static Map<String, dynamic> toMap(_Goat model) {
if (model == null) {
return null;
}
return {'integer': model.integer, 'list': model.list}; return {'integer': model.integer, 'list': model.list};
} }
} }

View file

@ -4,9 +4,9 @@ import 'package:collection/collection.dart';
import 'package:meta/meta.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?;
String _toString(Map v) => json.encode(v); String _toString(Map? v) => json.encode(v);
@serializable @serializable
abstract class _HasMap { abstract class _HasMap {
@ -15,5 +15,5 @@ abstract class _HasMap {
deserializer: #_fromString, deserializer: #_fromString,
isNullable: false, isNullable: false,
serializesTo: String) serializesTo: String)
Map get value; Map? get value;
} }

View file

@ -8,12 +8,12 @@ part of 'has_map.dart';
@generatedSerializable @generatedSerializable
class HasMap implements _HasMap { class HasMap implements _HasMap {
const HasMap({@required this.value}); const HasMap({required this.value});
@override @override
final Map<dynamic, dynamic> value; final 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,9 +75,6 @@ class HasMapSerializer extends Codec<HasMap, Map> {
} }
static Map<String, dynamic> toMap(_HasMap model) { static Map<String, dynamic> toMap(_HasMap model) {
if (model == null) {
return null;
}
if (model.value == null) { if (model.value == null) {
throw FormatException("Missing required field 'value' on HasMap."); throw FormatException("Missing required field 'value' on HasMap.");
} }

View file

@ -4,15 +4,15 @@ part 'subclass.g.dart';
@serializable @serializable
class _Animal { class _Animal {
@notNull @notNull
String genus; String? genus;
@notNull @notNull
String species; String? species;
} }
@serializable @serializable
class _Bird extends _Animal { class _Bird extends _Animal {
@DefaultsTo(false) @DefaultsTo(false)
bool isSparrow; bool? isSparrow;
} }
var saxaulSparrow = Bird( var saxaulSparrow = Bird(

View file

@ -8,15 +8,15 @@ part of 'subclass.dart';
@generatedSerializable @generatedSerializable
class Animal extends _Animal { class Animal extends _Animal {
Animal({@required this.genus, @required this.species}); Animal({required this.genus, required this.species});
@override @override
String genus; String? genus;
@override @override
String species; String? species;
Animal copyWith({String genus, String species}) { Animal copyWith({String? genus, String? species}) {
return Animal(genus: genus ?? this.genus, species: species ?? this.species); return Animal(genus: genus ?? this.genus, species: species ?? this.species);
} }
@ -41,18 +41,18 @@ class Animal extends _Animal {
@generatedSerializable @generatedSerializable
class Bird extends _Bird { class Bird extends _Bird {
Bird({@required this.genus, @required this.species, this.isSparrow = false}); Bird({required this.genus, required this.species, this.isSparrow = false});
@override @override
String genus; String? genus;
@override @override
String species; String? species;
@override @override
bool isSparrow; bool? isSparrow;
Bird copyWith({String genus, String species, bool isSparrow}) { Bird copyWith({String? genus, String? species, bool? isSparrow}) {
return Bird( return Bird(
genus: genus ?? this.genus, genus: genus ?? this.genus,
species: species ?? this.species, species: species ?? this.species,
@ -118,13 +118,10 @@ class AnimalSerializer extends Codec<Animal, Map> {
} }
return Animal( return Animal(
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 == null) {
return null;
}
if (model.genus == null) { if (model.genus == null) {
throw FormatException("Missing required field 'genus' on Animal."); throw FormatException("Missing required field 'genus' on Animal.");
} }
@ -178,15 +175,12 @@ class BirdSerializer extends Codec<Bird, Map> {
} }
return Bird( return Bird(
genus: map['genus'] as String, genus: map['genus'] as String?,
species: map['species'] as String, species: map['species'] as String?,
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 == null) {
return null;
}
if (model.genus == null) { if (model.genus == null) {
throw FormatException("Missing required field 'genus' on Bird."); throw FormatException("Missing required field 'genus' on Bird.");
} }

View file

@ -7,11 +7,11 @@ part 'with_enum.g.dart';
@serializable @serializable
abstract class _WithEnum { abstract class _WithEnum {
@DefaultsTo(WithEnumType.b) @DefaultsTo(WithEnumType.b)
WithEnumType get type; WithEnumType? get type;
List<int> get finalList; List<int>? get finalList;
Uint8List get imageBytes; Uint8List? get imageBytes;
} }
enum WithEnumType { a, b, c } enum WithEnumType { a, b, c }

View file

@ -11,16 +11,16 @@ class WithEnum implements _WithEnum {
const WithEnum({this.type = WithEnumType.b, this.finalList, this.imageBytes}); const WithEnum({this.type = WithEnumType.b, this.finalList, this.imageBytes});
@override @override
final WithEnumType type; final WithEnumType? type;
@override @override
final List<int> finalList; final List<int>? finalList;
@override @override
final Uint8List imageBytes; final Uint8List? imageBytes;
WithEnum copyWith( WithEnum copyWith(
{WithEnumType type, List<int> finalList, Uint8List imageBytes}) { {WithEnumType? type, List<int>? finalList, Uint8List? imageBytes}) {
return WithEnum( return WithEnum(
type: type ?? this.type, type: type ?? this.type,
finalList: finalList ?? this.finalList, finalList: finalList ?? this.finalList,
@ -80,7 +80,7 @@ class WithEnumSerializer extends Codec<WithEnum, Map> {
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?)
: (map['type'] is int : (map['type'] is int
? WithEnumType.values[map['type'] as int] ? WithEnumType.values[map['type'] as int]
: WithEnumType.b), : WithEnumType.b),
@ -88,7 +88,7 @@ class WithEnumSerializer extends Codec<WithEnum, Map> {
? (map['final_list'] as Iterable).cast<int>().toList() ? (map['final_list'] as Iterable).cast<int>().toList()
: null, : 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,15 +99,12 @@ class WithEnumSerializer extends Codec<WithEnum, Map> {
} }
static Map<String, dynamic> toMap(_WithEnum model) { static Map<String, dynamic> toMap(_WithEnum model) {
if (model == null) {
return null;
}
return { return {
'type': 'type':
model.type == null ? null : WithEnumType.values.indexOf(model.type), model.type == null ? null : WithEnumType.values.indexOf(model.type!),
'final_list': model.finalList, 'final_list': model.finalList,
'image_bytes': 'image_bytes':
model.imageBytes == null ? null : base64.encode(model.imageBytes) model.imageBytes == null ? null : base64.encode(model.imageBytes!)
}; };
} }
} }

View file

@ -1,4 +0,0 @@
cd angel_serialize_generator
pub get
pub run build_runner build --delete-conflicting-outputs
pub run test

View file

@ -1,3 +1,9 @@
# 4.0.0
* Migrated to support Dart SDK 2.12.x NNBD
# 3.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
# 2.0.2 # 2.0.2
* Deduplicate error messages. * Deduplicate error messages.

View file

@ -1,7 +1,6 @@
name: angel_validate name: angel_validate
description: Cross-platform request body validation library based on `matcher`. description: Cross-platform request body validation library based on `matcher`.
version: 4.0.0 version: 4.0.0
author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/validate homepage: https://github.com/angel-dart/validate
publish_to: none publish_to: none
environment: environment: