parseJson function

Code? parseJson(
  1. ClientType type,
  2. Expression variable, {
  3. bool yield = false,
  4. List<Code> postYieldCode = const [],
})

Implementation

Code? parseJson(
  ClientType type,
  Expression variable, {
  bool yield = false,
  List<Code> postYieldCode = const [],
}) {
  if (type.isStringContent) {
    return null;
  }

  if (type.isBytes) {
    return null;
  }

  if (shouldDecodeJson(type) case false) {
    final fromJson = switch (createReturnTypeFromJson(type, variable)) {
      final e? when yield => e.yielded.statement,
      final e? => e.returned.statement,
      _ => null,
    };

    if (fromJson == null) {
      return null;
    }

    return Block.of([
      fromJson,
      if (yield && postYieldCode.isNotEmpty) ...[
        const Code(''),
        ...postYieldCode,
      ],
    ]);
  }

  final data = refer('data');

  final body = switch (createReturnTypeFromJson(type, data)) {
    final e? => e,
    _ => data,
  };

  return CodeExpression(
    Block.of([
      ifStatement(
        switch (type) {
          ClientType(
            isStream: true,
            typeArguments: [ClientType(isStringContent: true)],
          ) =>
            variable,
          _ => refer('jsonDecode').call([variable]),
        },
        pattern: (cse: createJsonCase(type), when: null),
        body: switch (yield) {
          true => Block.of([
            body.yielded.statement,
            if (postYieldCode.isNotEmpty) ...[const Code(''), ...postYieldCode],
            const Code(''),
            refer('continue').statement,
          ]),
          false => Block.of([
            if (type.isNullable && !type.isIterable)
              createSwitchPattern(refer('data'), {
                literalNull: literalNull,
                declareFinal('data'): body,
              }).returned.statement
            else
              body.returned.statement,
          ]),
        },
      ).code,
      const Code(''),
      refer(
        (Exception).name,
      ).newInstance([literalString('Invalid response')]).thrown.statement,
    ]),
  ).code;
}