All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sttp.client3.impl.cats.implicits.scala Maven / Gradle / Ivy

There is a newer version: 3.10.0
Show newest version
package sttp.client3.impl.cats

import cats.effect.{Concurrent, Sync}
import cats.~>
import sttp.capabilities.Effect
import sttp.client3.monad.{FunctionK, MapEffect}
import sttp.client3.{Identity, Request, Response, SttpBackend}
import sttp.monad.{MonadAsyncError, MonadError}

object implicits extends CatsImplicits

trait CatsImplicits extends LowerLevelCatsImplicits {
  implicit final def sttpBackendToCatsMappableSttpBackend[R[_], P](
      sttpBackend: SttpBackend[R, P]
  ): MappableSttpBackend[R, P] = new MappableSttpBackend(sttpBackend)

  implicit final def asyncMonadError[F[_]: Concurrent]: MonadAsyncError[F] = new CatsMonadAsyncError[F]
}

trait LowerLevelCatsImplicits {
  implicit final def monadError[F[_]: Sync]: MonadError[F] = new CatsMonadError[F]
}

final class MappableSttpBackend[F[_], P] private[cats] (
    private val sttpBackend: SttpBackend[F, P]
) extends AnyVal {
  def mapK[G[_]: MonadError](f: F ~> G, g: G ~> F): SttpBackend[G, P] =
    new MappedKSttpBackend(sttpBackend, f, g, implicitly)
}

private[cats] final class MappedKSttpBackend[F[_], +P, G[_]](
    wrapped: SttpBackend[F, P],
    f: F ~> G,
    g: G ~> F,
    val responseMonad: MonadError[G]
) extends SttpBackend[G, P] {
  def send[T, R >: P with Effect[G]](request: Request[T, R]): G[Response[T]] =
    f(
      wrapped.send(
        MapEffect[G, F, Identity, T, P](
          request: Request[T, P with Effect[G]],
          asFunctionK(g),
          asFunctionK(f),
          responseMonad,
          wrapped.responseMonad
        )
      )
    )

  def close(): G[Unit] = f(wrapped.close())

  private def asFunctionK[A[_], B[_]](ab: A ~> B) =
    new FunctionK[A, B] {
      override def apply[X](x: A[X]): B[X] = ab(x)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy