createSerializer method

Mapper createSerializer()

Implementation

Mapper createSerializer() {
  Map<Type, MappingDefinition> mappings = {};
  var queue = Queue<Type>.from([type]);

  // local function

  void check(Type type) {
    if (!mappings.containsKey(type))
      queue.add(type);
  }

  MappingDefinition process(Type type) {
    var typeMapping = MappingDefinition<dynamic,Map<String, dynamic>>(sourceClass: type, targetClass: Map<String, dynamic>);
    var typeDescriptor = TypeDescriptor.forType(type);

    var jsonSerializable = typeDescriptor.findAnnotation<JsonSerializable>() ?? JsonSerializable();

    mappings[type] = typeMapping;

    // process fields

    for (var field in typeDescriptor.getFields()) {
      var json = field.find_annotation<Json>() ?? Json(name: field.name, defaultValue: null);
      var includeNull = jsonSerializable.includeNull && json.includeNull != false;

      if ( json.ignore)
        continue;

      if (field.type is ListType) {
        var elementType = field.elementType;

        check(elementType!);

        typeMapping.map(
            from: field.name,
            to: JSONAccessor(name: json.name, type: Map<String, dynamic>, includeNull: includeNull, containerConstructor: () => []),
            deep: true); // index?
      }
      else if ( field.type is ObjectType) {
        var objectType = field.type as ObjectType;

        if ( objectType.typeDescriptor.isEnum()) {
          Convert? convertSource = JSON.instance.getConvert(field.type.type);

          typeMapping.map(from: field.name,
              to: JSONAccessor(name: json.name,
                  type: field.type.type,
                  convert: convertSource?.sourceConverter(),
                  includeNull: includeNull));
        }
        else {
          var target = objectType.type;

          check(target);

          typeMapping.map(
              from: field.name,
              to: JSONAccessor(name: json.name, type: Map<String, dynamic>, includeNull: includeNull),
              deep: true); // index?
        }
      } // if
      else {
        Convert? convertSource = JSON.instance.getConvert(field.type.type);

        typeMapping.map(from: field.name,
            to: JSONAccessor(name: json.name,
                type: field.type.type,
                convert: convertSource?.sourceConverter(),
                includeNull: includeNull));
      }
    }

    return typeMapping;
  }

  // work on queue

  while (queue.isNotEmpty) {
    process(queue.removeFirst());
  }

  // done

  var mapper = Mapper(mappings.values.toList());

  serializerMapping = mapper.getMappingX(type, Map<String,dynamic>);

  return mapper;
}