Skip to content

Commit

Permalink
Add Endpoint.mapK
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeykolbasov committed Sep 18, 2019
1 parent 42c4a2d commit 849ac41
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
17 changes: 16 additions & 1 deletion core/src/main/scala/io/finch/Endpoint.scala
@@ -1,6 +1,6 @@
package io.finch

import cats.{Alternative, Applicative, ApplicativeError, Id, Monad, MonadError}
import cats.{~>, Alternative, Applicative, ApplicativeError, Id, Monad, MonadError}
import cats.data._
import cats.effect._
import cats.syntax.all._
Expand Down Expand Up @@ -170,6 +170,21 @@ trait Endpoint[F[_], A] { self =>
final override def toString: String = self.toString
}

/**
* Transform effect of endpoint given natural transformation `F ~> G`
*/
final def mapK[G[_]](nat: F ~> G): Endpoint[G, A] =
new Endpoint[G, A] {
def apply(input: Input): Endpoint.Result[G, A] =
self(input) match {
case EndpointResult.Matched(rem, trc, out) => EndpointResult.Matched(rem, trc, nat(out))
case skipped: EndpointResult.NotMatched[F] => skipped.asInstanceOf[EndpointResult[G, A]]
}

final override def item = self.item
final override def toString: String = self.toString
}

/**
* Returns a product of this and `other` endpoint. The resulting endpoint returns a tuple
* of both values.
Expand Down
16 changes: 15 additions & 1 deletion core/src/test/scala/io/finch/EndpointSpec.scala
Expand Up @@ -3,12 +3,13 @@ package io.finch
import java.util.UUID
import java.util.concurrent.TimeUnit

import cats.data.NonEmptyList
import cats.data.{NonEmptyList, WriterT}
import cats.effect.{IO, Resource}
import cats.laws._
import cats.laws.discipline._
import cats.laws.discipline.AlternativeTests
import cats.laws.discipline.SemigroupalTests.Isomorphisms
import cats.~>
import com.twitter.finagle.http.{Cookie, Method, Request}
import com.twitter.io.Buf
import io.finch.data.Foo
Expand Down Expand Up @@ -411,4 +412,17 @@ class EndpointSpec extends FinchSpec {
asFunction.apply(p).attempt.unsafeRunSync() === Left(e)
}}
}

it should "transform F[_] to G[_] effect" in {
type W[A] = WriterT[IO, List[String], A]

check { (ep: Endpoint[IO, Int], input: Input) => {
val nat = new (IO ~> W) {
def apply[A](fa: IO[A]): WriterT[IO, List[String], A] = WriterT.liftF(fa)
}

ep.mapK(nat)(input).awaitOutput() === ep(input).awaitOutput()
}
}
}
}

0 comments on commit 849ac41

Please sign in to comment.