From 4e903b7bd19dd9daf7172ab06fe2e52b6b1fdb60 Mon Sep 17 00:00:00 2001 From: Sergey Nastich Date: Tue, 21 Aug 2018 18:17:13 -0400 Subject: Add json formats for country code and currency code (#197) --- src/main/scala/xyz/driver/core/json.scala | 11 +++++++++ src/test/scala/xyz/driver/core/JsonTest.scala | 34 +++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/main/scala/xyz/driver/core/json.scala b/src/main/scala/xyz/driver/core/json.scala index 959239e..e4a0cef 100644 --- a/src/main/scala/xyz/driver/core/json.scala +++ b/src/main/scala/xyz/driver/core/json.scala @@ -8,6 +8,7 @@ import akka.http.scaladsl.model.Uri.Path import akka.http.scaladsl.server.PathMatcher.{Matched, Unmatched} import akka.http.scaladsl.server._ import akka.http.scaladsl.unmarshalling.Unmarshaller +import com.neovisionaries.i18n.{CountryCode, CurrencyCode} import enumeratum._ import eu.timepit.refined.api.{Refined, Validate} import eu.timepit.refined.collection.NonEmpty @@ -19,6 +20,7 @@ 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.util.Try @@ -234,6 +236,10 @@ object json { JsString(obj.getHostAddress) } + implicit val countryCodeFormat: JsonFormat[CountryCode] = javaEnumFormat[CountryCode] + + implicit val currencyCodeFormat: JsonFormat[CurrencyCode] = javaEnumFormat[CurrencyCode] + object enumeratum { def enumUnmarshaller[T <: EnumEntry](enum: Enum[T]): Unmarshaller[String, T] = @@ -281,6 +287,11 @@ object json { } } + def javaEnumFormat[T <: java.lang.Enum[_]: ClassTag]: JsonFormat[T] = { + val values = classTag[T].runtimeClass.asInstanceOf[Class[T]].getEnumConstants + new EnumJsonFormat[T](values.map(v => v.name() -> v): _*) + } + class ValueClassFormat[T: TypeTag](writeValue: T => BigDecimal, create: BigDecimal => T) extends JsonFormat[T] { def write(valueClass: T) = JsNumber(writeValue(valueClass)) def read(json: JsValue): T = json match { diff --git a/src/test/scala/xyz/driver/core/JsonTest.scala b/src/test/scala/xyz/driver/core/JsonTest.scala index 2c85560..330f6ed 100644 --- a/src/test/scala/xyz/driver/core/JsonTest.scala +++ b/src/test/scala/xyz/driver/core/JsonTest.scala @@ -2,11 +2,12 @@ package xyz.driver.core import java.net.InetAddress +import com.neovisionaries.i18n.{CountryCode, CurrencyCode} import enumeratum._ import eu.timepit.refined.collection.NonEmpty import eu.timepit.refined.numeric.Positive import eu.timepit.refined.refineMV -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.{FlatSpec, Inspectors, Matchers} import xyz.driver.core.json._ import xyz.driver.core.time.provider.SystemTimeProvider import spray.json._ @@ -19,7 +20,7 @@ import xyz.driver.core.time.TimeOfDay import scala.collection.immutable.IndexedSeq -class JsonTest extends FlatSpec with Matchers { +class JsonTest extends FlatSpec with Matchers with Inspectors { import DefaultJsonProtocol._ "Json format for Id" should "read and write correct JSON" in { @@ -348,4 +349,33 @@ class JsonTest extends FlatSpec with Matchers { written should be("{\"identifier\":\"someone@nowhere.com\",\"password\":\"nopassword\"}".parseJson) } + + "CountryCode format" should "read and write correct JSON" in { + val samples = Seq( + "US" -> CountryCode.US, + "CN" -> CountryCode.CN, + "AT" -> CountryCode.AT + ) + + forAll(samples) { + case (serialized, enumValue) => + countryCodeFormat.write(enumValue) shouldBe JsString(serialized) + countryCodeFormat.read(JsString(serialized)) shouldBe enumValue + } + } + + "CurrencyCode format" should "read and write correct JSON" in { + val samples = Seq( + "USD" -> CurrencyCode.USD, + "CNY" -> CurrencyCode.CNY, + "EUR" -> CurrencyCode.EUR + ) + + forAll(samples) { + case (serialized, enumValue) => + currencyCodeFormat.write(enumValue) shouldBe JsString(serialized) + currencyCodeFormat.read(JsString(serialized)) shouldBe enumValue + } + } + } -- cgit v1.2.3