createDeserializer method
Implementation
Mapper createDeserializer() {
Map<Type, MappingDefinition> mappings = {};
var queue = Queue<Type>.from([type]);
// local function
MappingDefinition process(Type type) {
var typeMapping = MappingDefinition<Map<String, dynamic>, dynamic>(sourceClass: Map<String, dynamic>, targetClass: type);
//if ( mapping == null)
// mapping = typeMapping;
var typeDescriptor = TypeDescriptor.forType(type);
var jsonSerializable = typeDescriptor.findAnnotation<JsonSerializable>() ?? JsonSerializable();
mappings[type] = typeMapping;
void check(Type type) {
if (!mappings.containsKey(type))
queue.add(type);
}
// 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;
Object? defaultValue = JSONAccessor;
if ( !json.required) {
defaultValue = json.defaultValue;
if ( !field.type.isValid(defaultValue))
throw MapperException("the default $defaultValue for ${field.name} is not valid");
}
if (field.type is ListType) {
var elementType = field.elementType;
check(elementType!);
typeMapping.map(
from: JSONAccessor(name: json.name, type: List<dynamic>, includeNull: includeNull, defaultValue: defaultValue, containerConstructor: () => []),
to: field.name,
deep: true,
validate: validate
);
}
else if ( field.type is ObjectType) {
var objectType = field.type as ObjectType;
if ( !objectType.typeDescriptor.isEnum()) {
var target = objectType.type;
check(target);
typeMapping.map(
from: JSONAccessor(name: json.name, type: Map<String, dynamic>, includeNull: includeNull, defaultValue: defaultValue),
to: field.name,
deep: true);
}
else {
Convert? convertSource = JSON.instance.getConvert(field.type.type);
typeMapping.map(from: JSONAccessor(name: json.name,
type: field.type.type,
convert: convertSource?.targetConverter(),
includeNull: includeNull,
defaultValue: defaultValue),
to: field.name,
validate: validate);
}
} // if
else {
Convert? convertSource = JSON.instance.getConvert(field.type.type);
typeMapping.map(from: JSONAccessor(name: json.name,
type: field.type.type,
convert: convertSource?.targetConverter(),
includeNull: includeNull,
defaultValue: defaultValue),
to: field.name,
validate: validate);
}
}
return typeMapping;
}
// work on queue
while (queue.isNotEmpty) {
process(queue.removeFirst());
}
// done
var mapper = Mapper(mappings.values.toList());
deserializerMapping = mapper.mappings.values.firstWhere((mapping) => mapping.typeDescriptor.type == type);
return mapper;
}