createSerializer method
Implementation
Mapper createSerializer() {
Map<Type, MappingDefinition> mappings = {};
var queue = Queue<Type>.from([type]);
// local function
void check(Type type) {
if ( !TypeDescriptor.hasType(type))
return;
// own class
if (!mappings.containsKey(type)) {
queue.add(type);
// check subclasses as well
for ( var sub in TypeDescriptor.forType(type).childClasses)
check(sub.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.findAnnotation<Json>() ?? Json(name: field.name, defaultValue: null);
var includeNull = jsonSerializable.includeNull && json.includeNull != false;
if ( json.ignore)
continue;
var jsonField = json.name;
if (jsonField.isEmpty)
jsonField = field.name;
if (field.type is ListType) {
var elementType = field.elementType;
check(elementType!);
typeMapping.map(
from: field.name,
to: JSONAccessor(
name: jsonField,
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: jsonField,
type: field.type.type,
convert: convertSource?.sourceConverter(),
includeNull: includeNull
)
);
}
else {
var target = objectType.type;
// manual converter?
Convert? convert ;
if ( json.converter != null) {
convert = JSON.getConvert4(json.converter!);
}
else convert = JSON.instance.getConvert(field.type.type);
if ( convert == null)
check(target);
typeMapping.map(
convert: convert,
from: field.name,
to: JSONAccessor(
name: jsonField,
type: Map<String, dynamic>,
includeNull: includeNull,
//convert: convert?.sourceConverter()
),
deep: convert == null,
validate: validate
); // index?
}
} // if
else {
Convert? convert ;
if ( json.converter != null) {
convert = JSON.getConvert4(json.converter!);
}
else convert = JSON.instance.getConvert(field.type.type);
typeMapping.map(
from: field.name,
to: JSONAccessor(
name: jsonField,
type: field.type.type,
convert: convert?.sourceConverter(),
includeNull: includeNull
),
validate: validate
);
}
}
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;
}