channel function

Expression channel(
  1. ClientType type, {
  2. required bool includeHasClosed,
})

Implementation

Expression channel(ClientType type, {required bool includeHasClosed}) {
  final channel = refer('channel').property('stream');
  final event = refer('utf8').property('decode').call([refer('event')]);

  final hasClosed = ifStatement(
    refer('hasClosed'),
    body: refer('break').statement,
  ).code;

  final fromJson = parseJson(
    type,
    event,
    yield: true,
    postYieldCode: [if (includeHasClosed) hasClosed],
  );

  if (fromJson == null && type.isBytes) {
    return CodeExpression(
      switch (type) {
        ClientType(typeArguments: [ClientType(isNullable: true)]) =>
          channel.property('map').call([
            Method(
              (b) => b
                ..lambda = true
                ..requiredParameters.add(Parameter((e) => e..name = 'e'))
                ..body = createSwitchPattern(refer('e'), {
                  literal([]): literalNull,
                  declareFinal('value'): refer('value'),
                }).code,
            ).closure,
          ]),
        _ => channel.property('cast').call([]),
      }.yieldedStar.statement,
    );
  }

  return forInLoop(
    declaration: declareFinal('event'),
    iterable: channel,
    body: switch (type) {
      ClientType(isStringContent: true, :final isNullable) ||
      ClientType(
        typeArguments: [ClientType(isStringContent: true, :final isNullable)],
      ) when fromJson == null => switch (isNullable) {
        true => Block.of([
          ifStatement(
            refer('event'),
            pattern: (cse: literal([]), when: null),
            body: Block.of([
              literalNull.yielded.statement,
              refer('continue').statement,
            ]),
          ).code,
          const Code(''),
          event.yielded.statement,
          if (includeHasClosed) ...[const Code(''), hasClosed],
        ]),
        false => Block.of([
          event.yielded.statement,
          if (includeHasClosed) ...[const Code(''), hasClosed],
        ]),
      },
      _ => fromJson,
    },
  ).awaited;
}