diff options
author | Bjørn Madsen <bm@aeons.dk> | 2017-08-04 10:21:30 +0200 |
---|---|---|
committer | Bjørn Madsen <bm@aeons.dk> | 2017-08-04 10:28:10 +0200 |
commit | 24f6fac2f4ca3a82eb776a8756a16785716489f8 (patch) | |
tree | 7ae32664d823913be38d5d8eb4c5d9eef1111559 | |
parent | c81487ff2c6d0a4a886ac9ceb7a7a89a39eb5c88 (diff) | |
download | sttp-24f6fac2f4ca3a82eb776a8756a16785716489f8.tar.gz sttp-24f6fac2f4ca3a82eb776a8756a16785716489f8.tar.bz2 sttp-24f6fac2f4ca3a82eb776a8756a16785716489f8.zip |
Add support for cats effect with AHC backend
4 files changed, 80 insertions, 1 deletions
diff --git a/async-http-client-handler/cats/src/main/scala/com/softwaremill/sttp/asynchttpclient/cats/CatsAsyncHttpClientHandler.scala b/async-http-client-handler/cats/src/main/scala/com/softwaremill/sttp/asynchttpclient/cats/CatsAsyncHttpClientHandler.scala new file mode 100644 index 0000000..cfd9c5b --- /dev/null +++ b/async-http-client-handler/cats/src/main/scala/com/softwaremill/sttp/asynchttpclient/cats/CatsAsyncHttpClientHandler.scala @@ -0,0 +1,61 @@ +package com.softwaremill.sttp.asynchttpclient.cats + +import java.nio.ByteBuffer + +import cats.effect._ +import com.softwaremill.sttp.asynchttpclient.AsyncHttpClientHandler +import com.softwaremill.sttp.{MonadAsyncError, SttpHandler} +import org.asynchttpclient.{ + AsyncHttpClient, + AsyncHttpClientConfig, + DefaultAsyncHttpClient +} +import org.reactivestreams.Publisher + +import scala.language.higherKinds + +class CatsAsyncHttpClientHandler[F[_]: Async](asyncHttpClient: AsyncHttpClient, + closeClient: Boolean) + extends AsyncHttpClientHandler[F, Nothing](asyncHttpClient, + new AsyncMonad, + closeClient) { + override protected def streamBodyToPublisher( + s: Nothing): Publisher[ByteBuffer] = s // nothing is everything + + override protected def publisherToStreamBody( + p: Publisher[ByteBuffer]): Nothing = + throw new IllegalStateException("This handler does not support streaming") +} + +object CatsAsyncHttpClientHandler { + + def apply[F[_]: Async](): SttpHandler[F, Nothing] = + new CatsAsyncHttpClientHandler(new DefaultAsyncHttpClient(), + closeClient = true) + + def usingConfig[F[_]: Async]( + cfg: AsyncHttpClientConfig): SttpHandler[F, Nothing] = + new CatsAsyncHttpClientHandler(new DefaultAsyncHttpClient(cfg), + closeClient = true) + + def usingClient[F[_]: Async]( + client: AsyncHttpClient): SttpHandler[F, Nothing] = + new CatsAsyncHttpClientHandler(client, closeClient = false) +} + +private[cats] class AsyncMonad[F[_]](implicit F: Async[F]) + extends MonadAsyncError[F] { + + override def async[T]( + register: ((Either[Throwable, T]) => Unit) => Unit): F[T] = + F.async(register) + + override def unit[T](t: T): F[T] = F.pure(t) + + override def map[T, T2](fa: F[T], f: (T) => T2): F[T2] = F.map(fa)(f) + + override def flatMap[T, T2](fa: F[T], f: (T) => F[T2]): F[T2] = + F.flatMap(fa)(f) + + override def error[T](t: Throwable): F[T] = F.raiseError(t) +} @@ -105,6 +105,16 @@ lazy val monixAsyncHttpClientHandler: Project = (project in file( ) ) dependsOn asyncHttpClientHandler +lazy val catsAsyncHttpClientHandler: Project = (project in file( + "async-http-client-handler/cats")) + .settings(commonSettings: _*) + .settings( + name := "async-http-client-handler-cats", + libraryDependencies ++= Seq( + "org.typelevel" %% "cats-effect" % "0.4" + ) + ) dependsOn asyncHttpClientHandler + lazy val okhttpClientHandler: Project = (project in file( "okhttp-client-handler")) .settings(commonSettings: _*) @@ -129,4 +139,4 @@ lazy val tests: Project = (project in file("tests")) ).map(_ % "test"), libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value % "test" ) dependsOn (core, akkaHttpHandler, futureAsyncHttpClientHandler, scalazAsyncHttpClientHandler, -monixAsyncHttpClientHandler, okhttpClientHandler) +monixAsyncHttpClientHandler, catsAsyncHttpClientHandler, okhttpClientHandler) diff --git a/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala b/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala index 5f17a7a..36c82ef 100644 --- a/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala +++ b/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala @@ -16,6 +16,7 @@ import com.typesafe.scalalogging.StrictLogging import org.scalatest.concurrent.{IntegrationPatience, ScalaFutures} import org.scalatest.{BeforeAndAfterAll, FlatSpec, Matchers} import better.files._ +import com.softwaremill.sttp.asynchttpclient.cats.CatsAsyncHttpClientHandler import com.softwaremill.sttp.asynchttpclient.future.FutureAsyncHttpClientHandler import com.softwaremill.sttp.asynchttpclient.monix.MonixAsyncHttpClientHandler import com.softwaremill.sttp.asynchttpclient.scalaz.ScalazAsyncHttpClientHandler @@ -130,6 +131,9 @@ class BasicTests ForceWrappedValue.scalazTask) runTests("Async Http Client - Monix")(MonixAsyncHttpClientHandler(), ForceWrappedValue.monixTask) + runTests("Async Http Client - Cats Effect")( + CatsAsyncHttpClientHandler[cats.effect.IO](), + ForceWrappedValue.catsIo) runTests("OkHttpSyncClientHandler")(OkHttpSyncClientHandler(), ForceWrappedValue.id) runTests("OkHttpSyncClientHandler - Future")(OkHttpFutureClientHandler(), diff --git a/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala b/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala index 9bf68bb..558e9dd 100644 --- a/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala +++ b/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala @@ -53,6 +53,10 @@ trait ForceWrapped extends ScalaFutures { this: Suite => override def force[T](wrapped: monix.eval.Task[T]): T = wrapped.runAsync.futureValue } + val catsIo = new ForceWrappedValue[cats.effect.IO] { + override def force[T](wrapped: cats.effect.IO[T]): T = + wrapped.unsafeRunSync + } } implicit class ForceDecorator[R[_], T](wrapped: R[T]) { def force()(implicit fwv: ForceWrappedValue[R]): T = fwv.force(wrapped) |