Skip to content

Commit

Permalink
added bodyEither directive
Browse files Browse the repository at this point in the history
  • Loading branch information
liviu.ungureanu committed Feb 11, 2020
1 parent 3d5ab50 commit 985c0a2
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
22 changes: 22 additions & 0 deletions core/src/main/scala/com/spingo/op_rabbit/Directives.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import scala.language.implicitConversions
import shapeless._
import com.spingo.op_rabbit.Binding._
import com.spingo.op_rabbit.Exchange.ExchangeType
import EnhancedTry._

import scala.util.{Failure, Success, Try}

Expand Down Expand Up @@ -179,6 +180,27 @@ trait Directives {
}
}

/**
Extract the message body as a Either. Uses a [[com.spingo.op_rabbit.RabbitUnmarshaller RabbitUnmarshaller]] to deserialize.
In case the body cannot be unmarshalled, the exception is present in the Left of the Either.
In this way the client code can have the unmarshalling error reason.
Example:
{{{
bodyOpt(as[JobDescription]) { jobDescriptionEither => ...
}
}}}
*/
def bodyEither[T](um: RabbitUnmarshaller[T]): Directive1[Either[Throwable, T]] = new Directive1[Either[Throwable, T]] {
def happly(fn: ::[Either[Throwable, T], HNil] => Handler): Handler = { (promise, delivery) =>
val dataTry = Try {
um.unmarshall(delivery.body, Option(delivery.properties.getContentType), Option(delivery.properties.getContentEncoding))
}

fn(dataTry.toEither :: HNil)(promise, delivery)
}
}

/**
Extract any arbitrary value from the delivery / Java RabbitMQ objects. Accepts a function which receives a Delivery and returns some value.
*/
Expand Down
10 changes: 10 additions & 0 deletions core/src/main/scala/com/spingo/op_rabbit/EnhancedTry.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.spingo.op_rabbit

import scala.util.{Success, Try}

object EnhancedTry {
implicit class EnhancedTryImpl[T](t: Try[T]) {
def toEither: Either[Throwable, T] =
t.transform(success => Success(Right(success)), exception => Success(Left(exception))).get
}
}
23 changes: 23 additions & 0 deletions core/src/test/scala/com/spingo/op_rabbit/DirectivesSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,29 @@ class DirectivesSpec extends FunSpec with Matchers with Inside {
}
} should be (acked)
}

it("yields the value for both directives when one is bodyEither") {
val delivery = testDelivery(body = "hi".getBytes, properties = Seq(ReplyTo("place")))
resultFor(delivery) {
(bodyEither(as[String]) & property(ReplyTo)) { (bodyEither, replyTo) =>
replyTo should be ("place")
bodyEither.right.get should be ("hi")
ack
}
} should be (acked)
}
}

describe("bodyEither") {
it("yields the value as an option") {
val delivery = testDelivery(body = "hi".getBytes)
resultFor(delivery) {
(bodyEither(as[String])) { (bodyEither) =>
bodyEither.right.get should be ("hi")
ack
}
} should be (acked)
}
}

describe("|") {
Expand Down

0 comments on commit 985c0a2

Please sign in to comment.