coderForField method

  1. @override
String? coderForField(
  1. FieldElement field,
  2. SharedChecker<Model> checker, {
  3. required bool wrappedInFuture,
  4. required Annotation 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, Futures 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 fieldValue = serdesValueForField(field, fieldAnnotation.name!, checker: checker);
  if (fieldAnnotation.ignoreTo) return null;

  // DateTime
  if (checker.isDateTime) {
    final nullabilitySuffix = checker.isNullable ? '?' : '';
    return '$fieldValue$nullabilitySuffix.toIso8601String()';

    // bool, double, int, num, String, Map, Iterable, enum
  } else if ((checker.isDartCoreType) || checker.isMap) {
    return fieldValue;

    // Iterable
  } else if (checker.isIterable) {
    final argTypeChecker = checkerForType(checker.argType);

    // Iterable<enum>
    if (argTypeChecker.isEnum) {
      final nullabilitySuffix = checker.isNullable ? '?' : '';
      final serializeMethod = argTypeChecker.enumSerializeMethod(providerName);
      if (serializeMethod != null) {
        return '$fieldValue$nullabilitySuffix.map((e) => e.$serializeMethod()).toList()';
      }

      if (fieldAnnotation.enumAsString) {
        return "$fieldValue$nullabilitySuffix.map((e) => e.name).toList()";
      } else {
        return '$fieldValue$nullabilitySuffix.map((e) => ${SharedChecker.withoutNullability(checker.argType)}.values.indexOf(e)).toList()';
      }
    }

    // Iterable<RestModel>, Iterable<Future<RestModel>>
    if (checker.isArgTypeASibling) {
      final awaited = checker.isArgTypeAFuture ? 'async' : '';
      final awaitedValue = checker.isArgTypeAFuture ? '(await s)' : 's';
      final nullabilitySuffix = checker.isNullable ? '?' : '';
      final nullabilityDefault = checker.isNullable ? ' ?? []' : '';
      return '''await Future.wait<Map<String, dynamic>>(
        $fieldValue$nullabilitySuffix.map((s) $awaited =>
          ${SharedChecker.withoutNullability(checker.unFuturedArgType)}Adapter().to$providerName($awaitedValue, provider: provider, repository: repository)
        ).toList()$nullabilityDefault
      )''';
    }

    // Iterable<toJson>
    if (argTypeChecker.toJsonMethod != null) {
      final nullabilitySuffix = checker.isNullable ? '?' : '';
      return '$fieldValue$nullabilitySuffix.map((s) => s.toJson()).toList()';
    }

    return fieldValue;

    // RestModel, Future<RestModel>
  } else if (checker.isSibling) {
    final wrappedField = wrappedInFuture ? '(await $fieldValue)' : fieldValue;
    final isNullableField = checker.unFuturedType.nullabilitySuffix != NullabilitySuffix.none;
    final wrappedFieldWithSuffix = isNullableField ? '$wrappedField!' : wrappedField;

    final result =
        'await ${SharedChecker.withoutNullability(checker.unFuturedType)}Adapter().to$providerName($wrappedFieldWithSuffix, provider: provider, repository: repository)';
    if (isNullableField) return '$wrappedField != null ? $result : null';

    return result;

    // 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";
    } else {
      if (checker.isNullable) {
        return '$fieldValue != null ? ${SharedChecker.withoutNullability(field.type)}.values.indexOf($fieldValue!) : null';
      }
      return '${SharedChecker.withoutNullability(field.type)}.values.indexOf($fieldValue)';
    }
  } else if (checker.toJsonMethod != null) {
    final nullabilitySuffix = checker.isNullable ? '?' : '';
    return '$fieldValue$nullabilitySuffix.toJson()';
  }

  return null;
}