generateDeserialization method

List<MapEntry<Expression, Code>> generateDeserialization(
  1. bool serverCode, {
  2. required GeneratorConfig config,
})

Generates the constructors for List and Map types

Implementation

List<MapEntry<Expression, Code>> generateDeserialization(
  bool serverCode, {
  required GeneratorConfig config,
}) {
  if ((className == 'List' || className == 'Set') && 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 dynamic')
                ])
              : Block.of([
                  const Code('(data as List).map((e) =>'
                      'deserialize<'),
                  generics.first.reference(serverCode, config: config).code,
                  Code(
                      '>(e))${className == 'Set' ? '.toSet()' : '.toList()'} as dynamic'),
                ])
        ]),
      ),
      ...generics.first.generateDeserialization(serverCode, config: config),
    ];
  } else if (className == 'Map' && 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 dynamic')
                    ])
                  : 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 dynamic')
                    ])
              : // 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 dynamic')
                    ])
                  : 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 dynamic')
                    ])
        ]),
      ),
      ...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 [];
  }
}