Skip to content

Commit

Permalink
Merge pull request #947 from geirolz/add-decoder-attempt
Browse files Browse the repository at this point in the history
Add decoder attempt instance
  • Loading branch information
geirolz committed May 30, 2024
2 parents adf1d5b + 920b3cb commit 9523d6e
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
*/

package dev.profunktor.fs2rabbit.effects
import cats.{Applicative, ApplicativeThrow}
import cats.{Applicative, ApplicativeError, ApplicativeThrow, MonadError}
import cats.data.Kleisli
import dev.profunktor.fs2rabbit.model.{AmqpFieldValue, AmqpProperties, ExchangeName, RoutingKey}
import dev.profunktor.fs2rabbit.model.AmqpFieldValue._
import cats.implicits._

object EnvelopeDecoder {
object EnvelopeDecoder extends EnvelopeDecoderInstances {

def apply[F[_], A](implicit e: EnvelopeDecoder[F, A]): EnvelopeDecoder[F, A] = e

def properties[F[_]: Applicative]: EnvelopeDecoder[F, AmqpProperties] =
Expand Down Expand Up @@ -81,3 +82,16 @@ object EnvelopeDecoder {
): EnvelopeDecoder[F, Option[A]] =
Kleisli(_.properties.headers.get(name).traverse(h => F.catchNonFatal(pf(h))))
}

sealed trait EnvelopeDecoderInstances {

implicit def decoderAttempt[F[_], E: ApplicativeError[F, *], A](implicit
decoder: EnvelopeDecoder[F, A]
): EnvelopeDecoder[F, Either[E, A]] =
decoder.attempt

implicit def decoderOption[F[_], E: ApplicativeError[F, *], A](implicit
decoder: EnvelopeDecoder[F, A]
): EnvelopeDecoder[F, Option[A]] =
decoder.attempt.map(_.toOption)
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@ import cats.effect.unsafe.implicits.global

class EnvelopeDecoderSpec extends AsyncFunSuite {

import EnvelopeDecoder._
// Available instances of EnvelopeDecoder for any ApplicativeError[F, Throwable]
EnvelopeDecoder[Either[Throwable, *], String]
EnvelopeDecoder[SyncIO, String]
EnvelopeDecoder[EitherT[IO, String, *], String]
EnvelopeDecoder[Try, String]
EnvelopeDecoder[Try, Option[String]]
EnvelopeDecoder[Try, Either[Throwable, String]]

test("should decode a UTF-8 string") {
val msg = "hello world!"
Expand Down Expand Up @@ -86,4 +89,32 @@ class EnvelopeDecoderSpec extends AsyncFunSuite {
.unsafeToFuture()
}

test("should decode a UTF-8 string - Attempt") {
val msg = "hello world!"
val raw = msg.getBytes(StandardCharsets.UTF_8)

EnvelopeDecoder[IO, Either[Throwable, String]]
.run(
AmqpEnvelope(DeliveryTag(0L), raw, AmqpProperties.empty, ExchangeName("test"), RoutingKey("test.route"), false)
)
.flatMap { result =>
IO(assert(result == Right(msg)))
}
.unsafeToFuture()
}

test("should decode a UTF-8 string - Attempt option") {
val msg = "hello world!"
val raw = msg.getBytes(StandardCharsets.UTF_8)

EnvelopeDecoder[IO, Option[String]]
.run(
AmqpEnvelope(DeliveryTag(0L), raw, AmqpProperties.empty, ExchangeName("test"), RoutingKey("test.route"), false)
)
.flatMap { result =>
IO(assert(result == Option(msg)))
}
.unsafeToFuture()
}

}

0 comments on commit 9523d6e

Please sign in to comment.