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

com.malliina.http.io.HttpClientIO.scala Maven / Gradle / Ivy

The newest version!
package com.malliina.http.io

import cats.MonadError
import cats.effect.implicits.monadCancelOps_
import cats.effect.{Async, IO, Sync}
import cats.effect.kernel.Resource
import com.malliina.http.io.HttpClientIO.CallOps
import com.malliina.http.{FullUrl, HttpClient, OkClient, OkHttpBackend, OkHttpResponse}
import okhttp3._

import java.io.IOException

object HttpClientIO {
  def resource[F[_]: Async]: Resource[F, HttpClientF2[F]] =
    Resource.make(Async[F].delay(new HttpClientF2()))(c => Async[F].delay(c.close()))

  def apply(http: OkHttpClient = OkClient.okHttpClient): HttpClientIO = new HttpClientIO(http)

  implicit class CallOps(val call: Call) extends AnyVal {
    def io[F[_]: Async]: F[Response] = run(call)
  }

  def run[F[_]: Async](call: Call): F[Response] = Async[F].async_ { cb =>
    call.enqueue(new Callback {
      override def onResponse(call: Call, response: Response): Unit = {
        cb(Right(response))
      }

      override def onFailure(call: Call, e: IOException): Unit =
        cb(Left(e))
    })
  }
}

class HttpClientIO(client: OkHttpClient) extends HttpClientF2[IO](client)

class HttpClientF2[F[_]: Async](val client: OkHttpClient = OkClient.okHttpClient)
  extends HttpClientF[F]
  with OkHttpBackend {
  override def streamed[T](request: Request)(consume: Response => F[T]): F[T] =
    raw(request).bracket(consume)(r => Sync[F].delay(r.close()))
  override def raw(request: Request): F[Response] =
    client.newCall(request).io
  def socket(
    url: FullUrl,
    headers: Map[String, String]
  ): Resource[F, WebSocketF[F]] = WebSocketF.build(url, headers, client)
}

abstract class HttpClientF[F[_]]()(implicit F: MonadError[F, Throwable]) extends HttpClient[F] {
  override def execute(request: Request): F[OkHttpResponse] =
    F.map(raw(request))(OkHttpResponse.apply)
  override def flatMap[T, U](t: F[T])(f: T => F[U]): F[U] = F.flatMap(t)(f)
  override def success[T](t: T): F[T] = F.pure(t)
  override def fail[T](e: Exception): F[T] = F.raiseError(e)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy