generate method
Implementation
@override
String generate(List<ClassMember> members) {
var toMap = '';
var patcher = '';
var usingToDouble = false;
var usingToDecimal = false;
final toDouble =
'final toDouble = (val) => val == null ? null : val * 1.0;\n';
final toDecimal =
'final toDecimal = (val) => val == null ? null : Decimal.parse(val.toString());\n';
for (var member in members) {
if (!(member is FieldDeclaration)) continue;
if (!getTag(member).contains('json')) continue;
final key = getTag(member).split(':')[1].replaceAll('"', '');
final isNullable = member.fields.type?.question != null;
final dot = isNullable ? '?.' : '.';
final typeName = (member.fields.type as NamedType).name.toString();
final typeArgs =
(member.fields.type as NamedType).typeArguments?.arguments;
final leftType = (typeArgs?.elementAtOrNull(0) as NamedType?);
final leftName = leftType?.name.toString() ?? 'dynamic';
final leftDot = (leftType?.question?.toString() ?? '') + '.';
final leftExcl = leftType?.question == null ? '!' : '';
final rightType = (typeArgs?.elementAtOrNull(1) as NamedType?);
final rightName = rightType?.name.toString() ?? 'dynamic';
final rightDot = (rightType?.question?.toString() ?? '') + '.';
final rightExcl = rightType?.question == null ? '!' : '';
final type = member.fields.type
.toString()
.replaceAll('\$', '')
.replaceAll('?', '');
final name = member.fields.variables.first.name.lexeme;
final initializer = member.fields.variables.first.initializer;
if ([
'String',
'num',
'bool',
'int',
'dynamic',
'Map<String, dynamic>',
'List<dynamic>'
].contains(type)) {
toMap += "'$key': $name,\n";
patcher += "$name = _data['$key']";
} else if (type == 'double') {
toMap += "'$key': $name,\n";
patcher += "$name = toDouble(_data['$key'])";
usingToDouble = true;
} else if (type == 'Decimal') {
toMap += "'$key': $name${dot}toDouble(),\n";
patcher += "$name = toDecimal(_data['$key'])";
usingToDecimal = true;
} else if (enums.contains(type)) {
toMap += "'$key': $name${dot}value,\n";
patcher += "$name = $type.parse(_data['$key'])";
} else if (typeName == 'Map') {
if (['String', 'num', 'bool', 'dynamic'].contains(rightName)) {
toMap += "'$key': $name,\n";
patcher +=
"$name = (_data['$key'] as Map?)?.map<$leftName, $rightName>((k, v) => MapEntry(k as $leftName, v as $rightName))";
} else if (rightName == 'int') {
toMap += "'$key': $name,\n";
patcher +=
"$name = (_data['$key'] as Map?)?.map<$leftName, $rightName>((k, v) => MapEntry(k as $leftName, v ~/ 1))";
} else if (rightName == 'double') {
toMap += "'$key': $name,\n";
patcher +=
"$name = (_data['$key'] as Map?)?.map<$leftName, $rightName>((k, v) => MapEntry(k as $leftName, v * 1.0))";
} else if (enums.contains(rightName)) {
toMap +=
"'$key': $name${dot}map<String, dynamic>((k,v) => MapEntry(k, v${rightDot}value)),\n";
patcher +=
"$name = (_data['$key'] as Map?)?.map<$leftName, $rightName>((k, v) => MapEntry(k as $leftName, $rightName.parse(v)$rightExcl))";
} else {
toMap +=
"'$key': $name${dot}map<String, dynamic>((k,v) => MapEntry(k, v${rightDot}toMap())),\n";
patcher +=
"$name = (_data['$key'] as Map?)?.map<$leftName, $rightName>((k, v) => MapEntry(k as $leftName, $rightName.fromMap(v)$rightExcl))";
}
} else if (typeName == 'List') {
if (['String', 'num', 'bool', 'dynamic'].contains(leftName)) {
toMap += "'$key': $name,\n";
patcher += "$name = _data['$key']?.cast<$leftName>()";
} else if (leftName == 'int') {
toMap += "'$key': $name,\n";
patcher +=
"$name = _data['$key']?.map((i) => i ~/ 1).toList().cast<int>()";
} else if (leftName == 'double') {
toMap += "'$key': $name,\n";
patcher +=
"$name = _data['$key']?.map((i) => i * 1.0).toList().cast<double>()";
} else if (enums.contains(leftName)) {
toMap +=
"'$key': $name${dot}map((i) => i${leftDot}value).toList(),\n";
patcher +=
"$name = _data['$key']?.map((i) => $leftName.parse(i)$leftExcl).toList().cast<$leftName>()";
} else {
toMap +=
"'$key': $name${dot}map((i) => i${leftDot}toMap()).toList(),\n";
patcher +=
"$name = _data['$key']?.map((i) => $leftName.fromMap(i)$leftExcl).toList().cast<$leftName>()";
}
} else {
toMap += "'$key': $name${dot}toMap(),";
patcher += "$name = $type.fromMap(_data['$key'])";
}
patcher += ' ?? ${initializer ?? name};\n';
}
return '''
void patch(Map? _data) { if(_data == null) return;
${usingToDouble ? toDouble : ''}
${usingToDecimal ? toDecimal : ''}
$patcher
}
static $className? fromMap(Map? data) { if(data == null) return null; return $className()..patch(data); }
Map<String, dynamic> toMap() => {
$toMap
};
''';
}