coderForField method
String?
coderForField(
- FieldElement field,
- SharedChecker<
Model> checker, { - required bool wrappedInFuture,
- required Sqlite fieldAnnotation,
Produces serializing or deserializing method given a field and checker.
The assignment (data['my_field']:
in serializers or myField:
in deserializers)
is automatically injected by the superclass and should not be included in the
output of the coder.
To simplify checking, Future
s are unwrapped before they get to this method.
If the type was originally a future, wrappedInFuture
is true
.
For example, Future<List<int>>
will be an iterable according to the checker and
wrappedInFuture
will be true
.
Implementation
@override
String? coderForField(field, checker, {required wrappedInFuture, required fieldAnnotation}) {
final name = providerNameForField(fieldAnnotation.name, checker: checker);
final fieldValue = serdesValueForField(field, fieldAnnotation.name!, checker: checker);
if (name == InsertTable.PRIMARY_KEY_COLUMN) {
throw InvalidGenerationSourceError(
'Field named `${InsertTable.PRIMARY_KEY_COLUMN}` conflicts with primary key',
todo: 'Rename the field from ${InsertTable.PRIMARY_KEY_COLUMN}',
element: field,
);
}
if (fieldAnnotation.ignoreTo) return null;
if (fieldAnnotation.columnType != null) {
return fieldValue;
}
// DateTime
if (checker.isDateTime) {
final nullableSuffix = checker.isNullable ? '?' : '';
return '$fieldValue$nullableSuffix.toIso8601String()';
// bool
} else if (checker.isBool) {
return _boolForField(fieldValue, checker.isNullable);
// double, int, num, String
} else if (checker.isDartCoreType) {
return fieldValue;
// Iterable
} else if (checker.isIterable) {
final argTypeChecker = checkerForType(checker.argType);
// Iterable<enum>
if (argTypeChecker.isEnum) {
final nullablePrefix = checker.isNullable ? '?' : '';
final nullableDefault = checker.isNullable ? ' ?? []' : '';
final serializeMethod = argTypeChecker.enumSerializeMethod(providerName);
final serializedValue = serializeMethod != null
? 's.$serializeMethod()'
: fieldAnnotation.enumAsString
? 's.name'
: '${SharedChecker.withoutNullability(checker.argType)}.values.indexOf(s)';
return '''
jsonEncode($fieldValue$nullablePrefix.map((s) =>
$serializedValue
).toList()$nullableDefault)
''';
}
// Iterable<Future<bool>>, Iterable<Future<DateTime>>, Iterable<Future<double>>,
// Iterable<Future<int>>, Iterable<Future<num>>, Iterable<Future<String>>, Iterable<Future<Map>>
if (checker.isArgTypeAFuture) {
if (checker.isSerializable && !checker.isArgTypeASibling) {
// Iterable<Future<bool>>
final wrappedValue =
checker.isBool ? _boolForField(fieldValue, fieldAnnotation.nullable) : fieldValue;
return 'jsonEncode(await Future.wait<${argTypeChecker.unFuturedArgType}>($wrappedValue) ?? [])';
}
}
// Set<any>
// jsonEncode can't convert LinkedHashSet
if (checker.isSet && !checker.isArgTypeASibling) {
return checker.isNullable
? '$fieldValue == null ? null : jsonEncode($fieldValue.toList())'
: 'jsonEncode($fieldValue.toList())';
}
// Iterable<bool>
if (argTypeChecker.isBool) {
return 'jsonEncode($fieldValue.map((b) => ${_boolForField('b', fieldAnnotation.nullable)}).toList())';
}
// Iterable<DateTime>, Iterable<double>, Iterable<int>, Iterable<num>, Iterable<String>, Iterable<Map>
if (argTypeChecker.isDartCoreType || argTypeChecker.isMap) {
return checker.isNullable
? '$fieldValue == null ? null : jsonEncode($fieldValue)'
: 'jsonEncode($fieldValue)';
}
// Iterable<toJson>
if (argTypeChecker.toJsonMethod != null) {
final serializedValue = 'jsonEncode($fieldValue)';
return checker.isNullable
? '$fieldValue != null ? $serializedValue : null'
: serializedValue;
}
// SqliteModel, Future<SqliteModel>
} else if (checker.isSibling) {
final instance = wrappedInFuture ? '(await $fieldValue)' : fieldValue;
final nullabilitySuffix = checker.isUnFuturedTypeNullable || checker.isNullable ? '!' : '';
final upsertMethod = '''
$instance$nullabilitySuffix.${InsertTable.PRIMARY_KEY_FIELD} ??
await provider.upsert<${SharedChecker.withoutNullability(checker.unFuturedType)}>(
$instance$nullabilitySuffix, repository: repository
)''';
if (checker.isUnFuturedTypeNullable) {
return '$instance != null ? $upsertMethod : null';
}
return upsertMethod;
// enum
} else if (checker.isEnum) {
final nullabilitySuffix = checker.isNullable ? '?' : '';
final serializeMethod = checker.enumSerializeMethod(providerName);
if (serializeMethod != null) {
return '$fieldValue$nullabilitySuffix.$serializeMethod()';
}
if (fieldAnnotation.enumAsString) {
return '$fieldValue$nullabilitySuffix.name';
}
if (checker.isNullable) {
return '$fieldValue != null ? ${SharedChecker.withoutNullability(field.type)}.values.indexOf($fieldValue!) : null';
}
return '${SharedChecker.withoutNullability(field.type)}.values.indexOf($fieldValue)';
// Map
} else if (checker.isMap) {
final nullableSuffix = checker.isNullable ? ' ?? {}' : '';
return 'jsonEncode($fieldValue$nullableSuffix)';
} else if (checker.toJsonMethod != null) {
final nullableSuffix = checker.isNullable ? '!' : '';
final output = 'jsonEncode($fieldValue$nullableSuffix.toJson())';
if (checker.isNullable) {
return '$fieldValue != null ? $output : null';
}
return output;
}
return null;
}