package org.lyranthe.fs2_grpc package java_runtime package client import cats.effect._ import cats.effect.concurrent.{Deferred, Ref} import cats.implicits._ import io.grpc._ class Fs2UnaryClientCallListener[F[_], Response](grpcStatus: Deferred[F, GrpcStatus], value: Ref[F, Option[Response]])( implicit F: Effect[F] ) extends ClientCall.Listener[Response] { override def onClose(status: Status, trailers: Metadata): Unit = grpcStatus.complete(GrpcStatus(status, trailers)).unsafeRun() override def onMessage(message: Response): Unit = value.set(message.some).unsafeRun() def getValue: F[Response] = { for { r <- grpcStatus.get v <- value.get result <- { if (!r.status.isOk) F.raiseError(r.status.asRuntimeException(r.trailers)) else { v match { case None => F.raiseError( Status.INTERNAL .withDescription("No value received for unary call") .asRuntimeException(r.trailers) ) case Some(v1) => F.pure(v1) } } } } yield result } } object Fs2UnaryClientCallListener { def apply[F[_]: ConcurrentEffect, Response]: F[Fs2UnaryClientCallListener[F, Response]] = { (Deferred[F, GrpcStatus], Ref.of[F, Option[Response]](none)).mapN((response, value) => new Fs2UnaryClientCallListener[F, Response](response, value) ) } }