aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Nastich <nastich@users.noreply.github.com>2018-04-09 16:53:45 -0700
committerGitHub <noreply@github.com>2018-04-09 16:53:45 -0700
commit57ee8fa785c3815e45e473e5625d6e3cb1cd9402 (patch)
tree1c476db2e6ec44473ebfdea09cb284768549c40f
parentcc86f8d609969b40793a227b9af4b41a18657dfb (diff)
downloaddriver-core-57ee8fa785c3815e45e473e5625d6e3cb1cd9402.tar.gz
driver-core-57ee8fa785c3815e45e473e5625d6e3cb1cd9402.tar.bz2
driver-core-57ee8fa785c3815e45e473e5625d6e3cb1cd9402.zip
Add convenience methods to work with Tags: `taggedWith` wrapper and a proxy JSON format (#147)
* Add convenience methods to work with Tags: `tagged` wrapper and a proxy JSON format
-rw-r--r--src/main/scala/xyz/driver/core/core.scala4
-rw-r--r--src/main/scala/xyz/driver/core/json.scala12
-rw-r--r--src/test/scala/xyz/driver/core/JsonTest.scala14
3 files changed, 28 insertions, 2 deletions
diff --git a/src/main/scala/xyz/driver/core/core.scala b/src/main/scala/xyz/driver/core/core.scala
index be19f0f..14e1b10 100644
--- a/src/main/scala/xyz/driver/core/core.scala
+++ b/src/main/scala/xyz/driver/core/core.scala
@@ -25,6 +25,10 @@ package object core {
object tagging {
private[core] trait Tagged[+V, +Tag]
+
+ implicit class Taggable[V <: Any](val v: V) extends AnyVal {
+ def tagged[Tag]: V @@ Tag = v.asInstanceOf[V @@ Tag]
+ }
}
type @@[+V, +Tag] = V with tagging.Tagged[V, Tag]
diff --git a/src/main/scala/xyz/driver/core/json.scala b/src/main/scala/xyz/driver/core/json.scala
index 06a8837..e7efce6 100644
--- a/src/main/scala/xyz/driver/core/json.scala
+++ b/src/main/scala/xyz/driver/core/json.scala
@@ -34,16 +34,24 @@ object json {
}
}
- implicit def idFormat[T] = new RootJsonFormat[Id[T]] {
+ implicit def idFormat[T]: JsonFormat[Id[T]] = new JsonFormat[Id[T]] {
def write(id: Id[T]) = JsString(id.value)
- def read(value: JsValue) = value match {
+ def read(value: JsValue): Id[T] = value match {
case JsString(id) if Try(UUID.fromString(id)).isSuccess => Id[T](id.toLowerCase)
case JsString(id) => Id[T](id)
case _ => throw DeserializationException("Id expects string")
}
}
+ implicit def taggedFormat[F, T](implicit underlying: JsonFormat[F]): JsonFormat[F @@ T] = new JsonFormat[F @@ T] {
+ import tagging._
+
+ override def write(obj: F @@ T): JsValue = underlying.write(obj)
+
+ override def read(json: JsValue): F @@ T = underlying.read(json).tagged[T]
+ }
+
def NameInPath[T]: PathMatcher1[Name[T]] = new PathMatcher1[Name[T]] {
def apply(path: Path) = path match {
case Path.Segment(segment, tail) => Matched(tail, Tuple1(Name[T](segment)))
diff --git a/src/test/scala/xyz/driver/core/JsonTest.scala b/src/test/scala/xyz/driver/core/JsonTest.scala
index 7e8dba2..b845a44 100644
--- a/src/test/scala/xyz/driver/core/JsonTest.scala
+++ b/src/test/scala/xyz/driver/core/JsonTest.scala
@@ -13,6 +13,7 @@ import spray.json._
import xyz.driver.core.TestTypes.CustomGADT
import xyz.driver.core.domain.{Email, PhoneNumber}
import xyz.driver.core.json.enumeratum.HasJsonFormat
+import xyz.driver.core.tagging.Taggable
import xyz.driver.core.time.TimeOfDay
import scala.collection.immutable.IndexedSeq
@@ -31,6 +32,19 @@ class JsonTest extends FlatSpec with Matchers {
parsedId should be(referenceId)
}
+ "Json format for @@" should "read and write correct JSON" in {
+ trait Irrelevant
+ val reference = Id[JsonTest]("SomeID").tagged[Irrelevant]
+
+ val format = json.taggedFormat[Id[JsonTest], Irrelevant]
+
+ val writtenJson = format.write(reference)
+ writtenJson shouldBe JsString("SomeID")
+
+ val parsedId: Id[JsonTest] @@ Irrelevant = format.read(writtenJson)
+ parsedId shouldBe reference
+ }
+
"Json format for Name" should "read and write correct JSON" in {
val referenceName = Name[String]("Homer")