middlewareContent function

String middlewareContent(
  1. ServerLifecycleComponent component,
  2. String formatter(
    1. Spec
    )
)

Implementation

String middlewareContent(
  ServerLifecycleComponent component,
  String Function(Spec) formatter,
) {
  final (:positioned, :named) = getParams(
    component.params,
    defaultExpression: createGetFromDi(),
    useField: true,
  );

  final parameter = createConstructorParameters(component.params);
  final fields = createFields(component.params);
  final generics = createGenerics(component.genericTypes);

  final clazz = Class(
    (p) => p
      ..name = component.middlewareClass.className
      ..implements.add(refer((Middleware).name))
      ..constructors.add(
        Constructor(
          (p) => p
            ..constant = true
            ..requiredParameters.add(
              Parameter(
                (p) => p
                  ..name = 'di'
                  ..toThis = true
                  ..named = false,
              ),
            )
            ..optionalParameters.addAll(parameter),
        ),
      )
      ..types.addAll(generics)
      ..fields.add(
        Field(
          (p) => p
            ..type = refer('DI')
            ..name = 'di'
            ..modifier = FieldModifier.final$,
        ),
      )
      ..fields.addAll(fields)
      ..methods.add(
        Method(
          (p) => p
            ..name = 'use'
            ..returns = refer('Future<${(MiddlewareResult).name}>')
            ..modifier = MethodModifier.async
            ..annotations.add(refer('override'))
            ..requiredParameters.add(
              Parameter(
                (p) => p
                  ..name = 'context'
                  ..type = refer((Context).name),
              ),
            )
            ..body = Block.of([
              declareFinal('component')
                  .assign(refer(component.name).newInstance(positioned, named))
                  .statement,
              const Code('\n'),
              declareFinal('middlewares')
                  .assign(
                    literalList(
                      [...createComponentMethods(component.middlewares)],
                      refer('FutureOr<${(MiddlewareResult).name}> Function()'),
                    ),
                  )
                  .statement,
              const Code('\n'),
              forInLoop(
                declaration: declareFinal('middleware'),
                iterable: refer('middlewares'),
                body: Block.of([
                  declareFinal('result')
                      .assign(
                        createSwitchPattern(refer('middleware').call([]), {
                          declareFinal(
                            'future',
                            type: refer('Future<${(MiddlewareResult).name}>'),
                          ): refer(
                            'future',
                          ),
                          declareFinal(
                            'result',
                            type: refer((MiddlewareResult).name),
                          ): refer(
                            'Future',
                          ).property('value').call([refer('result')]),
                        }).awaited,
                      )
                      .statement,
                  const Code('\n'),
                  ifStatement(
                    refer('result').property('isStop'),
                    body: refer('result').returned.statement,
                  ).code,
                ]),
              ).code,
              const Code('\n'),
              declareConst(
                (MiddlewareResult).name,
              ).property('next').call([]).returned.statement,
            ]),
        ),
      ),
  );

  return formatter(clazz);
}