From ccd6c4281fb0ddd0a74b79aa24f85834f5c9647a Mon Sep 17 00:00:00 2001 From: Sergey Nastich Date: Mon, 10 Sep 2018 19:05:58 -0400 Subject: Add `@@ Trimmed` tag for Strings and Names to support by JSON readers (#211) --- src/main/scala/xyz/driver/core/core.scala | 10 ++++++++++ src/main/scala/xyz/driver/core/json.scala | 15 +++++++++------ src/test/scala/xyz/driver/core/JsonTest.scala | 15 +++++++++++++++ src/test/scala/xyz/driver/core/TimeTest.scala | 1 + 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/main/scala/xyz/driver/core/core.scala b/src/main/scala/xyz/driver/core/core.scala index a654e85..846bed3 100644 --- a/src/main/scala/xyz/driver/core/core.scala +++ b/src/main/scala/xyz/driver/core/core.scala @@ -128,4 +128,14 @@ package core { } final case class Base64(value: String) + + trait Trimmed + + object Trimmed { + import tagging._ + + implicit def string2Trimmed(str: String): String @@ Trimmed = str.trim().tagged[Trimmed] + + implicit def name2Trimmed[T](name: Name[T]): Name[T] @@ Trimmed = Name[T](name.value.trim()).tagged[Trimmed] + } } diff --git a/src/main/scala/xyz/driver/core/json.scala b/src/main/scala/xyz/driver/core/json.scala index 98725fb..d9319e9 100644 --- a/src/main/scala/xyz/driver/core/json.scala +++ b/src/main/scala/xyz/driver/core/json.scala @@ -22,8 +22,8 @@ import xyz.driver.core.domain.{Email, PhoneNumber} import xyz.driver.core.rest.errors._ import xyz.driver.core.time.{Time, TimeOfDay} -import scala.reflect.{ClassTag, classTag} import scala.reflect.runtime.universe._ +import scala.reflect.{ClassTag, classTag} import scala.util.Try import scala.util.control.NonFatal @@ -56,13 +56,16 @@ object json { } } - implicit def taggedFormat[F, T](implicit underlying: JsonFormat[F]): JsonFormat[F @@ T] = new JsonFormat[F @@ T] { - import tagging._ + implicit def taggedFormat[F, T](implicit underlying: JsonFormat[F], convert: F => F @@ T = null): JsonFormat[F @@ T] = + new JsonFormat[F @@ T] { + import tagging._ - override def write(obj: F @@ T): JsValue = underlying.write(obj) + private val transformReadValue = Option(convert).getOrElse((_: F).tagged[T]) - override def read(json: JsValue): F @@ T = underlying.read(json).tagged[T] - } + override def write(obj: F @@ T): JsValue = underlying.write(obj) + + override def read(json: JsValue): F @@ T = transformReadValue(underlying.read(json)) + } def NameInPath[T]: PathMatcher1[Name[T]] = new PathMatcher1[Name[T]] { def apply(path: Path) = path match { diff --git a/src/test/scala/xyz/driver/core/JsonTest.scala b/src/test/scala/xyz/driver/core/JsonTest.scala index 49098fa..9a079b2 100644 --- a/src/test/scala/xyz/driver/core/JsonTest.scala +++ b/src/test/scala/xyz/driver/core/JsonTest.scala @@ -53,6 +53,13 @@ class JsonTest extends WordSpec with Matchers with Inspectors { val parsedId: Id[JsonTest] @@ Irrelevant = format.read(writtenJson) parsedId shouldBe reference } + + "read and write correct JSON when there's an implicit conversion defined" in { + JsString(" some string ").convertTo[String @@ Trimmed] shouldBe "some string" + + val trimmed: String @@ Trimmed = " some string " + trimmed.toJson shouldBe JsString("some string") + } } "Json format for Name" should { @@ -66,6 +73,14 @@ class JsonTest extends WordSpec with Matchers with Inspectors { val parsedName = json.nameFormat.read(writtenJson) parsedName should be(referenceName) } + + "read and write correct JSON for Name @@ Trimmed" in { + trait Irrelevant + JsString(" some name ").convertTo[Name[Irrelevant] @@ Trimmed] shouldBe Name[Irrelevant]("some name") + + val trimmed: Name[Irrelevant] @@ Trimmed = Name(" some name ") + trimmed.toJson shouldBe JsString("some name") + } } "Json format for NonEmptyName" should { diff --git a/src/test/scala/xyz/driver/core/TimeTest.scala b/src/test/scala/xyz/driver/core/TimeTest.scala index 7a888b6..1019f60 100644 --- a/src/test/scala/xyz/driver/core/TimeTest.scala +++ b/src/test/scala/xyz/driver/core/TimeTest.scala @@ -11,6 +11,7 @@ import xyz.driver.core.date.Month import xyz.driver.core.time.{Time, _} import scala.concurrent.duration._ +import scala.language.postfixOps class TimeTest extends FlatSpec with Matchers with Checkers { -- cgit v1.2.3