generateDeserialization method
List<MapEntry<Expression, Code> >
generateDeserialization(
- bool serverCode, {
- required GeneratorConfig config,
Generates the constructors for List and Map types
Implementation
List<MapEntry<Expression, Code>> generateDeserialization(
bool serverCode, {
required GeneratorConfig config,
}) {
if (isRecordType) {
return [
MapEntry(
refer('getType', serverpodUrl(serverCode))
.call([], {}, [reference(serverCode, config: config)]),
Block.of(
[
if (nullable) const Code(' (data == null) ? null as T : '),
const Code('('),
for (final (i, positionalField)
in positionalRecordFields.indexed) ...[
if (positionalField.nullable)
Code(
"((data ${i == 0 ? 'as Map' : ''})['p'] as List)[$i] == null ? null : "),
const Code('deserialize<'),
positionalField
.reference(serverCode, config: config, nullable: false)
.code,
const Code('>('),
if (i == 0 && !positionalField.nullable) ...[
Code("((data as Map)['p'] as List)[$i]"),
] else
Code("data['p'][$i]"),
const Code(')'),
const Code(','),
],
if (namedRecordFields.isNotEmpty) ...[
for (final (i, namedField) in namedRecordFields.indexed) ...[
Code(namedField.recordFieldName!),
const Code(':'),
if (namedField.nullable)
Code(
"((data ${i == 0 && positionalRecordFields.isEmpty ? 'as Map' : ''})['n'] as Map)['${namedField.recordFieldName!}'] == null ? null : "),
const Code('deserialize<'),
namedField
.reference(serverCode, config: config, nullable: false)
.code,
const Code('>('),
if (i == 0 &&
positionalRecordFields.isEmpty &&
!namedField.nullable)
Code(
"((data as Map)['n'] as Map)['${namedField.recordFieldName!}']")
else
Code("data['n']['${namedField.recordFieldName!}']"),
const Code(')'),
const Code(','),
],
],
const Code(') as T'),
],
),
),
];
} else if ((className == ListKeyword.className ||
className == SetKeyword.className) &&
generics.length == 1) {
return [
MapEntry(
nullable
? refer('getType', serverpodUrl(serverCode))
.call([], {}, [reference(serverCode, config: config)])
: reference(serverCode, config: config),
Block.of([
nullable
? Block.of([
// using Code.scope only sets the generic to List
const Code('(data!=null?'
'(data as List).map((e) =>'
'deserialize<'),
generics.first.reference(serverCode, config: config).code,
Code('>(e))${className == 'Set' ? '.toSet()' : '.toList()'}'
':null) as T')
])
: Block.of([
const Code('(data as List).map((e) =>'
'deserialize<'),
generics.first.reference(serverCode, config: config).code,
Code(
'>(e))${className == 'Set' ? '.toSet()' : '.toList()'} as T'),
])
]),
),
...generics.first.generateDeserialization(serverCode, config: config),
];
} else if (className == MapKeyword.className && generics.length == 2) {
return [
MapEntry(
nullable
? refer('getType', serverpodUrl(serverCode))
.call([], {}, [reference(serverCode, config: config)])
: reference(serverCode, config: config),
Block.of([
generics.first.className == 'String'
? nullable
? Block.of([
// using Code.scope only sets the generic to List
const Code('(data!=null?'
'(data as Map).map((k,v) =>'
'MapEntry(deserialize<'),
generics.first
.reference(serverCode, config: config)
.code,
const Code('>(k),deserialize<'),
generics[1].reference(serverCode, config: config).code,
const Code('>(v)))' ':null) as T')
])
: Block.of([
// using Code.scope only sets the generic to List
const Code('(data as Map).map((k,v) =>'
'MapEntry(deserialize<'),
generics.first
.reference(serverCode, config: config)
.code,
const Code('>(k),deserialize<'),
generics[1].reference(serverCode, config: config).code,
const Code('>(v))) as T')
])
: // Key is not String -> stored as list of map entries
nullable
? Block.of([
// using Code.scope only sets the generic to List
const Code('(data!=null?'
'Map.fromEntries((data as List).map((e) =>'
'MapEntry(deserialize<'),
generics.first
.reference(serverCode, config: config)
.code,
const Code('>(e[\'k\']),deserialize<'),
generics[1].reference(serverCode, config: config).code,
const Code('>(e[\'v\']))))' ':null) as T')
])
: Block.of([
// using Code.scope only sets the generic to List
const Code('Map.fromEntries((data as List).map((e) =>'
'MapEntry(deserialize<'),
generics.first
.reference(serverCode, config: config)
.code,
const Code('>(e[\'k\']),deserialize<'),
generics[1].reference(serverCode, config: config).code,
const Code('>(e[\'v\'])))) as T')
])
]),
),
...generics.first.generateDeserialization(serverCode, config: config),
...generics[1].generateDeserialization(serverCode, config: config),
];
} else if (customClass) {
// This is the only place the customClass bool is used.
// It could be moved as we already know that we are working on custom classes
// when we generate the deserialization.
// But the additional functionality we get here is that we generate resolves for lists and maps
// if the custom class is used as a generic type. The day we create a more generic way to resolve generics
// in lists, maps, etc the customClass bool can be removed which will simplify the code.
return [
MapEntry(
nullable
? refer('getType', serverpodUrl(serverCode))
.call([], {}, [reference(serverCode, config: config)])
: reference(serverCode, config: config),
Code.scope((a) => nullable
? '(data!=null?'
'${a(reference(serverCode, config: config))}'
'.fromJson(data):null)as T'
: '${a(reference(serverCode, config: config))}'
'.fromJson(data) as T'))
];
} else {
return [];
}
}