|
| 1 | +package com.github.plokhotnyuk.jsoniter_scala.macros |
| 2 | + |
| 3 | +import com.epam.deltix.dfp.{Decimal64, Decimal64Utils} |
| 4 | +import com.github.plokhotnyuk.jsoniter_scala.core._ |
| 5 | +import com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMaker._ |
| 6 | + |
| 7 | +class JsonCodecMakerDecimal64Spec extends VerifyingSpec { |
| 8 | + import Decimal64Codec._ |
| 9 | + |
| 10 | + "Decimal64Codec" should { |
| 11 | + "deserialize both numeric and string representation of numbers to canonized Decimal64 values" in { |
| 12 | + verifyDeser(make[List[Decimal64]], |
| 13 | + List(Decimal64.ONE_TENTH, Decimal64.MILLION, Decimal64.fromLong(4503599627370497L), Decimal64.parse("1.23456789e+309"), Decimal64.MAX_VALUE), |
| 14 | + """[0.1,"001000000",4503599627370497,1.23456789e+309,"9999999999999999e+369"]""") |
| 15 | + } |
| 16 | + "serialize Decimal64 values into numeric or string representation depending on number of mantissa bits of canonized in-memory representation" in { |
| 17 | + verifySer(make[List[Decimal64]], |
| 18 | + List(Decimal64.ONE_TENTH, Decimal64.MILLION, Decimal64.fromLong(4503599627370497L), Decimal64.parse("1.23456789e+309"), Decimal64.MAX_VALUE), |
| 19 | + """[0.1,1E+6,"4503599627370497","1.23456789E+309","9.999999999999999E+384"]""") |
| 20 | + } |
| 21 | + } |
| 22 | +} |
| 23 | + |
| 24 | +object Decimal64Codec { |
| 25 | + implicit val codec: JsonValueCodec[Decimal64] = new JsonValueCodec[Decimal64] { |
| 26 | + override def decodeValue(in: JsonReader, default: Decimal64): Decimal64 = |
| 27 | + Decimal64.fromUnderlying(Decimal64Utils.canonize(Decimal64Utils.fromBigDecimal((if (in.isNextToken('"')) { |
| 28 | + in.rollbackToken() |
| 29 | + in.readStringAsBigDecimal(null) |
| 30 | + } else { |
| 31 | + in.rollbackToken() |
| 32 | + in.readBigDecimal(null) |
| 33 | + }).bigDecimal))) |
| 34 | + |
| 35 | + override def encodeValue(x: Decimal64, out: JsonWriter): Unit = { |
| 36 | + val cx = Decimal64Utils.canonize(Decimal64.toUnderlying(x)) |
| 37 | + val bd = new BigDecimal(Decimal64Utils.toBigDecimal(cx)) |
| 38 | + val m = Decimal64Utils.getUnscaledValue(cx) |
| 39 | + val s = Decimal64Utils.getScale(cx) |
| 40 | + if (m >= -4503599627370496L && m <= 4503599627370496L && s >= -256 && s <= 256) out.writeVal(bd) |
| 41 | + else out.writeValAsString(bd) |
| 42 | + } |
| 43 | + |
| 44 | + override def nullValue: Decimal64 = null |
| 45 | + } |
| 46 | +} |
0 commit comments