diff --git a/.github/workflows/scala.yml b/.github/workflows/scala.yml index 17c4ee84..ba202ee8 100644 --- a/.github/workflows/scala.yml +++ b/.github/workflows/scala.yml @@ -26,6 +26,9 @@ jobs: - name: Test run: sbt ++${{matrix.scala}} test + + - name: Fmt + run: sbt "scalafmtCheckAll;scalafmtSbtCheck" publish: name: Publish Artifacts diff --git a/modules/circe/src/main/scala/io.circe/JsonNumberHack.scala b/modules/circe/src/main/scala/io.circe/JsonNumberHack.scala index a4f78dea..950cdcfc 100644 --- a/modules/circe/src/main/scala/io.circe/JsonNumberHack.scala +++ b/modules/circe/src/main/scala/io.circe/JsonNumberHack.scala @@ -4,7 +4,7 @@ import tethys.writers.tokens.TokenWriter trait JsonNumberHack { protected def writeNumber(number: JsonNumber, writer: TokenWriter): Unit = { - if(JsonNumberHack.isHackCompatible) { + if (JsonNumberHack.isHackCompatible) { number match { case value: JsonDecimal => writer.writeRawJson(value.toString) @@ -27,17 +27,18 @@ trait JsonNumberHack { } object JsonNumberHack { - private val isHackCompatible: Boolean = try { - val loader = getClass.getClassLoader - loader.loadClass("io.circe.BiggerDecimalJsonNumber") - loader.loadClass("io.circe.JsonDecimal") - loader.loadClass("io.circe.JsonBiggerDecimal") - loader.loadClass("io.circe.JsonBigDecimal") - loader.loadClass("io.circe.JsonLong") - loader.loadClass("io.circe.JsonDouble") - loader.loadClass("io.circe.JsonFloat") - true - } catch { - case _: ClassNotFoundException => false - } + private val isHackCompatible: Boolean = + try { + val loader = getClass.getClassLoader + loader.loadClass("io.circe.BiggerDecimalJsonNumber") + loader.loadClass("io.circe.JsonDecimal") + loader.loadClass("io.circe.JsonBiggerDecimal") + loader.loadClass("io.circe.JsonBigDecimal") + loader.loadClass("io.circe.JsonLong") + loader.loadClass("io.circe.JsonDouble") + loader.loadClass("io.circe.JsonFloat") + true + } catch { + case _: ClassNotFoundException => false + } } diff --git a/modules/circe/src/main/scala/tethys/circe/ast/CirceSupport.scala b/modules/circe/src/main/scala/tethys/circe/ast/CirceSupport.scala index d9456ff0..e5b286f9 100644 --- a/modules/circe/src/main/scala/tethys/circe/ast/CirceSupport.scala +++ b/modules/circe/src/main/scala/tethys/circe/ast/CirceSupport.scala @@ -8,59 +8,73 @@ import tethys.{JsonObjectWriter, JsonReader, JsonWriter} import tethys.writers.tokens.TokenWriter trait CirceSupport { - implicit lazy val circeJsonObjectWriter: JsonWriter[JsonObject] = new JsonObjectWriter[JsonObject] { - def writeValues(value: JsonObject, writer: TokenWriter): Unit = { - val folder = new TethysJsonFolder(writer) - val it = value.toIterable.iterator - while (it.hasNext) { - val (k, v) = it.next() - - writer.writeFieldName(k) - v.foldWith(folder) + implicit lazy val circeJsonObjectWriter: JsonWriter[JsonObject] = + new JsonObjectWriter[JsonObject] { + def writeValues(value: JsonObject, writer: TokenWriter): Unit = { + val folder = new TethysJsonFolder(writer) + val it = value.toIterable.iterator + while (it.hasNext) { + val (k, v) = it.next() + + writer.writeFieldName(k) + v.foldWith(folder) + } } } - } implicit lazy val circeJsonWriter: JsonWriter[Json] = new JsonWriter[Json] { - def write(value: Json, writer: TokenWriter): Unit = value.foldWith(new TethysJsonFolder(writer)) + def write(value: Json, writer: TokenWriter): Unit = + value.foldWith(new TethysJsonFolder(writer)) } - implicit lazy val circeJsonObjectReader: JsonReader[JsonObject] = new JsonReader[JsonObject] { - def read(it: TokenIterator)(implicit fieldName: FieldName): JsonObject = - if (!it.currentToken().isObjectStart) ReaderError.wrongJson(s"Expected object start but found: ${it.currentToken()}") - else { - it.next() - - var builder = ArrayBuffer.newBuilder[(String, Json)] - while (!it.currentToken().isObjectEnd) { - val token = it.currentToken() - if (token.isFieldName) { - val name = it.fieldName() - val value = circeJsonReader.read(it.next())(fieldName.appendFieldName(name)) - - builder += ((name, value)) + implicit lazy val circeJsonObjectReader: JsonReader[JsonObject] = + new JsonReader[JsonObject] { + def read(it: TokenIterator)(implicit fieldName: FieldName): JsonObject = + if (!it.currentToken().isObjectStart) + ReaderError.wrongJson( + s"Expected object start but found: ${it.currentToken()}" + ) + else { + it.next() + + var builder = ArrayBuffer.newBuilder[(String, Json)] + while (!it.currentToken().isObjectEnd) { + val token = it.currentToken() + if (token.isFieldName) { + val name = it.fieldName() + val value = + circeJsonReader.read(it.next())(fieldName.appendFieldName(name)) + + builder += ((name, value)) + } else + ReaderError.wrongJson( + s"Expect end of object or field name but '$token' found" + )(fieldName) } - else ReaderError.wrongJson(s"Expect end of object or field name but '$token' found")(fieldName) - } - it.next() + it.next() - JsonObject.fromIterable(builder.result) - } - } + JsonObject.fromIterable(builder.result) + } + } implicit lazy val circeJsonReader: JsonReader[Json] = new JsonReader[Json] { def read(it: TokenIterator)(implicit fieldName: FieldName): Json = { val token = it.currentToken() - if (token.isObjectStart) Json.fromJsonObject(circeJsonObjectReader.read(it)) - else if (token.isArrayStart) Json.fromValues(JsonReader[Vector[Json]].read(it)) - else if (token.isStringValue) Json.fromString(JsonReader.stringReader.read(it)) - else if (token.isBooleanValue) Json.fromBoolean(JsonReader.booleanReader.read(it)) - else if (token.isNumberValue) JsonReader.numberReader.read(it) match { - case x@(_: java.lang.Byte | _: java.lang.Short | _: java.lang.Long) => Json.fromLong(x.longValue) - case x: java.lang.Integer => Json.fromInt(x) - case x: java.lang.Float => Json.fromFloatOrNull(x) - case x: java.lang.Double => Json.fromDoubleOrNull(x) + if (token.isObjectStart) + Json.fromJsonObject(circeJsonObjectReader.read(it)) + else if (token.isArrayStart) + Json.fromValues(JsonReader[Vector[Json]].read(it)) + else if (token.isStringValue) + Json.fromString(JsonReader.stringReader.read(it)) + else if (token.isBooleanValue) + Json.fromBoolean(JsonReader.booleanReader.read(it)) + else if (token.isNumberValue) JsonReader.numberReader.read(it) match { + case x @ (_: java.lang.Byte | _: java.lang.Short | _: java.lang.Long) => + Json.fromLong(x.longValue) + case x: java.lang.Integer => Json.fromInt(x) + case x: java.lang.Float => Json.fromFloatOrNull(x) + case x: java.lang.Double => Json.fromDoubleOrNull(x) case x: java.math.BigInteger => Json.fromBigInt(x) case x: BigInt => Json.fromBigInt(x) @@ -69,12 +83,14 @@ trait CirceSupport { case x: BigDecimal => Json.fromBigDecimal(x) case x => Json.fromBigDecimal(x.doubleValue) } - else if (token.isNullValue) { it.next(); Json.Null } + else if (token.isNullValue) { it.next(); Json.Null } else ReaderError.wrongJson(s"Unexpected token found: $token")(fieldName) } } - private[this] class TethysJsonFolder(writer: TokenWriter) extends Json.Folder[Unit] with JsonNumberHack { + private[this] class TethysJsonFolder(writer: TokenWriter) + extends Json.Folder[Unit] + with JsonNumberHack { def onNull: Unit = writer.writeNull() def onBoolean(value: Boolean): Unit = writer.writeBoolean(value) def onNumber(value: JsonNumber): Unit = writeNumber(value, writer) diff --git a/modules/circe/src/test/scala/tethys/circe/CirceSupportTest.scala b/modules/circe/src/test/scala/tethys/circe/CirceSupportTest.scala index c49085b2..84092d8b 100644 --- a/modules/circe/src/test/scala/tethys/circe/CirceSupportTest.scala +++ b/modules/circe/src/test/scala/tethys/circe/CirceSupportTest.scala @@ -23,7 +23,7 @@ class CirceSupportTest extends AnyFlatSpec with Matchers { } it should "parse Double" in { - token(100.0D).tokensAs[Json] shouldBe Json.fromDoubleOrNull(100.0D) + token(100.0d).tokensAs[Json] shouldBe Json.fromDoubleOrNull(100.0d) } it should "parse BigInt" in { @@ -31,7 +31,9 @@ class CirceSupportTest extends AnyFlatSpec with Matchers { } it should "parse BigDecimal" in { - token(BigDecimal(100.0D)).tokensAs[Json] shouldBe Json.fromBigDecimal(100.0D) + token(BigDecimal(100.0d)).tokensAs[Json] shouldBe Json.fromBigDecimal( + 100.0d + ) } it should "parse String" in { @@ -52,7 +54,9 @@ class CirceSupportTest extends AnyFlatSpec with Matchers { it should "parse Array" in { arr(1, 2L, 3).tokensAs[Json] shouldBe - Json.fromValues(List(Json.fromLong(1L), Json.fromLong(2L), Json.fromLong(3L))) + Json.fromValues( + List(Json.fromLong(1L), Json.fromLong(2L), Json.fromLong(3L)) + ) } it should "parse JsonObject" in { @@ -72,13 +76,15 @@ class CirceSupportTest extends AnyFlatSpec with Matchers { } it should "parse Array of JsonObject" in { - arr(obj("a" -> "b"), obj("c" -> "d")).tokensAs[Json] shouldBe Json.fromValues(List( - Json.fromJsonObject(JsonObject("a" -> Json.fromString("b"))), - Json.fromJsonObject(JsonObject("c" -> Json.fromString("d"))) - )) + arr(obj("a" -> "b"), obj("c" -> "d")) + .tokensAs[Json] shouldBe Json.fromValues( + List( + Json.fromJsonObject(JsonObject("a" -> Json.fromString("b"))), + Json.fromJsonObject(JsonObject("c" -> Json.fromString("d"))) + ) + ) } - behavior of "Circe ast JsonWriter" it should "write Int" in { @@ -94,19 +100,21 @@ class CirceSupportTest extends AnyFlatSpec with Matchers { } it should "write Double" in { - Json.fromDouble(100.0D).asTokenList shouldBe token(100.0D) + Json.fromDouble(100.0d).asTokenList shouldBe token(100.0d) } it should "write BigInt" in { Json.fromBigInt(BigInt("10000000000")).asTokenList match { case DoubleValueNode(d) :: Nil => d shouldBe 1.0e10 // 2.11 only behavior - case LongValueNode(l) :: Nil => l shouldBe 10000000000L - case _ => fail() + case LongValueNode(l) :: Nil => l shouldBe 10000000000L + case _ => fail() } } it should "write BigDecimal" in { - Json.fromBigDecimal(BigDecimal(100.0D)).asTokenList shouldBe token(BigDecimal(100.0D)) + Json.fromBigDecimal(BigDecimal(100.0d)).asTokenList shouldBe token( + BigDecimal(100.0d) + ) } it should "write String" in { @@ -126,11 +134,15 @@ class CirceSupportTest extends AnyFlatSpec with Matchers { } it should "write Array" in { - Json.fromValues(List( - Json.fromInt(1), - Json.fromInt(2), - Json.fromInt(3) - )).asTokenList shouldBe arr(1L, 2L, 3L) + Json + .fromValues( + List( + Json.fromInt(1), + Json.fromInt(2), + Json.fromInt(3) + ) + ) + .asTokenList shouldBe arr(1L, 2L, 3L) } it should "write JsonObject" in { diff --git a/modules/core/src/main/scala-3/tethys/FieldStyle.scala b/modules/core/src/main/scala-3/tethys/FieldStyle.scala index b26e7e6a..ded1b2b5 100644 --- a/modules/core/src/main/scala-3/tethys/FieldStyle.scala +++ b/modules/core/src/main/scala-3/tethys/FieldStyle.scala @@ -2,7 +2,6 @@ package tethys import java.util.regex.Pattern - enum FieldStyle { case Capitalize, Uncapitalize, LowerCase, UpperCase @@ -11,36 +10,42 @@ enum FieldStyle { case SnakeCase, LowerSnakeCase, UpperSnakeCase, CapitalizedSnakeCase } -private[tethys] -object FieldStyle: +private[tethys] object FieldStyle: private val regexp1: Pattern = Pattern.compile("([A-Z]+)([A-Z][a-z])") private val regexp2: Pattern = Pattern.compile("([a-z\\d])([A-Z])") private val replacement: String = "$1_$2" private val snakeCase: String => String = splitName(_).mkString("_") private val kebabcase: String => String = splitName(_).mkString("-") private val capitalize: String => String = _.capitalize - private val uncapitalize: String => String = (field: String) => field.updated(0, field.charAt(0).toLower) + private val uncapitalize: String => String = (field: String) => + field.updated(0, field.charAt(0).toLower) private val lowercase: String => String = _.toLowerCase() private val uppercase: String => String = _.toUpperCase() def applyStyle(string: String, style: FieldStyle): String = style match - case FieldStyle.Capitalize => capitalize(string) + case FieldStyle.Capitalize => capitalize(string) case FieldStyle.Uncapitalize => uncapitalize(string) - case FieldStyle.LowerCase => lowercase(string) - case FieldStyle.UpperCase => uppercase(string) + case FieldStyle.LowerCase => lowercase(string) + case FieldStyle.UpperCase => uppercase(string) - case FieldStyle.KebabCase => kebabcase(string) + case FieldStyle.KebabCase => kebabcase(string) case FieldStyle.LowerKebabCase => (kebabcase andThen lowercase)(string) case FieldStyle.UpperKebabCase => (kebabcase andThen uppercase)(string) - case FieldStyle.CapitalizedKebabCase => (kebabcase andThen capitalize)(string) + case FieldStyle.CapitalizedKebabCase => + (kebabcase andThen capitalize)(string) - case FieldStyle.SnakeCase => snakeCase(string) + case FieldStyle.SnakeCase => snakeCase(string) case FieldStyle.LowerSnakeCase => (snakeCase andThen lowercase)(string) case FieldStyle.UpperSnakeCase => (snakeCase andThen uppercase)(string) - case FieldStyle.CapitalizedSnakeCase => (snakeCase andThen capitalize)(string) - + case FieldStyle.CapitalizedSnakeCase => + (snakeCase andThen capitalize)(string) private def splitName(name: String): List[String] = - val first = FieldStyle.regexp1.matcher(name).replaceAll(FieldStyle.replacement) - FieldStyle.regexp2.matcher(first).replaceAll(FieldStyle.replacement).split("_").toList + val first = + FieldStyle.regexp1.matcher(name).replaceAll(FieldStyle.replacement) + FieldStyle.regexp2 + .matcher(first) + .replaceAll(FieldStyle.replacement) + .split("_") + .toList diff --git a/modules/core/src/main/scala-3/tethys/OrdinalEnumJsonReader.scala b/modules/core/src/main/scala-3/tethys/OrdinalEnumJsonReader.scala index 6b9f1488..d59bdd4f 100644 --- a/modules/core/src/main/scala-3/tethys/OrdinalEnumJsonReader.scala +++ b/modules/core/src/main/scala-3/tethys/OrdinalEnumJsonReader.scala @@ -17,4 +17,6 @@ object OrdinalEnumJsonReader: case ex: NoSuchElementException => ReaderError.wrongJson(s"Unknown enum ordinal: $res") else - ReaderError.wrongJson(s"Expected int value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected int value but found: ${it.currentToken()}" + ) diff --git a/modules/core/src/main/scala-3/tethys/OrdinalEnumJsonWriter.scala b/modules/core/src/main/scala-3/tethys/OrdinalEnumJsonWriter.scala index 08b51f08..457d1330 100644 --- a/modules/core/src/main/scala-3/tethys/OrdinalEnumJsonWriter.scala +++ b/modules/core/src/main/scala-3/tethys/OrdinalEnumJsonWriter.scala @@ -2,14 +2,16 @@ package tethys import tethys.writers.tokens.TokenWriter - trait OrdinalEnumJsonWriter[A] extends JsonWriter[A] object OrdinalEnumJsonWriter: inline def derived[A <: scala.reflect.Enum]: OrdinalEnumJsonWriter[A] = - (value: A, tokenWriter: TokenWriter) => tokenWriter.writeNumber(value.ordinal) + (value: A, tokenWriter: TokenWriter) => + tokenWriter.writeNumber(value.ordinal) - inline def withLabel[A <: scala.reflect.Enum](label: String): JsonObjectWriter[A] = + inline def withLabel[A <: scala.reflect.Enum]( + label: String + ): JsonObjectWriter[A] = (value: A, tokenWriter: writers.tokens.TokenWriter) => tokenWriter.writeFieldName(label) tokenWriter.writeNumber(value.ordinal) diff --git a/modules/core/src/main/scala-3/tethys/ReaderBuilder.scala b/modules/core/src/main/scala-3/tethys/ReaderBuilder.scala index c54807f0..31f3027e 100644 --- a/modules/core/src/main/scala-3/tethys/ReaderBuilder.scala +++ b/modules/core/src/main/scala-3/tethys/ReaderBuilder.scala @@ -3,22 +3,30 @@ package tethys import tethys.{FieldStyle, JsonReader} sealed trait ReaderBuilder[A]: - def extract[Field](field: A => Field): ReaderBuilder.DependentFieldAs[A, Field] + def extract[Field]( + field: A => Field + ): ReaderBuilder.DependentFieldAs[A, Field] - def extractReader[Field](field: A => Field): ReaderBuilder.DependentField0[A, JsonReader[_ <: Field]] + def extractReader[Field]( + field: A => Field + ): ReaderBuilder.DependentField0[A, JsonReader[_ <: Field]] def fieldStyle(fieldStyle: FieldStyle): ReaderBuilder[A] @deprecated("Use tethys.FieldStyle instead") - def fieldStyle(fieldStyle: tethys.derivation.builder.FieldStyle): ReaderBuilder[A] + def fieldStyle( + fieldStyle: tethys.derivation.builder.FieldStyle + ): ReaderBuilder[A] def strict: ReaderBuilder[A] - object ReaderBuilder: - def apply[A](using mirror: scala.deriving.Mirror.ProductOf[A]): ReaderBuilder[A] = - throw IllegalStateException("Config must be an inlined given or provided directly to 'derived'") - + def apply[A](using + mirror: scala.deriving.Mirror.ProductOf[A] + ): ReaderBuilder[A] = + throw IllegalStateException( + "Config must be an inlined given or provided directly to 'derived'" + ) sealed trait AsSyntax[A, B, C]: def apply(fun: B => C): ReaderBuilder[A] @@ -33,26 +41,32 @@ object ReaderBuilder: def from[B](name: String): DependentField1[A, Field, B] - sealed trait DependentField1[A, Field, OneCollected]: def apply(fun: OneCollected => Field): ReaderBuilder[A] - def and[B](f1: A => B): DependentFieldN[A, Field, OneCollected *: B *: EmptyTuple] + def and[B]( + f1: A => B + ): DependentFieldN[A, Field, OneCollected *: B *: EmptyTuple] - def and[B](name: String): DependentFieldN[A, Field, OneCollected *: B *: EmptyTuple] + def and[B]( + name: String + ): DependentFieldN[A, Field, OneCollected *: B *: EmptyTuple] - def product - (using mirror: scala.deriving.Mirror.ProductOf[Field]) - (using ev: OneCollected *: EmptyTuple =:= mirror.MirroredElemTypes): ReaderBuilder[A] + def product(using mirror: scala.deriving.Mirror.ProductOf[Field])(using + ev: OneCollected *: EmptyTuple =:= mirror.MirroredElemTypes + ): ReaderBuilder[A] sealed trait DependentFieldN[A, Field, Collected <: NonEmptyTuple]: def apply(fun: Collected => Field): ReaderBuilder[A] - def and[B](f1: A => B): DependentFieldN[A, Field, Tuple.Append[Collected, B]] + def and[B]( + f1: A => B + ): DependentFieldN[A, Field, Tuple.Append[Collected, B]] - def and[B](name: String): DependentFieldN[A, Field, Tuple.Append[Collected, B]] + def and[B]( + name: String + ): DependentFieldN[A, Field, Tuple.Append[Collected, B]] - def product - (using mirror: scala.deriving.Mirror.ProductOf[Field]) - (using ev: Collected =:= mirror.MirroredElemTypes): ReaderBuilder[A] - \ No newline at end of file + def product(using mirror: scala.deriving.Mirror.ProductOf[Field])(using + ev: Collected =:= mirror.MirroredElemTypes + ): ReaderBuilder[A] diff --git a/modules/core/src/main/scala-3/tethys/StringEnumJsonReader.scala b/modules/core/src/main/scala-3/tethys/StringEnumJsonReader.scala index 3eccb416..e143d371 100644 --- a/modules/core/src/main/scala-3/tethys/StringEnumJsonReader.scala +++ b/modules/core/src/main/scala-3/tethys/StringEnumJsonReader.scala @@ -12,10 +12,11 @@ object StringEnumJsonReader: if it.currentToken().isStringValue then val res = it.string() it.next() - try - derivation.EnumCompanion.getByName[A](res) - catch + try derivation.EnumCompanion.getByName[A](res) + catch case ex: NoSuchElementException => ReaderError.wrongJson(s"Unknown enum name: $res") else - ReaderError.wrongJson(s"Expected string value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected string value but found: ${it.currentToken()}" + ) diff --git a/modules/core/src/main/scala-3/tethys/StringEnumJsonWriter.scala b/modules/core/src/main/scala-3/tethys/StringEnumJsonWriter.scala index 9a95e310..c63a0b84 100644 --- a/modules/core/src/main/scala-3/tethys/StringEnumJsonWriter.scala +++ b/modules/core/src/main/scala-3/tethys/StringEnumJsonWriter.scala @@ -5,9 +5,12 @@ trait StringEnumJsonWriter[A] extends JsonWriter[A] object StringEnumJsonWriter: inline def derived[A <: scala.reflect.Enum]: StringEnumJsonWriter[A] = - (value: A, tokenWriter: TokenWriter) => tokenWriter.writeString(value.toString) + (value: A, tokenWriter: TokenWriter) => + tokenWriter.writeString(value.toString) - inline def withLabel[A <: scala.reflect.Enum](label: String): JsonObjectWriter[A] = + inline def withLabel[A <: scala.reflect.Enum]( + label: String + ): JsonObjectWriter[A] = (value: A, tokenWriter: writers.tokens.TokenWriter) => tokenWriter.writeFieldName(label) tokenWriter.writeString(value.toString) diff --git a/modules/core/src/main/scala-3/tethys/WriterBuilder.scala b/modules/core/src/main/scala-3/tethys/WriterBuilder.scala index 5590e80c..9ae460d2 100644 --- a/modules/core/src/main/scala-3/tethys/WriterBuilder.scala +++ b/modules/core/src/main/scala-3/tethys/WriterBuilder.scala @@ -12,21 +12,27 @@ sealed trait WriterBuilder[A]: def rename[B](field: A => B)(rename: String): WriterBuilder[A] def update[B](field: A => B): FunApply[A, B] with WithRename[FunApply[A, B]] - + @deprecated("Use 'update' instead") - def updatePartial[B](field: A => B): FunApply[A, B] with WithRename[FunApply[A, B]] + def updatePartial[B]( + field: A => B + ): FunApply[A, B] with WithRename[FunApply[A, B]] def fieldStyle(style: FieldStyle): WriterBuilder[A] - - @deprecated("Use tethys.FieldStyle instead") - def fieldStyle(fieldStyle: tethys.derivation.builder.FieldStyle): WriterBuilder[A] - + @deprecated("Use tethys.FieldStyle instead") + def fieldStyle( + fieldStyle: tethys.derivation.builder.FieldStyle + ): WriterBuilder[A] object WriterBuilder: - def apply[A](using mirror: scala.deriving.Mirror.ProductOf[A]): WriterBuilder[A] = - throw IllegalStateException("Config must be an inlined given or provided directly to 'derived'") - + def apply[A](using + mirror: scala.deriving.Mirror.ProductOf[A] + ): WriterBuilder[A] = + throw IllegalStateException( + "Config must be an inlined given or provided directly to 'derived'" + ) + sealed trait WithRename[Res]: def withRename(rename: String): Res @@ -34,4 +40,4 @@ object WriterBuilder: def apply[C](fun: B => C): WriterBuilder[A] sealed trait FunApply[A, B] extends FunApply0[A, B]: - def fromRoot[C](fun: A => C): WriterBuilder[A] \ No newline at end of file + def fromRoot[C](fun: A => C): WriterBuilder[A] diff --git a/modules/core/src/main/scala-3/tethys/compat/CollectionBuilder.scala b/modules/core/src/main/scala-3/tethys/compat/CollectionBuilder.scala index 39a4fa12..b53ce562 100644 --- a/modules/core/src/main/scala-3/tethys/compat/CollectionBuilder.scala +++ b/modules/core/src/main/scala-3/tethys/compat/CollectionBuilder.scala @@ -8,33 +8,59 @@ trait CollectionBuilder[A, C] { } object CollectionBuilder { - final class IterableFactoryCollectionBuilder[A, C[_]](factory: IterableFactory[C]) extends CollectionBuilder[A, C[A]] { + final class IterableFactoryCollectionBuilder[A, C[_]]( + factory: IterableFactory[C] + ) extends CollectionBuilder[A, C[A]] { def newBuilder: mutable.Builder[A, C[A]] = factory.newBuilder[A] } - final class MapFactoryCollectionBuilder[K, V, M[_, _]](factory: MapFactory[M]) extends CollectionBuilder[(K, V), M[K, V]] { + final class MapFactoryCollectionBuilder[K, V, M[_, _]](factory: MapFactory[M]) + extends CollectionBuilder[(K, V), M[K, V]] { def newBuilder: mutable.Builder[(K, V), M[K, V]] = factory.newBuilder[K, V] } - inline given iterableFactoryCollectionBuilder[A, C[X] <: Iterable[X]]: CollectionBuilder[A, C[A]] = - ${CollectionBuilderMacroImpl.fromIterableFactory[A, C]} + inline given iterableFactoryCollectionBuilder[A, C[X] <: Iterable[X]] + : CollectionBuilder[A, C[A]] = + ${ CollectionBuilderMacroImpl.fromIterableFactory[A, C] } - inline given mapFactoryCollectionBuilder[K, V, M[X, Y] <: scala.collection.Map[X, Y]]: CollectionBuilder[(K, V), M[K, V]] = - ${CollectionBuilderMacroImpl.fromMapFactory[K, V, M]} + inline given mapFactoryCollectionBuilder[K, V, M[ + X, + Y + ] <: scala.collection.Map[X, Y]]: CollectionBuilder[(K, V), M[K, V]] = + ${ CollectionBuilderMacroImpl.fromMapFactory[K, V, M] } object CollectionBuilderMacroImpl { - def fromIterableFactory[A: Type, C[X] <: Iterable[X]: Type](using Quotes): Expr[IterableFactoryCollectionBuilder[A, C]] = { + def fromIterableFactory[A: Type, C[X] <: Iterable[X]: Type](using + Quotes + ): Expr[IterableFactoryCollectionBuilder[A, C]] = { import quotes.reflect.* - val factory = Ref(TypeRepr.of[C].typeSymbol.companionModule).asExprOf[IterableFactory[C]] - '{new tethys.compat.CollectionBuilder.IterableFactoryCollectionBuilder[A, C]($factory)} + val factory = Ref(TypeRepr.of[C].typeSymbol.companionModule) + .asExprOf[IterableFactory[C]] + '{ + new tethys.compat.CollectionBuilder.IterableFactoryCollectionBuilder[ + A, + C + ]($factory) + } } - def fromMapFactory[K: Type, V: Type, M[X, Y] <: scala.collection.Map[X, Y]: Type](using Quotes): Expr[MapFactoryCollectionBuilder[K, V, M]] = { + def fromMapFactory[ + K: Type, + V: Type, + M[X, Y] <: scala.collection.Map[X, Y]: Type + ](using Quotes): Expr[MapFactoryCollectionBuilder[K, V, M]] = { import quotes.reflect.* - val factory = Ref(TypeRepr.of[M].typeSymbol.companionModule).asExprOf[MapFactory[M]] - '{new tethys.compat.CollectionBuilder.MapFactoryCollectionBuilder[K, V, M]($factory)} + val factory = + Ref(TypeRepr.of[M].typeSymbol.companionModule).asExprOf[MapFactory[M]] + '{ + new tethys.compat.CollectionBuilder.MapFactoryCollectionBuilder[ + K, + V, + M + ]($factory) + } } } } diff --git a/modules/core/src/main/scala-3/tethys/derivation/ConfigurationMacroUtils.scala b/modules/core/src/main/scala-3/tethys/derivation/ConfigurationMacroUtils.scala index 00a524d0..2ec0bae3 100644 --- a/modules/core/src/main/scala-3/tethys/derivation/ConfigurationMacroUtils.scala +++ b/modules/core/src/main/scala-3/tethys/derivation/ConfigurationMacroUtils.scala @@ -10,7 +10,10 @@ import scala.deriving.Mirror import scala.quoted.{Expr, FromExpr, Quotes, ToExpr, Type, Varargs} import tethys.readers.tokens.{QueueIterator, TokenIterator} import tethys.commons.TokenNode -import tethys.derivation.builder.{ReaderDerivationConfig, WriterDerivationConfig} +import tethys.derivation.builder.{ + ReaderDerivationConfig, + WriterDerivationConfig +} trait ConfigurationMacroUtils: given Quotes = quotes @@ -24,8 +27,8 @@ trait ConfigurationMacroUtils: case failure: ImplicitSearchFailure => // Not sees statements put in a block (e.g. derived instances) // So we use summonInline - '{summonInline[T]} - + '{ summonInline[T] } + def lookupOpt[T: Type]: Option[Expr[T]] = Implicits.search(TypeRepr.of[T]) match case success: ImplicitSearchSuccess => @@ -101,13 +104,17 @@ trait ConfigurationMacroUtils: (acc.copy(fieldStyle = Some(fieldStyle.valueOrAbort)), updatedFields) case '{ - ($rest: WriterBuilder[T]).fieldStyle(${ style }: tethys.derivation.builder.FieldStyle) - } => + ($rest: WriterBuilder[T]).fieldStyle(${ + style + }: tethys.derivation.builder.FieldStyle) + } => val fieldStyle = legacyFieldStyleToFieldStyle(style).getOrElse { - report.errorAndAbort(s"Can't extract fieldStyle from ${style.asTerm.show(using Printer.TreeShortCode)}") + report.errorAndAbort( + s"Can't extract fieldStyle from ${style.asTerm.show(using Printer.TreeShortCode)}" + ) } (acc.copy(fieldStyle = Some(fieldStyle)), updatedFields) - + case '{ ($rest: WriterBuilder[T]) .add($field: String) @@ -377,8 +384,13 @@ trait ConfigurationMacroUtils: val updatedDefault = field.extractor match case None => default case Some((tpe, lambda)) => - Option.when(tpe.isOption)('{ None }).orElse(default) - .map(default => Apply(Select.unique(lambda, "apply"), List(default.asTerm))).map(_.asExprOf[Any]) + Option + .when(tpe.isOption)('{ None }) + .orElse(default) + .map(default => + Apply(Select.unique(lambda, "apply"), List(default.asTerm)) + ) + .map(_.asExprOf[Any]) field.update(idx, updatedDefault, macroConfig.fieldStyle) @@ -391,17 +403,25 @@ trait ConfigurationMacroUtils: .update(idx, default, macroConfig.fieldStyle) } val existingFieldNames = fields.map(_.name).toSet - val additionalFields = fields.collect { - case field: ReaderField.Extracted => - field.extractors.collect { case (name, tpe) if !existingFieldNames(name) => - ReaderField.Basic(name, tpe, None, -1, Option.when(tpe.isOption)('{None})) + val additionalFields = fields + .collect { case field: ReaderField.Extracted => + field.extractors.collect { + case (name, tpe) if !existingFieldNames(name) => + ReaderField.Basic( + name, + tpe, + None, + -1, + Option.when(tpe.isOption)('{ None }) + ) } - }.flatten.distinctBy(_.name) + } + .flatten + .distinctBy(_.name) val allFields = fields ::: additionalFields checkLoops(allFields) (sortDependencies(allFields), macroConfig.isStrict) - private def sortDependencies(fields: List[ReaderField]): List[ReaderField] = val known = fields.map(_.name).toSet val (basic, allExtracted) = fields.partitionMap { @@ -525,14 +545,16 @@ trait ConfigurationMacroUtils: } => if acc.extracted.contains(field.name) then exitExtractionAlreadyDefined(field.name) - + loop( config = rest, acc = acc.withExtracted( ReaderField.Basic( name = field.name, tpe = TypeRepr.of[t], - extractor = Some((TypeRepr.of[t1], Typed(fun.asTerm, TypeTree.of[t1 => t]))) + extractor = Some( + (TypeRepr.of[t1], Typed(fun.asTerm, TypeTree.of[t1 => t])) + ) ) ) ) @@ -545,10 +567,14 @@ trait ConfigurationMacroUtils: ) case '{ - ($rest: ReaderBuilder[T]).fieldStyle(${ style }: tethys.derivation.builder.FieldStyle) - } => + ($rest: ReaderBuilder[T]).fieldStyle(${ + style + }: tethys.derivation.builder.FieldStyle) + } => val fieldStyle = legacyFieldStyleToFieldStyle(style).getOrElse { - report.errorAndAbort(s"Can't extract fieldStyle from ${style.asTerm.show(using Printer.TreeShortCode)}") + report.errorAndAbort( + s"Can't extract fieldStyle from ${style.asTerm.show(using Printer.TreeShortCode)}" + ) } loop( config = rest, @@ -655,8 +681,13 @@ trait ConfigurationMacroUtils: selectors match case constructorSymbol :: Nil => - val symbol = tpe.typeSymbol.fieldMembers.find(_.name == constructorSymbol.name) - .getOrElse(report.errorAndAbort(s"Not found symbol corresponding to constructor symbol ${constructorSymbol.name}")) + val symbol = tpe.typeSymbol.fieldMembers + .find(_.name == constructorSymbol.name) + .getOrElse( + report.errorAndAbort( + s"Not found symbol corresponding to constructor symbol ${constructorSymbol.name}" + ) + ) val discriminators: List[Term] = getAllChildren(tpe).map { case tpe: TypeRef => @@ -666,14 +697,23 @@ trait ConfigurationMacroUtils: case tpe => report.errorAndAbort(s"Unknown tpe: $tpe") } - SumMacroConfig(Some(DiscriminatorConfig(symbol.name, tpe.memberType(symbol), discriminators))) + SumMacroConfig( + Some( + DiscriminatorConfig( + symbol.name, + tpe.memberType(symbol), + discriminators + ) + ) + ) case Nil => SumMacroConfig(None) case multiple => - report.errorAndAbort(s"Only one field can be a selector. Found ${multiple.map(_.name).mkString(", ")}") - + report.errorAndAbort( + s"Only one field can be a selector. Found ${multiple.map(_.name).mkString(", ")}" + ) private def stub(tpe: TypeRepr): Term = import quotes.reflect.* @@ -706,17 +746,20 @@ trait ConfigurationMacroUtils: case Block(_, term) => traverseTree(term) case term => term - private def typeReprsOf[Ts: Type]: List[TypeRepr] = Type.of[Ts] match case '[EmptyTuple] => Nil - case '[t *: ts] => TypeRepr.of[t] :: typeReprsOf[ts] + case '[t *: ts] => TypeRepr.of[t] :: typeReprsOf[ts] def getAllChildren(tpe: TypeRepr): List[TypeRepr] = tpe.asType match case '[t] => Expr.summon[scala.deriving.Mirror.Of[t]] match - case Some('{ $m: scala.deriving.Mirror.SumOf[t] {type MirroredElemTypes = subs} }) => + case Some('{ + $m: scala.deriving.Mirror.SumOf[t] { + type MirroredElemTypes = subs + } + }) => typeReprsOf[subs].flatMap(getAllChildren) case _ => List(tpe) @@ -816,9 +859,9 @@ trait ConfigurationMacroUtils: def reader: Boolean def initializeFieldCase( - readers: Map[TypeRepr, Ref], - it: Expr[TokenIterator], - fieldName: Expr[FieldName] + readers: Map[TypeRepr, Ref], + it: Expr[TokenIterator], + fieldName: Expr[FieldName] ): Option[CaseDef] = this match case _: ReaderField.Basic => @@ -830,8 +873,14 @@ trait ConfigurationMacroUtils: None, Block( init { - val reader = readers.get(readerTpe.get).fold(lookup[JsonReader[t]])(_.asExprOf[JsonReader[t]]) - '{${reader}.read(${it})(${fieldName}.appendFieldName(${Expr(name)}))}.asTerm + val reader = readers + .get(readerTpe.get) + .fold(lookup[JsonReader[t]])(_.asExprOf[JsonReader[t]]) + '{ + ${ reader }.read(${ it })( + ${ fieldName }.appendFieldName(${ Expr(name) }) + ) + }.asTerm }, '{}.asTerm ) @@ -845,23 +894,48 @@ trait ConfigurationMacroUtils: Literal(StringConstant(name)), None, Block( - initIterator('{ ${it}.collectExpression() }.asTerm), + initIterator('{ ${ it }.collectExpression() }.asTerm), '{}.asTerm ) ) } - lazy val (initialize, ref, initRef, iteratorRef) = { - val flags = default.fold(Flags.Deferred | Flags.Mutable)(_ => Flags.Mutable) - val symbol = Symbol.newVal(Symbol.spliceOwner, s"${name}Var", tpe, flags, Symbol.noSymbol) - val initSymbol = Symbol.newVal(Symbol.spliceOwner, s"${name}Init", TypeRepr.of[Boolean], Flags.Mutable, Symbol.noSymbol) + val flags = + default.fold(Flags.Deferred | Flags.Mutable)(_ => Flags.Mutable) + val symbol = Symbol.newVal( + Symbol.spliceOwner, + s"${name}Var", + tpe, + flags, + Symbol.noSymbol + ) + val initSymbol = Symbol.newVal( + Symbol.spliceOwner, + s"${name}Init", + TypeRepr.of[Boolean], + Flags.Mutable, + Symbol.noSymbol + ) val stat = ValDef(symbol, default.map(_.asTerm)) - val initStat = ValDef(initSymbol, Some('{false}.asTerm)) - val iteratorSymbol = Option.when(reader)(Symbol.newVal(Symbol.spliceOwner, s"${name}Iterator", TypeRepr.of[TokenIterator], Flags.Mutable | Flags.Deferred, Symbol.noSymbol)) + val initStat = ValDef(initSymbol, Some('{ false }.asTerm)) + val iteratorSymbol = Option.when(reader)( + Symbol.newVal( + Symbol.spliceOwner, + s"${name}Iterator", + TypeRepr.of[TokenIterator], + Flags.Mutable | Flags.Deferred, + Symbol.noSymbol + ) + ) val iteratorStat = iteratorSymbol.map(ValDef(_, None)) val iteratorRef = iteratorStat.map(stat => Ref(stat.symbol)) - (List(stat, initStat) ++ iteratorStat, Ref(stat.symbol), Ref(initStat.symbol), iteratorRef) + ( + List(stat, initStat) ++ iteratorStat, + Ref(stat.symbol), + Ref(initStat.symbol), + iteratorRef + ) } def idx: Int @@ -874,18 +948,17 @@ trait ConfigurationMacroUtils: case field: ReaderField.Extracted => Some(field.tpe) - def init(value: Term): List[Statement] = this match case ReaderField.Basic(_, _, None, _, _) => List( Assign(ref, value), - Assign(initRef, '{true}.asTerm) + Assign(initRef, '{ true }.asTerm) ) case ReaderField.Basic(_, _, Some((_, lambda)), _, _) => List( - Assign(ref, Apply(Select.unique(lambda, "apply") , List(value))), - Assign(initRef, '{true}.asTerm) + Assign(ref, Apply(Select.unique(lambda, "apply"), List(value))), + Assign(initRef, '{ true }.asTerm) ) case extracted: ReaderField.Extracted => List( @@ -893,14 +966,14 @@ trait ConfigurationMacroUtils: Assign(initRef, '{ true }.asTerm) ) - def initIterator(value: Term): List[Statement] = iteratorRef.map { ref => - List( - Assign(ref, value), - Assign(initRef, '{ true }.asTerm) - ) - }.getOrElse(Nil) - - + def initIterator(value: Term): List[Statement] = iteratorRef + .map { ref => + List( + Assign(ref, value), + Assign(initRef, '{ true }.asTerm) + ) + } + .getOrElse(Nil) def update( index: Int, @@ -911,13 +984,15 @@ trait ConfigurationMacroUtils: field.copy( idx = index, default = default, - name = fieldStyle.fold(field.name)(FieldStyle.applyStyle(field.name, _)) + name = + fieldStyle.fold(field.name)(FieldStyle.applyStyle(field.name, _)) ) case field: ReaderField.Extracted => field.copy( idx = index, default = default, - name = fieldStyle.fold(field.name)(FieldStyle.applyStyle(field.name, _)) + name = + fieldStyle.fold(field.name)(FieldStyle.applyStyle(field.name, _)) ) } @@ -940,7 +1015,10 @@ trait ConfigurationMacroUtils: idx: Int = 0, default: Option[Expr[Any]] = None ) extends ReaderField: - def extract(fields: Map[String, Ref], fieldName: Expr[FieldName]): List[Statement] = + def extract( + fields: Map[String, Ref], + fieldName: Expr[FieldName] + ): List[Statement] = val term = extractors match case (depName, _) :: Nil => Apply(Select.unique(lambda, "apply"), List(fields(depName))) @@ -948,17 +1026,27 @@ trait ConfigurationMacroUtils: val value = extractors .map((name, _) => fields(name)) .foldRight[Term]('{ EmptyTuple }.asTerm) { (el, acc) => - Select.unique(acc, "*:") + Select + .unique(acc, "*:") .appliedToTypes(List(el.tpe, acc.tpe)) .appliedToArgs(List(el)) } Select.unique(lambda, "apply").appliedToArgs(List(value)) - + iteratorRef match case Some(iteratorRef) => - val reader = Typed(term, TypeTree.of[JsonReader[Any]]).asExprOf[JsonReader[Any]] - val it = '{if ${initRef.asExprOf[Boolean]} then ${iteratorRef.asExprOf[TokenIterator]} else QueueIterator(List(TokenNode.NullValueNode))} - val value = '{${reader}.read(${it})(${fieldName}.appendFieldName(${ Expr(name) }))} + val reader = Typed(term, TypeTree.of[JsonReader[Any]]) + .asExprOf[JsonReader[Any]] + val it = '{ + if ${ initRef.asExprOf[Boolean] } then + ${ iteratorRef.asExprOf[TokenIterator] } + else QueueIterator(List(TokenNode.NullValueNode)) + } + val value = '{ + ${ reader }.read(${ it })(${ fieldName }.appendFieldName(${ + Expr(name) + })) + } init(value.asTerm) case None => init(term) @@ -1008,49 +1096,90 @@ trait ConfigurationMacroUtils: case _ => None @deprecated - def legacyFieldStyleToFieldStyle(x: Expr[tethys.derivation.builder.FieldStyle]): Option[FieldStyle] = + def legacyFieldStyleToFieldStyle( + x: Expr[tethys.derivation.builder.FieldStyle] + ): Option[FieldStyle] = x match - case '{ tethys.derivation.builder.FieldStyle.UpperCase } => Some(FieldStyle.UpperCase) - case '{ tethys.derivation.builder.FieldStyle.uppercase } => Some(FieldStyle.UpperCase) - case '{ tethys.derivation.builder.FieldStyle.LowerCase } => Some(FieldStyle.LowerCase) - case '{ tethys.derivation.builder.FieldStyle.lowercase } => Some(FieldStyle.LowerCase) - case '{ tethys.derivation.builder.FieldStyle.Capitalize } => Some(FieldStyle.Capitalize) - case '{ tethys.derivation.builder.FieldStyle.capitalize } => Some(FieldStyle.Capitalize) - case '{ tethys.derivation.builder.FieldStyle.Uncapitalize } => Some(FieldStyle.Uncapitalize) - case '{ tethys.derivation.builder.FieldStyle.uncapitalize } => Some(FieldStyle.Uncapitalize) - case '{ tethys.derivation.builder.FieldStyle.KebabCase } => Some(FieldStyle.KebabCase) - case '{ tethys.derivation.builder.FieldStyle.kebabCase } => Some(FieldStyle.KebabCase) - case '{ tethys.derivation.builder.FieldStyle.LowerKebabCase } => Some(FieldStyle.LowerKebabCase) - case '{ tethys.derivation.builder.FieldStyle.lowerKebabCase } => Some(FieldStyle.LowerKebabCase) - case '{ tethys.derivation.builder.FieldStyle.UpperKebabCase } => Some(FieldStyle.UpperKebabCase) - case '{ tethys.derivation.builder.FieldStyle.upperKebabCase } => Some(FieldStyle.UpperKebabCase) - case '{ tethys.derivation.builder.FieldStyle.CapitalizedKebabCase } => Some(FieldStyle.CapitalizedKebabCase) - case '{ tethys.derivation.builder.FieldStyle.capitalizedKebabCase } => Some(FieldStyle.CapitalizedKebabCase) - case '{ tethys.derivation.builder.FieldStyle.SnakeCase } => Some(FieldStyle.SnakeCase) - case '{ tethys.derivation.builder.FieldStyle.snakeCase } => Some(FieldStyle.SnakeCase) - case '{ tethys.derivation.builder.FieldStyle.LowerSnakeCase } => Some(FieldStyle.LowerSnakeCase) - case '{ tethys.derivation.builder.FieldStyle.lowerSnakeCase } => Some(FieldStyle.LowerSnakeCase) - case '{ tethys.derivation.builder.FieldStyle.UpperSnakeCase } => Some(FieldStyle.UpperSnakeCase) - case '{ tethys.derivation.builder.FieldStyle.upperSnakeCase } => Some(FieldStyle.UpperSnakeCase) - case '{ tethys.derivation.builder.FieldStyle.CapitalizedSnakeCase } => Some(FieldStyle.CapitalizedSnakeCase) - case '{ tethys.derivation.builder.FieldStyle.capitalizedSnakeCase } => Some(FieldStyle.CapitalizedSnakeCase) + case '{ tethys.derivation.builder.FieldStyle.UpperCase } => + Some(FieldStyle.UpperCase) + case '{ tethys.derivation.builder.FieldStyle.uppercase } => + Some(FieldStyle.UpperCase) + case '{ tethys.derivation.builder.FieldStyle.LowerCase } => + Some(FieldStyle.LowerCase) + case '{ tethys.derivation.builder.FieldStyle.lowercase } => + Some(FieldStyle.LowerCase) + case '{ tethys.derivation.builder.FieldStyle.Capitalize } => + Some(FieldStyle.Capitalize) + case '{ tethys.derivation.builder.FieldStyle.capitalize } => + Some(FieldStyle.Capitalize) + case '{ tethys.derivation.builder.FieldStyle.Uncapitalize } => + Some(FieldStyle.Uncapitalize) + case '{ tethys.derivation.builder.FieldStyle.uncapitalize } => + Some(FieldStyle.Uncapitalize) + case '{ tethys.derivation.builder.FieldStyle.KebabCase } => + Some(FieldStyle.KebabCase) + case '{ tethys.derivation.builder.FieldStyle.kebabCase } => + Some(FieldStyle.KebabCase) + case '{ tethys.derivation.builder.FieldStyle.LowerKebabCase } => + Some(FieldStyle.LowerKebabCase) + case '{ tethys.derivation.builder.FieldStyle.lowerKebabCase } => + Some(FieldStyle.LowerKebabCase) + case '{ tethys.derivation.builder.FieldStyle.UpperKebabCase } => + Some(FieldStyle.UpperKebabCase) + case '{ tethys.derivation.builder.FieldStyle.upperKebabCase } => + Some(FieldStyle.UpperKebabCase) + case '{ tethys.derivation.builder.FieldStyle.CapitalizedKebabCase } => + Some(FieldStyle.CapitalizedKebabCase) + case '{ tethys.derivation.builder.FieldStyle.capitalizedKebabCase } => + Some(FieldStyle.CapitalizedKebabCase) + case '{ tethys.derivation.builder.FieldStyle.SnakeCase } => + Some(FieldStyle.SnakeCase) + case '{ tethys.derivation.builder.FieldStyle.snakeCase } => + Some(FieldStyle.SnakeCase) + case '{ tethys.derivation.builder.FieldStyle.LowerSnakeCase } => + Some(FieldStyle.LowerSnakeCase) + case '{ tethys.derivation.builder.FieldStyle.lowerSnakeCase } => + Some(FieldStyle.LowerSnakeCase) + case '{ tethys.derivation.builder.FieldStyle.UpperSnakeCase } => + Some(FieldStyle.UpperSnakeCase) + case '{ tethys.derivation.builder.FieldStyle.upperSnakeCase } => + Some(FieldStyle.UpperSnakeCase) + case '{ tethys.derivation.builder.FieldStyle.CapitalizedSnakeCase } => + Some(FieldStyle.CapitalizedSnakeCase) + case '{ tethys.derivation.builder.FieldStyle.capitalizedSnakeCase } => + Some(FieldStyle.CapitalizedSnakeCase) case _ => None - @deprecated - def parseLegacyReaderDerivationConfig[T: Type](config: Expr[ReaderDerivationConfig], - mirror: Expr[Mirror.ProductOf[T]]): Expr[ReaderBuilder[T]] = + def parseLegacyReaderDerivationConfig[T: Type]( + config: Expr[ReaderDerivationConfig], + mirror: Expr[Mirror.ProductOf[T]] + ): Expr[ReaderBuilder[T]] = config match - case '{ ReaderDerivationConfig.withFieldStyle(${ fieldStyle }: FieldStyle) } => + case '{ + ReaderDerivationConfig.withFieldStyle(${ fieldStyle }: FieldStyle) + } => '{ ReaderBuilder[T](using ${ mirror }).fieldStyle(${ fieldStyle }) } - case '{ ReaderDerivationConfig.withFieldStyle(${ fieldStyle }: tethys.derivation.builder.FieldStyle) } => + case '{ + ReaderDerivationConfig.withFieldStyle(${ + fieldStyle + }: tethys.derivation.builder.FieldStyle) + } => '{ ReaderBuilder[T](using ${ mirror }).fieldStyle(${ fieldStyle }) } - case '{ ReaderDerivationConfig.empty.withFieldStyle(${ fieldStyle }: FieldStyle) } => + case '{ + ReaderDerivationConfig.empty.withFieldStyle(${ + fieldStyle + }: FieldStyle) + } => '{ ReaderBuilder[T](using ${ mirror }).fieldStyle(${ fieldStyle }) } - case '{ ReaderDerivationConfig.empty.withFieldStyle(${ fieldStyle }: tethys.derivation.builder.FieldStyle) } => + case '{ + ReaderDerivationConfig.empty.withFieldStyle(${ + fieldStyle + }: tethys.derivation.builder.FieldStyle) + } => '{ ReaderBuilder[T](using ${ mirror }).fieldStyle(${ fieldStyle }) } case '{ ReaderDerivationConfig.strict } => @@ -1059,57 +1188,135 @@ trait ConfigurationMacroUtils: case '{ ReaderDerivationConfig.empty.strict } => '{ ReaderBuilder[T](using ${ mirror }).strict } - case '{ ReaderDerivationConfig.withFieldStyle(${ fieldStyle }: FieldStyle).strict } => - '{ ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) } + case '{ + ReaderDerivationConfig + .withFieldStyle(${ fieldStyle }: FieldStyle) + .strict + } => + '{ + ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) + } - case '{ ReaderDerivationConfig.withFieldStyle(${ fieldStyle }: tethys.derivation.builder.FieldStyle).strict } => - '{ ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) } + case '{ + ReaderDerivationConfig + .withFieldStyle(${ + fieldStyle + }: tethys.derivation.builder.FieldStyle) + .strict + } => + '{ + ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) + } - case '{ ReaderDerivationConfig.strict.withFieldStyle(${ fieldStyle }: FieldStyle) } => - '{ ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) } + case '{ + ReaderDerivationConfig.strict.withFieldStyle(${ + fieldStyle + }: FieldStyle) + } => + '{ + ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) + } - case '{ ReaderDerivationConfig.strict.withFieldStyle(${ fieldStyle }: tethys.derivation.builder.FieldStyle) } => - '{ ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) } + case '{ + ReaderDerivationConfig.strict.withFieldStyle(${ + fieldStyle + }: tethys.derivation.builder.FieldStyle) + } => + '{ + ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) + } - case '{ ReaderDerivationConfig.empty.withFieldStyle(${ fieldStyle }: FieldStyle).strict } => - '{ ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) } + case '{ + ReaderDerivationConfig.empty + .withFieldStyle(${ fieldStyle }: FieldStyle) + .strict + } => + '{ + ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) + } - case '{ ReaderDerivationConfig.empty.withFieldStyle(${ fieldStyle }: tethys.derivation.builder.FieldStyle).strict } => - '{ ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) } + case '{ + ReaderDerivationConfig.empty + .withFieldStyle(${ + fieldStyle + }: tethys.derivation.builder.FieldStyle) + .strict + } => + '{ + ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) + } - case '{ ReaderDerivationConfig.empty.strict.withFieldStyle(${ fieldStyle }: FieldStyle) } => - '{ ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) } + case '{ + ReaderDerivationConfig.empty.strict.withFieldStyle(${ + fieldStyle + }: FieldStyle) + } => + '{ + ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) + } - case '{ ReaderDerivationConfig.empty.strict.withFieldStyle(${ fieldStyle }: tethys.derivation.builder.FieldStyle) } => - '{ ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) } + case '{ + ReaderDerivationConfig.empty.strict.withFieldStyle(${ + fieldStyle + }: tethys.derivation.builder.FieldStyle) + } => + '{ + ReaderBuilder[T](using ${ mirror }).strict.fieldStyle(${ fieldStyle }) + } case other => - report.errorAndAbort(s"Unknown tree: ${other.asTerm.show(using Printer.TreeShortCode)}") + report.errorAndAbort( + s"Unknown tree: ${other.asTerm.show(using Printer.TreeShortCode)}" + ) @deprecated - def parseLegacyWriterDerivationConfig[T: Type](config: Expr[WriterDerivationConfig], - mirror: Expr[Mirror.ProductOf[T]]): Expr[WriterBuilder[T]] = + def parseLegacyWriterDerivationConfig[T: Type]( + config: Expr[WriterDerivationConfig], + mirror: Expr[Mirror.ProductOf[T]] + ): Expr[WriterBuilder[T]] = config match - case '{ WriterDerivationConfig.withFieldStyle(${ fieldStyle }: FieldStyle) } => + case '{ + WriterDerivationConfig.withFieldStyle(${ fieldStyle }: FieldStyle) + } => '{ WriterBuilder[T](using ${ mirror }).fieldStyle(${ fieldStyle }) } - case '{ WriterDerivationConfig.withFieldStyle(${ fieldStyle }: tethys.derivation.builder.FieldStyle) } => + case '{ + WriterDerivationConfig.withFieldStyle(${ + fieldStyle + }: tethys.derivation.builder.FieldStyle) + } => '{ WriterBuilder[T](using ${ mirror }).fieldStyle(${ fieldStyle }) } - case '{ WriterDerivationConfig.empty.withFieldStyle(${ fieldStyle }: FieldStyle) } => + case '{ + WriterDerivationConfig.empty.withFieldStyle(${ + fieldStyle + }: FieldStyle) + } => '{ WriterBuilder[T](using ${ mirror }).fieldStyle(${ fieldStyle }) } - case '{ WriterDerivationConfig.empty.withFieldStyle(${ fieldStyle }: tethys.derivation.builder.FieldStyle) } => + case '{ + WriterDerivationConfig.empty.withFieldStyle(${ + fieldStyle + }: tethys.derivation.builder.FieldStyle) + } => '{ WriterBuilder[T](using ${ mirror }).fieldStyle(${ fieldStyle }) } case other => - report.errorAndAbort(s"Unknown tree: ${other.asTerm.show(using Printer.TreeShortCode)}") + report.errorAndAbort( + s"Unknown tree: ${other.asTerm.show(using Printer.TreeShortCode)}" + ) - def parseLegacyDiscriminator[T: Type](config: Expr[WriterDerivationConfig]): DiscriminatorConfig = + def parseLegacyDiscriminator[T: Type]( + config: Expr[WriterDerivationConfig] + ): DiscriminatorConfig = val name: String = config match - case '{ WriterDerivationConfig.withDiscriminator($name: String)} => name.valueOrAbort - case '{ WriterDerivationConfig.empty.withDiscriminator($name: String)} => name.valueOrAbort + case '{ WriterDerivationConfig.withDiscriminator($name: String) } => + name.valueOrAbort + case '{ WriterDerivationConfig.empty.withDiscriminator($name: String) } => + name.valueOrAbort case other => - report.errorAndAbort(s"Unknown tree: ${other.asTerm.show(using Printer.TreeShortCode)}") + report.errorAndAbort( + s"Unknown tree: ${other.asTerm.show(using Printer.TreeShortCode)}" + ) DiscriminatorConfig(name, TypeRepr.of[String], Nil) diff --git a/modules/core/src/main/scala-3/tethys/derivation/Derivation.scala b/modules/core/src/main/scala-3/tethys/derivation/Derivation.scala index 37e53eae..688c9bc5 100644 --- a/modules/core/src/main/scala-3/tethys/derivation/Derivation.scala +++ b/modules/core/src/main/scala-3/tethys/derivation/Derivation.scala @@ -1,10 +1,19 @@ package tethys.derivation -import tethys.derivation.builder.{ReaderDerivationConfig, WriterDerivationConfig} +import tethys.derivation.builder.{ + ReaderDerivationConfig, + WriterDerivationConfig +} import tethys.writers.tokens.TokenWriter import tethys.readers.{FieldName, ReaderError} import tethys.readers.tokens.TokenIterator -import tethys.{JsonObjectWriter, JsonReader, JsonWriter, ReaderBuilder, WriterBuilder} +import tethys.{ + JsonObjectWriter, + JsonReader, + JsonWriter, + ReaderBuilder, + WriterBuilder +} import scala.Tuple2 import scala.annotation.tailrec import scala.compiletime.{constValueTuple, summonInline} @@ -12,65 +21,101 @@ import scala.quoted.* import scala.collection.mutable import scala.deriving.Mirror -private[tethys] -object Derivation: +private[tethys] object Derivation: - inline def deriveJsonWriterForProduct[T](inline config: WriterBuilder[T]): JsonObjectWriter[T] = - ${ DerivationMacro.deriveJsonWriterForProduct[T]('{config})} + inline def deriveJsonWriterForProduct[T]( + inline config: WriterBuilder[T] + ): JsonObjectWriter[T] = + ${ DerivationMacro.deriveJsonWriterForProduct[T]('{ config }) } inline def deriveJsonWriterForSum[T]: JsonObjectWriter[T] = ${ DerivationMacro.deriveJsonWriterForSum[T] } - inline def deriveJsonReaderForProduct[T](inline config: ReaderBuilder[T]): JsonReader[T] = - ${ DerivationMacro.deriveJsonReaderForProduct[T]('{config})} + inline def deriveJsonReaderForProduct[T]( + inline config: ReaderBuilder[T] + ): JsonReader[T] = + ${ DerivationMacro.deriveJsonReaderForProduct[T]('{ config }) } @deprecated - inline def deriveJsonReaderForProductLegacy[T](inline config: ReaderDerivationConfig)(using mirror: Mirror.ProductOf[T]): JsonReader[T] = - ${ DerivationMacro.deriveJsonReaderForProductLegacy[T]('{config}, '{mirror}) } + inline def deriveJsonReaderForProductLegacy[T]( + inline config: ReaderDerivationConfig + )(using mirror: Mirror.ProductOf[T]): JsonReader[T] = + ${ + DerivationMacro + .deriveJsonReaderForProductLegacy[T]('{ config }, '{ mirror }) + } @deprecated - inline def deriveJsonWriterForProductLegacy[T](inline config: WriterDerivationConfig)(using mirror: Mirror.ProductOf[T]): JsonObjectWriter[T] = - ${ DerivationMacro.deriveJsonWriterForProductLegacy[T]('{config}, '{mirror}) } + inline def deriveJsonWriterForProductLegacy[T]( + inline config: WriterDerivationConfig + )(using mirror: Mirror.ProductOf[T]): JsonObjectWriter[T] = + ${ + DerivationMacro + .deriveJsonWriterForProductLegacy[T]('{ config }, '{ mirror }) + } @deprecated - inline def deriveJsonWriterForSumLegacy[T](inline config: WriterDerivationConfig): JsonObjectWriter[T] = + inline def deriveJsonWriterForSumLegacy[T]( + inline config: WriterDerivationConfig + ): JsonObjectWriter[T] = ${ DerivationMacro.deriveJsonWriterForSumLegacy[T]('{ config }) } inline def deriveJsonReaderForSum[T]: JsonReader[T] = ${ DerivationMacro.deriveJsonReaderForSum[T] } object DerivationMacro: - def deriveJsonWriterForProduct[T: Type](config: Expr[WriterBuilder[T]])(using quotes: Quotes): Expr[JsonObjectWriter[T]] = + def deriveJsonWriterForProduct[T: Type](config: Expr[WriterBuilder[T]])(using + quotes: Quotes + ): Expr[JsonObjectWriter[T]] = new DerivationMacro(quotes).deriveJsonWriterForProduct[T](config) - def deriveJsonWriterForSum[T: Type](using quotes: Quotes): Expr[JsonObjectWriter[T]] = + def deriveJsonWriterForSum[T: Type](using + quotes: Quotes + ): Expr[JsonObjectWriter[T]] = new DerivationMacro(quotes).deriveJsonWriterForSum[T](None) - def deriveJsonReaderForProduct[T: Type](config: Expr[ReaderBuilder[T]])(using quotes: Quotes): Expr[JsonReader[T]] = + def deriveJsonReaderForProduct[T: Type](config: Expr[ReaderBuilder[T]])(using + quotes: Quotes + ): Expr[JsonReader[T]] = new DerivationMacro(quotes).deriveJsonReaderForProduct[T](config) - def deriveJsonReaderForSum[T: Type](using quotes: Quotes): Expr[JsonReader[T]] = + def deriveJsonReaderForSum[T: Type](using + quotes: Quotes + ): Expr[JsonReader[T]] = new DerivationMacro(quotes).deriveJsonReaderForSum[T] @deprecated - def deriveJsonReaderForProductLegacy[T: Type](config: Expr[ReaderDerivationConfig], mirror: Expr[Mirror.ProductOf[T]])(using quotes: Quotes): Expr[JsonReader[T]] = - new DerivationMacro(quotes).deriveJsonReaderForProductLegacy[T](config, mirror) + def deriveJsonReaderForProductLegacy[T: Type]( + config: Expr[ReaderDerivationConfig], + mirror: Expr[Mirror.ProductOf[T]] + )(using quotes: Quotes): Expr[JsonReader[T]] = + new DerivationMacro(quotes) + .deriveJsonReaderForProductLegacy[T](config, mirror) @deprecated - def deriveJsonWriterForProductLegacy[T: Type](config: Expr[WriterDerivationConfig], mirror: Expr[Mirror.ProductOf[T]])(using quotes: Quotes): Expr[JsonObjectWriter[T]] = - new DerivationMacro(quotes).deriveJsonWriterForProductLegacy[T](config, mirror) + def deriveJsonWriterForProductLegacy[T: Type]( + config: Expr[WriterDerivationConfig], + mirror: Expr[Mirror.ProductOf[T]] + )(using quotes: Quotes): Expr[JsonObjectWriter[T]] = + new DerivationMacro(quotes) + .deriveJsonWriterForProductLegacy[T](config, mirror) @deprecated - def deriveJsonWriterForSumLegacy[T: Type](config: Expr[WriterDerivationConfig])(using quotes: Quotes): Expr[JsonObjectWriter[T]] = + def deriveJsonWriterForSumLegacy[T: Type]( + config: Expr[WriterDerivationConfig] + )(using quotes: Quotes): Expr[JsonObjectWriter[T]] = new DerivationMacro(quotes).deriveJsonWriterForSumLegacy[T](config) -private[derivation] -class DerivationMacro(val quotes: Quotes) extends ConfigurationMacroUtils: +private[derivation] class DerivationMacro(val quotes: Quotes) + extends ConfigurationMacroUtils: import quotes.reflect.* - def deriveJsonWriterForProduct[T: Type](config: Expr[WriterBuilder[T]]): Expr[JsonObjectWriter[T]] = + def deriveJsonWriterForProduct[T: Type]( + config: Expr[WriterBuilder[T]] + ): Expr[JsonObjectWriter[T]] = val fields = prepareWriterProductFields(config) - val (missingWriters, refs) = deriveMissingWriters(TypeRepr.of[T], fields.map(_.tpe)) + val (missingWriters, refs) = + deriveMissingWriters(TypeRepr.of[T], fields.map(_.tpe)) val writer = Block( missingWriters, '{ @@ -78,10 +123,19 @@ class DerivationMacro(val quotes: Quotes) extends ConfigurationMacroUtils: override def writeValues(value: T, tokenWriter: TokenWriter): Unit = ${ Expr.block( - fields.map { field => field.tpe.asType match - case '[f] => - val writer = refs.get(field.tpe).fold(lookup[JsonWriter[f]])(_.asExprOf[JsonWriter[f]]) - '{ ${writer}.write(${ field.label }, ${ field.value('{ value }.asTerm).asExprOf[f] }, tokenWriter) } + fields.map { field => + field.tpe.asType match + case '[f] => + val writer = refs + .get(field.tpe) + .fold(lookup[JsonWriter[f]])(_.asExprOf[JsonWriter[f]]) + '{ + ${ writer }.write( + ${ field.label }, + ${ field.value('{ value }.asTerm).asExprOf[f] }, + tokenWriter + ) + } }, '{} ) @@ -90,55 +144,80 @@ class DerivationMacro(val quotes: Quotes) extends ConfigurationMacroUtils: ) writer.asExprOf[JsonObjectWriter[T]] - def deriveJsonWriterForSum[T: Type](legacyConfig: Option[DiscriminatorConfig]): Expr[JsonObjectWriter[T]] = + def deriveJsonWriterForSum[T: Type]( + legacyConfig: Option[DiscriminatorConfig] + ): Expr[JsonObjectWriter[T]] = val tpe = TypeRepr.of[T] val parsedConfig = parseSumConfig[T] val types = getAllChildren(tpe) val (missingWriters, refs) = deriveMissingWritersForSum(types) - val mirror = '{summonInline[Mirror.SumOf[T]]} + val mirror = '{ summonInline[Mirror.SumOf[T]] } val writer = Block( missingWriters, - '{ - new JsonObjectWriter[T]: - override def writeValues(value: T, tokenWriter: TokenWriter): Unit = - ${ - legacyConfig.fold('{}) { case DiscriminatorConfig(label, tpe, values) => - '{ - JsonWriter.stringWriter.write( - name = ${ Expr(label) }, - value = ${Expr.ofList(types.map(t => Expr(t.typeSymbol.name.filterNot(_ == '$'))))}.apply(${mirror}.ordinal(value)), - tokenWriter = tokenWriter - ) - } - } - } - ${ - parsedConfig.discriminator.fold('{}) { case DiscriminatorConfig(label, tpe, discriminators) => - tpe.asType match - case '[discriminatorType] => + '{ + new JsonObjectWriter[T]: + override def writeValues(value: T, tokenWriter: TokenWriter): Unit = + ${ + legacyConfig.fold('{}) { + case DiscriminatorConfig(label, tpe, values) => '{ - ${lookup[JsonWriter[discriminatorType]]}.write( + JsonWriter.stringWriter.write( name = ${ Expr(label) }, - value = ${ Select.unique('{ value }.asTerm, label).asExprOf[discriminatorType] }, + value = ${ + Expr.ofList( + types.map(t => + Expr(t.typeSymbol.name.filterNot(_ == '$')) + ) + ) + }.apply(${ mirror }.ordinal(value)), tokenWriter = tokenWriter ) } + } } - } - ${ matchByTypeAndWrite( - term = '{ value }.asTerm, - types = types, - write = (ref, tpe) => tpe.asType match - case '[t] => - val writer = refs.get(tpe).fold(lookup[JsonObjectWriter[t]])(_.asExprOf[JsonObjectWriter[t]]) - '{ ${writer}.writeValues(${ref.asExprOf[t]}, tokenWriter) } - ) - } - }.asTerm + ${ + parsedConfig.discriminator.fold('{}) { + case DiscriminatorConfig(label, tpe, discriminators) => + tpe.asType match + case '[discriminatorType] => + '{ + ${ lookup[JsonWriter[discriminatorType]] }.write( + name = ${ Expr(label) }, + value = ${ + Select + .unique('{ value }.asTerm, label) + .asExprOf[discriminatorType] + }, + tokenWriter = tokenWriter + ) + } + } + } + ${ + matchByTypeAndWrite( + term = '{ value }.asTerm, + types = types, + write = (ref, tpe) => + tpe.asType match + case '[t] => + val writer = refs + .get(tpe) + .fold(lookup[JsonObjectWriter[t]])( + _.asExprOf[JsonObjectWriter[t]] + ) + '{ + ${ writer } + .writeValues(${ ref.asExprOf[t] }, tokenWriter) + } + ) + } + }.asTerm ) writer.asExprOf[JsonObjectWriter[T]] - private def deriveMissingWritersForSum(types: List[TypeRepr]): (List[ValDef], Map[TypeRepr, Ref]) = + private def deriveMissingWritersForSum( + types: List[TypeRepr] + ): (List[ValDef], Map[TypeRepr, Ref]) = val (stats, refs) = types.flatMap { tpe => tpe.asType match case '[t] => @@ -150,17 +229,26 @@ class DerivationMacro(val quotes: Quotes) extends ConfigurationMacroUtils: Symbol.noSymbol ) val valDef = Option.when(lookupOpt[JsonObjectWriter[t]].isEmpty)( - ValDef(symbol, Some('{ JsonObjectWriter.derived[t](using ${lookup[Mirror.Of[t]]}) }.asTerm)) + ValDef( + symbol, + Some('{ + JsonObjectWriter.derived[t](using ${ lookup[Mirror.Of[t]] }) + }.asTerm) + ) ) valDef.map(valDef => (valDef, (tpe, Ref(valDef.symbol)))) }.unzip (stats, refs.toMap) + private def tpeAsString(tpe: TypeRepr) = + tpe.dealias.show(using Printer.TypeReprCode) - private def tpeAsString(tpe: TypeRepr) = tpe.dealias.show(using Printer.TypeReprCode) - - private def deriveMissingWriters(thisTpe: TypeRepr, tpes: List[TypeRepr]): (List[ValDef], Map[TypeRepr, Ref]) = - val (stats, refs) = distinct(tpes).filterNot(isRecursive(thisTpe, _)) + private def deriveMissingWriters( + thisTpe: TypeRepr, + tpes: List[TypeRepr] + ): (List[ValDef], Map[TypeRepr, Ref]) = + val (stats, refs) = distinct(tpes) + .filterNot(isRecursive(thisTpe, _)) .flatMap { tpe => tpe.asType match case '[t] => @@ -184,25 +272,31 @@ class DerivationMacro(val quotes: Quotes) extends ConfigurationMacroUtils: Symbol.noSymbol ), Some( - other.flatMap(_.toOption) + other + .flatMap(_.toOption) .getOrElse { tpe match case or: OrType => deriveOrTypeJsonWriter[t].asTerm case _ => - '{ JsonObjectWriter.derived[t](using ${ lookup[scala.deriving.Mirror.Of[t]] }) }.asTerm + '{ + JsonObjectWriter.derived[t](using + ${ lookup[scala.deriving.Mirror.Of[t]] } + ) + }.asTerm } ) ) Some((valDef, (tpe, Ref(valDef.symbol)))) - }.unzip + } + .unzip (stats, refs.toMap) - private def deriveOrTypeJsonWriter[T: Type]: Expr[JsonWriter[T]] = def collectTypes(tpe: TypeRepr, acc: List[TypeRepr] = Nil): List[TypeRepr] = tpe match - case OrType(left, right) => collectTypes(left, Nil) ::: acc ::: collectTypes(right, Nil) + case OrType(left, right) => + collectTypes(left, Nil) ::: acc ::: collectTypes(right, Nil) case other => other :: acc val types = collectTypes(TypeRepr.of[T]) @@ -216,28 +310,37 @@ class DerivationMacro(val quotes: Quotes) extends ConfigurationMacroUtils: matchByTypeAndWrite( term = '{ value }.asTerm, types = types, - (ref, tpe) => tpe.asType match - case '[t] => - val writer = refs.get(tpe).fold(lookup[JsonWriter[t]])(_.asExprOf[JsonWriter[t]]) - '{ ${writer}.write(${ref.asExprOf[t]}, tokenWriter) } + (ref, tpe) => + tpe.asType match + case '[t] => + val writer = refs + .get(tpe) + .fold(lookup[JsonWriter[t]])(_.asExprOf[JsonWriter[t]]) + '{ ${ writer }.write(${ ref.asExprOf[t] }, tokenWriter) } ) } }.asTerm ) term.asExprOf[JsonWriter[T]] - - - private def matchByTypeAndWrite(term: Term, - types: List[TypeRepr], - write: (Ref, TypeRepr) => Expr[Unit]): Expr[Unit] = + private def matchByTypeAndWrite( + term: Term, + types: List[TypeRepr], + write: (Ref, TypeRepr) => Expr[Unit] + ): Expr[Unit] = Match( term, types.map { tpe => tpe.asType match case '[t] => val valDef = ValDef( - Symbol.newVal(Symbol.spliceOwner, "value", tpe, Flags.EmptyFlags, Symbol.noSymbol), + Symbol.newVal( + Symbol.spliceOwner, + "value", + tpe, + Flags.EmptyFlags, + Symbol.noSymbol + ), Some(Typed(term, TypeTree.of[t])) ) CaseDef( @@ -248,49 +351,65 @@ class DerivationMacro(val quotes: Quotes) extends ConfigurationMacroUtils: } ).asExprOf[Unit] - def deriveJsonReaderForProduct[T: Type](config: Expr[ReaderBuilder[T]]): Expr[JsonReader[T]] = + def deriveJsonReaderForProduct[T: Type]( + config: Expr[ReaderBuilder[T]] + ): Expr[JsonReader[T]] = val tpe = TypeRepr.of[T] val (fields, isStrict) = prepareReaderProductFields[T](config) val existingLabels = fields.map(_.name).toSet - val fieldsWithoutReader = fields.collect { case field: ReaderField.Extracted if field.reader => field.name } + val fieldsWithoutReader = fields.collect { + case field: ReaderField.Extracted if field.reader => field.name + } val (basicFields, extractedFields) = fields.partitionMap { - case field: ReaderField.Basic => Left(field) + case field: ReaderField.Basic => Left(field) case field: ReaderField.Extracted => Right(field) } - val expectedFieldNames = basicFields.map(_.name).toSet ++ extractedFields.flatMap(_.extractors.map(_._1)) -- extractedFields.map(_.name) + val expectedFieldNames = + basicFields.map(_.name).toSet ++ extractedFields.flatMap( + _.extractors.map(_._1) + ) -- extractedFields.map(_.name) def failIfNotInitialized(fieldName: Expr[FieldName]): Expr[Unit] = basicFields.filterNot(_.default.nonEmpty) match case refs @ head :: tail => - val boolExpr = tail.foldLeft('{!${head.initRef.asExprOf[Boolean]}}) { (acc, el) => - '{${acc} || !${el.initRef.asExprOf[Boolean]}} + val boolExpr = tail.foldLeft('{ + !${ head.initRef.asExprOf[Boolean] } + }) { (acc, el) => + '{ ${ acc } || !${ el.initRef.asExprOf[Boolean] } } } '{ - if {$boolExpr} then - val uninitializedFields = new scala.collection.mutable.ArrayBuffer[String](${ Expr(refs.size) }) + if { $boolExpr } then + val uninitializedFields = + new scala.collection.mutable.ArrayBuffer[String](${ + Expr(refs.size) + }) ${ Expr.block( refs.map { ref => '{ - if !${ref.initRef.asExprOf[Boolean]} then - uninitializedFields += ${Expr(ref.name)} + if !${ ref.initRef.asExprOf[Boolean] } then + uninitializedFields += ${ Expr(ref.name) } } }, - '{} + '{} ) } - ReaderError.wrongJson("Can not extract fields from json: " + uninitializedFields.mkString(", "))(${fieldName}) + ReaderError.wrongJson( + "Can not extract fields from json: " + uninitializedFields + .mkString(", ") + )(${ fieldName }) } case Nil => '{} if tpe.typeSymbol.flags.is(Flags.Module) then - '{JsonReader.const(${Ref(tpe.termSymbol).asExprOf[T]})} + '{ JsonReader.const(${ Ref(tpe.termSymbol).asExprOf[T] }) } else - val (missingReaders, refs) = deriveMissingReaders(tpe, basicFields.map(_.tpe)) + val (missingReaders, refs) = + deriveMissingReaders(tpe, basicFields.map(_.tpe)) val term = Block( missingReaders, '{ @@ -298,101 +417,151 @@ class DerivationMacro(val quotes: Quotes) extends ConfigurationMacroUtils: given JsonReader[T] = this override def read(it: TokenIterator)(using fieldName: FieldName) = if !it.currentToken().isObjectStart then - ReaderError.wrongJson("Expected object start but found: " + it.currentToken().toString) + ReaderError.wrongJson( + "Expected object start but found: " + it + .currentToken() + .toString + ) else it.nextToken() ${ - Block( - fields.flatMap(_.initialize), - '{ - while (!it.currentToken().isObjectEnd) - val jsonName = it.fieldName() + Block( + fields.flatMap(_.initialize), + '{ + while (!it.currentToken().isObjectEnd) + val jsonName = it.fieldName() + it.nextToken() + ${ + Match( + selector = '{ jsonName }.asTerm, + cases = fields.flatMap( + _.initializeFieldCase( + refs, + '{ it }, + '{ fieldName } + ) + ) :+ + CaseDef( + Wildcard(), + None, + if isStrict then + '{ + ReaderError.wrongJson( + s"unexpected field '$jsonName', expected one of ${${ Expr(expectedFieldNames.mkString("'", "', '", "'")) }}" + ) + }.asTerm + else '{ it.skipExpression(); () }.asTerm + ) + ).asExprOf[Unit] + } it.nextToken() - ${ - Match( - selector = '{ jsonName }.asTerm, - cases = fields.flatMap(_.initializeFieldCase(refs, '{ it }, '{ fieldName })) :+ - CaseDef( - Wildcard(), - None, - if isStrict then - '{ ReaderError.wrongJson(s"unexpected field '$jsonName', expected one of ${${ Expr(expectedFieldNames.mkString("'", "', '", "'")) }}") }.asTerm - else - '{ it.skipExpression() ; () }.asTerm - ) - ).asExprOf[Unit] - } - it.nextToken() - ${ failIfNotInitialized('{ fieldName }) } + ${ failIfNotInitialized('{ fieldName }) } - ${ - val allRefs = fields.map(field => field.name -> field.ref).toMap - Expr.block(extractedFields.flatMap(_.extract(allRefs, '{fieldName})).map(_.asExprOf[Unit]), '{}) - } + ${ + val allRefs = + fields.map(field => field.name -> field.ref).toMap + Expr.block( + extractedFields + .flatMap(_.extract(allRefs, '{ fieldName })) + .map(_.asExprOf[Unit]), + '{} + ) + } - ${ - New(TypeTree.of[T]) - .select(tpe.classSymbol.get.primaryConstructor) - .appliedToTypes(tpe.typeArgs) - .appliedToArgs(fields.filterNot(_.idx == -1).sortBy(_.idx).map(_.ref)) - .asExprOf[T] - } + ${ + New(TypeTree.of[T]) + .select(tpe.classSymbol.get.primaryConstructor) + .appliedToTypes(tpe.typeArgs) + .appliedToArgs( + fields + .filterNot(_.idx == -1) + .sortBy(_.idx) + .map(_.ref) + ) + .asExprOf[T] + } - }.asTerm - ).asExprOf[T] - } + }.asTerm + ).asExprOf[T] + } }.asTerm ) term.asExprOf[JsonReader[T]] - def deriveJsonReaderForSum[T: Type]: Expr[JsonReader[T]] = val tpe = TypeRepr.of[T] val parsed = parseSumConfig[T] val children = getAllChildren(tpe) parsed.discriminator match - case Some(DiscriminatorConfig(label, tpe, discriminators)) => tpe.asType match - case '[discriminator] => - val (discriminatorStats, discriminatorRefs) = discriminators.zipWithIndex.map((term, idx) => - val stat = ValDef( - Symbol.newVal(Symbol.spliceOwner, s"Discriminator_$idx", term.tpe, Flags.Private, Symbol.noSymbol), - Some(term) - ) - (stat, Ref(stat.symbol)) - ).unzip - val (readers, refs) = deriveMissingReaders(TypeRepr.of[T], children) - val term = Block( - readers ++ discriminatorStats, - '{ - JsonReader.builder - .addField[discriminator]( - name = ${Expr(label)}, - jsonReader = ${lookup[JsonReader[discriminator]]} + case Some(DiscriminatorConfig(label, tpe, discriminators)) => + tpe.asType match + case '[discriminator] => + val (discriminatorStats, discriminatorRefs) = + discriminators.zipWithIndex + .map((term, idx) => + val stat = ValDef( + Symbol.newVal( + Symbol.spliceOwner, + s"Discriminator_$idx", + term.tpe, + Flags.Private, + Symbol.noSymbol + ), + Some(term) + ) + (stat, Ref(stat.symbol)) ) - .selectReader[T] { discriminator => - ${ - Match( - '{discriminator}.asTerm, - children.zip(discriminatorRefs).map((tpe, branchDiscriminator) => tpe.asType match - case '[t] => - CaseDef( - branchDiscriminator, - None, - Typed(refs.getOrElse(tpe, lookup[JsonReader[t]].asTerm), TypeTree.of[JsonReader[? <: T]]) - ) - ) :+ CaseDef(Wildcard(), None, - '{ReaderError.wrongJson(s"Unexpected discriminator found: $discriminator")(using FieldName(${Expr(label)})) }.asTerm - ) - ).asExprOf[JsonReader[? <: T]] + .unzip + val (readers, refs) = deriveMissingReaders(TypeRepr.of[T], children) + val term = Block( + readers ++ discriminatorStats, + '{ + JsonReader.builder + .addField[discriminator]( + name = ${ Expr(label) }, + jsonReader = ${ lookup[JsonReader[discriminator]] } + ) + .selectReader[T] { discriminator => + ${ + Match( + '{ discriminator }.asTerm, + children + .zip(discriminatorRefs) + .map((tpe, branchDiscriminator) => + tpe.asType match + case '[t] => + CaseDef( + branchDiscriminator, + None, + Typed( + refs.getOrElse( + tpe, + lookup[JsonReader[t]].asTerm + ), + TypeTree.of[JsonReader[? <: T]] + ) + ) + ) :+ CaseDef( + Wildcard(), + None, + '{ + ReaderError.wrongJson( + s"Unexpected discriminator found: $discriminator" + )(using FieldName(${ Expr(label) })) + }.asTerm + ) + ).asExprOf[JsonReader[? <: T]] + } } - } - }.asTerm - ) - term.asExprOf[JsonReader[T]] + }.asTerm + ) + term.asExprOf[JsonReader[T]] case None => - report.errorAndAbort("Discriminator is required to derive JsonReader for sum type. Use @selector annotation") + report.errorAndAbort( + "Discriminator is required to derive JsonReader for sum type. Use @selector annotation" + ) private def distinct(tpes: List[TypeRepr]) = tpes.foldLeft(List.empty[TypeRepr]) { (acc, tpe) => @@ -403,10 +572,15 @@ class DerivationMacro(val quotes: Quotes) extends ConfigurationMacroUtils: private def isRecursive(tpe: TypeRepr, childTpe: TypeRepr): Boolean = tpe =:= childTpe || (childTpe match case AppliedType(_, types) => types.exists(isRecursive(tpe, _)) - case _ => false) + case _ => false + ) - private def deriveMissingReaders(thisTpe: TypeRepr, tpes: List[TypeRepr]): (List[ValDef], Map[TypeRepr, Ref]) = - val (stats, refs) = distinct(tpes).filterNot(isRecursive(thisTpe, _)) + private def deriveMissingReaders( + thisTpe: TypeRepr, + tpes: List[TypeRepr] + ): (List[ValDef], Map[TypeRepr, Ref]) = + val (stats, refs) = distinct(tpes) + .filterNot(isRecursive(thisTpe, _)) .flatMap { tpe => tpe.asType match case '[t] => @@ -430,29 +604,42 @@ class DerivationMacro(val quotes: Quotes) extends ConfigurationMacroUtils: Symbol.noSymbol ), Some( - other.flatMap(_.toOption) + other + .flatMap(_.toOption) .getOrElse { - '{ JsonReader.derived[t](using ${ lookup[scala.deriving.Mirror.Of[t]] }) }.asTerm + '{ + JsonReader.derived[t](using + ${ lookup[scala.deriving.Mirror.Of[t]] } + ) + }.asTerm } ) ) Some((valDef, (tpe, Ref(valDef.symbol)))) - }.unzip + } + .unzip (stats, refs.toMap) - @deprecated - def deriveJsonReaderForProductLegacy[T: Type](config: Expr[ReaderDerivationConfig], - mirror: Expr[Mirror.ProductOf[T]] - ): Expr[JsonReader[T]] = - deriveJsonReaderForProduct(parseLegacyReaderDerivationConfig(config, mirror)) + def deriveJsonReaderForProductLegacy[T: Type]( + config: Expr[ReaderDerivationConfig], + mirror: Expr[Mirror.ProductOf[T]] + ): Expr[JsonReader[T]] = + deriveJsonReaderForProduct( + parseLegacyReaderDerivationConfig(config, mirror) + ) @deprecated - def deriveJsonWriterForProductLegacy[T: Type](config: Expr[WriterDerivationConfig], - mirror: Expr[Mirror.ProductOf[T]]): Expr[JsonObjectWriter[T]] = - deriveJsonWriterForProduct(parseLegacyWriterDerivationConfig(config, mirror)) - + def deriveJsonWriterForProductLegacy[T: Type]( + config: Expr[WriterDerivationConfig], + mirror: Expr[Mirror.ProductOf[T]] + ): Expr[JsonObjectWriter[T]] = + deriveJsonWriterForProduct( + parseLegacyWriterDerivationConfig(config, mirror) + ) @deprecated - def deriveJsonWriterForSumLegacy[T: Type](config: Expr[WriterDerivationConfig]): Expr[JsonObjectWriter[T]] = + def deriveJsonWriterForSumLegacy[T: Type]( + config: Expr[WriterDerivationConfig] + ): Expr[JsonObjectWriter[T]] = deriveJsonWriterForSum(Some(parseLegacyDiscriminator(config))) diff --git a/modules/core/src/main/scala-3/tethys/derivation/EnumCompanion.scala b/modules/core/src/main/scala-3/tethys/derivation/EnumCompanion.scala index 8f5356fe..d217b2ac 100644 --- a/modules/core/src/main/scala-3/tethys/derivation/EnumCompanion.scala +++ b/modules/core/src/main/scala-3/tethys/derivation/EnumCompanion.scala @@ -1,33 +1,35 @@ package tethys.derivation -private[tethys] -object EnumCompanion: +private[tethys] object EnumCompanion: inline def getByName[T](name: String): T = ${ EnumCompanionMacro.getByName[T]('{ name }) } inline def getByOrdinal[T](ordinal: Int): T = ${ EnumCompanionMacro.getByOrdinal[T]('{ ordinal }) } - + inline def isEnum[T]: Boolean = ${ EnumCompanionMacro.isEnum[T] } - -private[derivation] -object EnumCompanionMacro: +private[derivation] object EnumCompanionMacro: import scala.quoted.* - def getByName[T: scala.quoted.Type](name: Expr[String])(using quotes: Quotes): Expr[T] = + def getByName[T: scala.quoted.Type](name: Expr[String])(using + quotes: Quotes + ): Expr[T] = import quotes.reflect.* - Select.unique(Ref(TypeRepr.of[T].typeSymbol.companionModule), "valueOf") + Select + .unique(Ref(TypeRepr.of[T].typeSymbol.companionModule), "valueOf") .appliedToArgs(List(name.asTerm)) .asExprOf[T] - - def getByOrdinal[T: scala.quoted.Type](ordinal: Expr[Int])(using quotes: Quotes): Expr[T] = + def getByOrdinal[T: scala.quoted.Type](ordinal: Expr[Int])(using + quotes: Quotes + ): Expr[T] = import quotes.reflect.* - Select.unique(Ref(TypeRepr.of[T].typeSymbol.companionModule), "fromOrdinal") + Select + .unique(Ref(TypeRepr.of[T].typeSymbol.companionModule), "fromOrdinal") .appliedToArgs(List(ordinal.asTerm)) .asExprOf[T] - + def isEnum[T: scala.quoted.Type](using quotes: Quotes): Expr[Boolean] = import quotes.reflect.* Expr(TypeRepr.of[T].typeSymbol.flags.is(Flags.Enum)) diff --git a/modules/core/src/main/scala-3/tethys/derivation/JsonObjectWriterDerivation.scala b/modules/core/src/main/scala-3/tethys/derivation/JsonObjectWriterDerivation.scala index 23d0f002..cff0a8f9 100644 --- a/modules/core/src/main/scala-3/tethys/derivation/JsonObjectWriterDerivation.scala +++ b/modules/core/src/main/scala-3/tethys/derivation/JsonObjectWriterDerivation.scala @@ -7,15 +7,24 @@ import tethys.{JsonObjectWriter, JsonWriter, WriterBuilder} import tethys.writers.tokens.TokenWriter import scala.deriving.Mirror -import scala.compiletime.{constValueTuple, erasedValue, summonFrom, summonInline} +import scala.compiletime.{ + constValueTuple, + erasedValue, + summonFrom, + summonInline +} private[tethys] trait JsonObjectWriterDerivation: - inline def derived[A](inline config: WriterBuilder[A])(using mirror: Mirror.ProductOf[A]) = + inline def derived[A](inline config: WriterBuilder[A])(using + mirror: Mirror.ProductOf[A] + ) = Derivation.deriveJsonWriterForProduct[A](config) - + @deprecated("Use WriterBuilder instead") - inline def derived[A](inline config: WriterDerivationConfig)(using mirror: Mirror.Of[A]) = + inline def derived[A](inline config: WriterDerivationConfig)(using + mirror: Mirror.Of[A] + ) = inline mirror match case given Mirror.ProductOf[A] => Derivation.deriveJsonWriterForProductLegacy[A](config) @@ -36,4 +45,3 @@ private[tethys] trait JsonObjectWriterDerivation: case given Mirror.SumOf[A] => Derivation.deriveJsonWriterForSum[A] - \ No newline at end of file diff --git a/modules/core/src/main/scala-3/tethys/derivation/JsonReaderDerivation.scala b/modules/core/src/main/scala-3/tethys/derivation/JsonReaderDerivation.scala index 8aa62ce1..36b957f4 100644 --- a/modules/core/src/main/scala-3/tethys/derivation/JsonReaderDerivation.scala +++ b/modules/core/src/main/scala-3/tethys/derivation/JsonReaderDerivation.scala @@ -9,26 +9,36 @@ import tethys.derivation.builder.ReaderDerivationConfig import scala.collection.mutable import scala.deriving.Mirror -import scala.compiletime.{constValue, constValueTuple, erasedValue, summonFrom, summonInline} +import scala.compiletime.{ + constValue, + constValueTuple, + erasedValue, + summonFrom, + summonInline +} - -private [tethys] -trait JsonReaderDerivation: +private[tethys] trait JsonReaderDerivation: def const[A](value: A): JsonReader[A] = new JsonReader[A]: override def read(it: TokenIterator)(implicit fieldName: FieldName): A = if !it.currentToken().isObjectStart then - ReaderError.wrongJson("Expected object start but found: " + it.currentToken().toString) + ReaderError.wrongJson( + "Expected object start but found: " + it.currentToken().toString + ) else { it.skipExpression() value } - inline def derived[A](inline config: ReaderBuilder[A])(using mirror: Mirror.ProductOf[A]): JsonReader[A] = + inline def derived[A](inline config: ReaderBuilder[A])(using + mirror: Mirror.ProductOf[A] + ): JsonReader[A] = Derivation.deriveJsonReaderForProduct[A](config) @deprecated("Use ReaderBuilder instead") - inline def derived[A](inline config: ReaderDerivationConfig)(using mirror: Mirror.ProductOf[A]): JsonReader[A] = + inline def derived[A](inline config: ReaderDerivationConfig)(using + mirror: Mirror.ProductOf[A] + ): JsonReader[A] = Derivation.deriveJsonReaderForProductLegacy[A](config) inline def derived[A](using mirror: Mirror.Of[A]): JsonReader[A] = @@ -37,9 +47,8 @@ trait JsonReaderDerivation: Derivation.deriveJsonReaderForProduct[A]( summonFrom[ReaderBuilder[A]] { case config: ReaderBuilder[A] => config - case _ => ReaderBuilder[A] + case _ => ReaderBuilder[A] } ) case given Mirror.SumOf[A] => Derivation.deriveJsonReaderForSum[A] - \ No newline at end of file diff --git a/modules/core/src/main/scala-3/tethys/derivation/builder/FieldStyle.scala b/modules/core/src/main/scala-3/tethys/derivation/builder/FieldStyle.scala index e1a9c1bb..8b29e5c7 100644 --- a/modules/core/src/main/scala-3/tethys/derivation/builder/FieldStyle.scala +++ b/modules/core/src/main/scala-3/tethys/derivation/builder/FieldStyle.scala @@ -9,8 +9,8 @@ enum FieldStyle { case KebabCase, LowerKebabCase, UpperKebabCase, CapitalizedKebabCase case SnakeCase, LowerSnakeCase, UpperSnakeCase, CapitalizedSnakeCase - + case capitalize, uncapitalize, lowercase, uppercase case kebabCase, lowerKebabCase, upperKebabCase, capitalizedKebabCase - case snakeCase, lowerSnakeCase, upperSnakeCase, capitalizedSnakeCase + case snakeCase, lowerSnakeCase, upperSnakeCase, capitalizedSnakeCase } diff --git a/modules/core/src/main/scala-3/tethys/derivation/builder/ReaderDescription.scala b/modules/core/src/main/scala-3/tethys/derivation/builder/ReaderDescription.scala index d56b131a..bf7a3071 100644 --- a/modules/core/src/main/scala-3/tethys/derivation/builder/ReaderDescription.scala +++ b/modules/core/src/main/scala-3/tethys/derivation/builder/ReaderDescription.scala @@ -5,7 +5,9 @@ import tethys.FieldStyle @deprecated("Use ReaderBuilder[A] instead") case class ReaderDerivationConfig() { def withFieldStyle(fieldStyle: FieldStyle): ReaderDerivationConfig = this - def withFieldStyle(fieldStyle: tethys.derivation.builder.FieldStyle): ReaderDerivationConfig = this + def withFieldStyle( + fieldStyle: tethys.derivation.builder.FieldStyle + ): ReaderDerivationConfig = this def strict: ReaderDerivationConfig = this } @@ -13,12 +15,17 @@ case class ReaderDerivationConfig() { object ReaderDerivationConfig { def empty: ReaderDerivationConfig = ReaderDerivationConfig() def withFieldStyle(fieldStyle: FieldStyle): ReaderDerivationConfig = empty - def withFieldStyle(fieldStyle: tethys.derivation.builder.FieldStyle): ReaderDerivationConfig = empty + def withFieldStyle( + fieldStyle: tethys.derivation.builder.FieldStyle + ): ReaderDerivationConfig = empty def strict: ReaderDerivationConfig = empty } @deprecated("Use ReaderBuilder[A] instead") -case class ReaderDescription[A](config: ReaderDerivationConfig, operations: Seq[ReaderDescription.BuilderOperation]) +case class ReaderDescription[A]( + config: ReaderDerivationConfig, + operations: Seq[ReaderDescription.BuilderOperation] +) object ReaderDescription { sealed trait Field[A] @@ -27,12 +34,20 @@ object ReaderDescription { final case class RawField[A](name: String) extends Field[A] } - sealed trait BuilderOperation object BuilderOperation { - final case class ExtractFieldAs[B, C](field: String, fun: B => C) extends BuilderOperation - final case class ExtractFieldValue(field: String, from: Seq[Field[?]], fun: Any) extends BuilderOperation - final case class ExtractFieldReader(field: String, from: Seq[Field[?]], fun: Any) extends BuilderOperation + final case class ExtractFieldAs[B, C](field: String, fun: B => C) + extends BuilderOperation + final case class ExtractFieldValue( + field: String, + from: Seq[Field[?]], + fun: Any + ) extends BuilderOperation + final case class ExtractFieldReader( + field: String, + from: Seq[Field[?]], + fun: Any + ) extends BuilderOperation } } diff --git a/modules/core/src/main/scala-3/tethys/derivation/builder/WriterDescription.scala b/modules/core/src/main/scala-3/tethys/derivation/builder/WriterDescription.scala index 1120f6b0..4c9d8b75 100644 --- a/modules/core/src/main/scala-3/tethys/derivation/builder/WriterDescription.scala +++ b/modules/core/src/main/scala-3/tethys/derivation/builder/WriterDescription.scala @@ -4,31 +4,58 @@ import tethys.FieldStyle import tethys.derivation.builder.WriterDescription.BuilderOperation @deprecated("Use WriterBuilder[A] instead") -case class WriterDerivationConfig(fieldStyle: Option[FieldStyle], discriminator: Option[String] = None) { +case class WriterDerivationConfig( + fieldStyle: Option[FieldStyle], + discriminator: Option[String] = None +) { def withFieldStyle(fieldStyle: FieldStyle): WriterDerivationConfig = this - def withFieldStyle(fieldStyle: tethys.derivation.builder.FieldStyle): WriterDerivationConfig = this + def withFieldStyle( + fieldStyle: tethys.derivation.builder.FieldStyle + ): WriterDerivationConfig = this def withDiscriminator(discriminator: String): WriterDerivationConfig = this } object WriterDerivationConfig { def empty: WriterDerivationConfig = WriterDerivationConfig(None) def withFieldStyle(fieldStyle: FieldStyle): WriterDerivationConfig = empty - def withFieldStyle(fieldStyle: tethys.derivation.builder.FieldStyle): WriterDerivationConfig = empty + def withFieldStyle( + fieldStyle: tethys.derivation.builder.FieldStyle + ): WriterDerivationConfig = empty def withDiscriminator(discriminator: String): WriterDerivationConfig = empty } @deprecated("Use WriterBuilder[A] instead") -case class WriterDescription[A](config: WriterDerivationConfig, operations: Seq[BuilderOperation[A]]) +case class WriterDescription[A]( + config: WriterDerivationConfig, + operations: Seq[BuilderOperation[A]] +) object WriterDescription { trait BuilderOperation[A] object BuilderOperation { case class Remove[T](field: String) extends BuilderOperation[T] - case class Update[T, From, To](field: String, name: Option[String], fun: From => To) extends BuilderOperation[T] - case class UpdateFromRoot[T, To](field: String, name: Option[String], fun: T => To) extends BuilderOperation[T] - case class UpdatePartial[T, From, To](field: String, name: Option[String], fun: PartialFunction[From, To]) extends BuilderOperation[T] - case class UpdatePartialFromRoot[T, To](field: String, name: Option[String], fun: PartialFunction[T, To]) extends BuilderOperation[T] - case class Add[T, To](field: String, fun: T => To) extends BuilderOperation[T] + case class Update[T, From, To]( + field: String, + name: Option[String], + fun: From => To + ) extends BuilderOperation[T] + case class UpdateFromRoot[T, To]( + field: String, + name: Option[String], + fun: T => To + ) extends BuilderOperation[T] + case class UpdatePartial[T, From, To]( + field: String, + name: Option[String], + fun: PartialFunction[From, To] + ) extends BuilderOperation[T] + case class UpdatePartialFromRoot[T, To]( + field: String, + name: Option[String], + fun: PartialFunction[T, To] + ) extends BuilderOperation[T] + case class Add[T, To](field: String, fun: T => To) + extends BuilderOperation[T] } } diff --git a/modules/core/src/main/scala/tethys/JsonObjectWriter.scala b/modules/core/src/main/scala/tethys/JsonObjectWriter.scala index f6b16565..3c37c0d7 100644 --- a/modules/core/src/main/scala/tethys/JsonObjectWriter.scala +++ b/modules/core/src/main/scala/tethys/JsonObjectWriter.scala @@ -16,25 +16,33 @@ trait JsonObjectWriter[A] extends JsonWriter[A] { def ++(that: JsonObjectWriter[A]): JsonObjectWriter[A] = concat(that) - def concat(that: JsonObjectWriter[A]): JsonObjectWriter[A] = new JsonObjectWriter[A] { - override def writeValues(value: A, tokenWriter: TokenWriter): Unit = { - self.writeValues(value, tokenWriter) - that.writeValues(value, tokenWriter) + def concat(that: JsonObjectWriter[A]): JsonObjectWriter[A] = + new JsonObjectWriter[A] { + override def writeValues(value: A, tokenWriter: TokenWriter): Unit = { + self.writeValues(value, tokenWriter) + that.writeValues(value, tokenWriter) + } } - } - override def contramap[B](fun: B => A): JsonObjectWriter[B] = new JsonObjectWriter[B] { - override def writeValues(value: B, tokenWriter: TokenWriter): Unit = - self.writeValues(fun(value), tokenWriter) - } + override def contramap[B](fun: B => A): JsonObjectWriter[B] = + new JsonObjectWriter[B] { + override def writeValues(value: B, tokenWriter: TokenWriter): Unit = + self.writeValues(fun(value), tokenWriter) + } } -object JsonObjectWriter extends LowPriorityJsonObjectWriters with derivation.JsonObjectWriterDerivation { - def apply[A](implicit jsonObjectWriter: JsonObjectWriter[A]): JsonObjectWriter[A] = jsonObjectWriter +object JsonObjectWriter + extends LowPriorityJsonObjectWriters + with derivation.JsonObjectWriterDerivation { + def apply[A](implicit + jsonObjectWriter: JsonObjectWriter[A] + ): JsonObjectWriter[A] = jsonObjectWriter } private[tethys] trait LowPriorityJsonObjectWriters { - implicit final def lowPriorityWriter[A](implicit lowPriorityInstance: LowPriorityInstance[JsonObjectWriter[A]]): JsonObjectWriter[A] = { + implicit final def lowPriorityWriter[A](implicit + lowPriorityInstance: LowPriorityInstance[JsonObjectWriter[A]] + ): JsonObjectWriter[A] = { lowPriorityInstance.instance } -} \ No newline at end of file +} diff --git a/modules/core/src/main/scala/tethys/JsonReader.scala b/modules/core/src/main/scala/tethys/JsonReader.scala index 14d99b90..ae3fea56 100644 --- a/modules/core/src/main/scala/tethys/JsonReader.scala +++ b/modules/core/src/main/scala/tethys/JsonReader.scala @@ -12,12 +12,15 @@ trait JsonReader[@specialized(specializations) A] { def read(it: TokenIterator)(implicit fieldName: FieldName): A def map[B](fun: A => B): JsonReader[B] = new JsonReader[B] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): B = fun(self.read(it)) + override def read(it: TokenIterator)(implicit fieldName: FieldName): B = + fun(self.read(it)) } - def mapWithField[B](fun: FieldName => A => B): JsonReader[B] = new JsonReader[B] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): B = fun(fieldName)(self.read(it)) - } + def mapWithField[B](fun: FieldName => A => B): JsonReader[B] = + new JsonReader[B] { + override def read(it: TokenIterator)(implicit fieldName: FieldName): B = + fun(fieldName)(self.read(it)) + } } object JsonReader extends AllJsonReaders with derivation.JsonReaderDerivation { diff --git a/modules/core/src/main/scala/tethys/JsonStreaming.scala b/modules/core/src/main/scala/tethys/JsonStreaming.scala index fe6b469a..3f95e949 100644 --- a/modules/core/src/main/scala/tethys/JsonStreaming.scala +++ b/modules/core/src/main/scala/tethys/JsonStreaming.scala @@ -6,9 +6,13 @@ import tethys.writers.tokens.TokenWriter object JsonStreaming { - def streamValue(from: TokenIterator, to: TokenWriter)(implicit fieldName: FieldName): Unit = writeCurrentValue(from, to) + def streamValue(from: TokenIterator, to: TokenWriter)(implicit + fieldName: FieldName + ): Unit = writeCurrentValue(from, to) - private def writeCurrentValue(it: TokenIterator, writer: TokenWriter)(implicit fieldName: FieldName): Unit = { + private def writeCurrentValue(it: TokenIterator, writer: TokenWriter)(implicit + fieldName: FieldName + ): Unit = { val token = it.currentToken() if (token.isArrayStart) writeArray(it, writer) else if (token.isObjectStart) writeObject(it, writer) @@ -20,7 +24,9 @@ object JsonStreaming { it.next() } - private def writeArray(it: TokenIterator, writer: TokenWriter)(implicit fieldName: FieldName): Unit = { + private def writeArray(it: TokenIterator, writer: TokenWriter)(implicit + fieldName: FieldName + ): Unit = { it.next() writer.writeArrayStart() var index: Int = 0 @@ -31,12 +37,14 @@ object JsonStreaming { writer.writeArrayEnd() } - private def writeObject(it: TokenIterator, writer: TokenWriter)(implicit fieldName: FieldName): Unit = { + private def writeObject(it: TokenIterator, writer: TokenWriter)(implicit + fieldName: FieldName + ): Unit = { it.next() writer.writeObjectStart() while (!it.currentToken().isObjectEnd) { val token = it.currentToken() - if(token.isFieldName) { + if (token.isFieldName) { val name = it.fieldName() writer.writeFieldName(name) writeCurrentValue(it.next(), writer)(fieldName.appendFieldName(name)) diff --git a/modules/core/src/main/scala/tethys/JsonWriter.scala b/modules/core/src/main/scala/tethys/JsonWriter.scala index 80a3df60..041a8ae0 100644 --- a/modules/core/src/main/scala/tethys/JsonWriter.scala +++ b/modules/core/src/main/scala/tethys/JsonWriter.scala @@ -16,7 +16,11 @@ trait JsonWriter[@specialized(specializations) A] { def write(value: A, tokenWriter: TokenWriter): Unit def contramap[B](fun: B => A): JsonWriter[B] = new JsonWriter[B] { - override def write(name: String, value: B, tokenWriter: TokenWriter): Unit = { + override def write( + name: String, + value: B, + tokenWriter: TokenWriter + ): Unit = { self.write(name, fun(value), tokenWriter) } @@ -26,7 +30,9 @@ trait JsonWriter[@specialized(specializations) A] { } } -object JsonWriter extends AllJsonWriters with derivation.JsonObjectWriterDerivation { +object JsonWriter + extends AllJsonWriters + with derivation.JsonObjectWriterDerivation { def apply[A](implicit jsonWriter: JsonWriter[A]): JsonWriter[A] = jsonWriter diff --git a/modules/core/src/main/scala/tethys/commons/RawJson.scala b/modules/core/src/main/scala/tethys/commons/RawJson.scala index f6521d22..26b40093 100644 --- a/modules/core/src/main/scala/tethys/commons/RawJson.scala +++ b/modules/core/src/main/scala/tethys/commons/RawJson.scala @@ -11,11 +11,16 @@ final case class RawJson(json: String) object RawJson { implicit val rawJsonWriter: JsonWriter[RawJson] = new JsonWriter[RawJson] { - override def write(value: RawJson, tokenWriter: TokenWriter): Unit = tokenWriter.writeRawJson(value.json) + override def write(value: RawJson, tokenWriter: TokenWriter): Unit = + tokenWriter.writeRawJson(value.json) } - implicit def rawJsonReader(implicit tokenWriterProducer: TokenWriterProducer): JsonReader[RawJson] = new JsonReader[RawJson] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): RawJson = { + implicit def rawJsonReader(implicit + tokenWriterProducer: TokenWriterProducer + ): JsonReader[RawJson] = new JsonReader[RawJson] { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): RawJson = { val stringWriter = new StringWriter() val tokenWriter: TokenWriter = tokenWriterProducer.forWriter(stringWriter) JsonStreaming.streamValue(it, tokenWriter) diff --git a/modules/core/src/main/scala/tethys/commons/TokenNode.scala b/modules/core/src/main/scala/tethys/commons/TokenNode.scala index ede41096..306978d4 100644 --- a/modules/core/src/main/scala/tethys/commons/TokenNode.scala +++ b/modules/core/src/main/scala/tethys/commons/TokenNode.scala @@ -59,10 +59,9 @@ object TokenNode { override val token: Token = NumberValueToken } - def obj(fields: (String, Any)*): List[TokenNode] = { - val tokens = fields.toList.flatMap { - case (name, a) => FieldNameNode(name) :: anyToTokens(a) + val tokens = fields.toList.flatMap { case (name, a) => + FieldNameNode(name) :: anyToTokens(a) } ObjectStartNode :: tokens ::: ObjectEndNode :: Nil @@ -81,31 +80,35 @@ object TokenNode { def value(v: Float): List[TokenNode] = FloatValueNode(v) :: Nil def value(v: Double): List[TokenNode] = DoubleValueNode(v) :: Nil def value(v: BigInt): List[TokenNode] = NumberValueNode(v) :: Nil - def value(v: java.math.BigInteger): List[TokenNode] = NumberValueNode(v) :: Nil + def value(v: java.math.BigInteger): List[TokenNode] = + NumberValueNode(v) :: Nil def value(v: BigDecimal): List[TokenNode] = NumberValueNode(v) :: Nil - def value(v: java.math.BigDecimal): List[TokenNode] = NumberValueNode(v) :: Nil + def value(v: java.math.BigDecimal): List[TokenNode] = + NumberValueNode(v) :: Nil private def anyToTokens(any: Any): List[TokenNode] = any match { - case v: TokenNode => v :: Nil - case nodes: List[_] => nodes.flatMap(anyToTokens) - case v: String => value(v) - case v: Byte => value(v) - case v: Short => value(v) - case v: Int => value(v) - case v: Long => value(v) + case v: TokenNode => v :: Nil + case nodes: List[_] => nodes.flatMap(anyToTokens) + case v: String => value(v) + case v: Byte => value(v) + case v: Short => value(v) + case v: Int => value(v) + case v: Long => value(v) case v: java.math.BigInteger => value(v) - case v: BigInt => value(v) - case v: Double => value(v) - case v: Float => value(v) + case v: BigInt => value(v) + case v: Double => value(v) + case v: Float => value(v) case v: java.math.BigDecimal => value(v) - case v: BigDecimal => value(v) - case v: Boolean => value(v) - case null | None => NullValueNode :: Nil - case v => throw new Exception(s"Can't auto wrap '$v'") + case v: BigDecimal => value(v) + case v: Boolean => value(v) + case null | None => NullValueNode :: Nil + case v => throw new Exception(s"Can't auto wrap '$v'") } implicit class TokenNodesOps(val json: String) extends AnyVal { - def jsonAsTokensList(implicit producer: TokenIteratorProducer): List[TokenNode] = { + def jsonAsTokensList(implicit + producer: TokenIteratorProducer + ): List[TokenNode] = { import tethys._ val iterator = json.toTokenIterator.fold(throw _, identity) val builder = List.newBuilder[TokenNode] @@ -120,13 +123,13 @@ object TokenNode { else if (token.isFieldName) FieldNameNode(iterator.fieldName()) else if (token.isStringValue) StringValueNode(iterator.string()) else if (token.isNumberValue) iterator.number() match { - case v: java.lang.Byte => ByteValueNode(v) - case v: java.lang.Short => ShortValueNode(v) + case v: java.lang.Byte => ByteValueNode(v) + case v: java.lang.Short => ShortValueNode(v) case v: java.lang.Integer => IntValueNode(v) - case v: java.lang.Long => LongValueNode(v) - case v: java.lang.Float => FloatValueNode(v) - case v: java.lang.Double => DoubleValueNode(v) - case n => NumberValueNode(n) + case v: java.lang.Long => LongValueNode(v) + case v: java.lang.Float => FloatValueNode(v) + case v: java.lang.Double => DoubleValueNode(v) + case n => NumberValueNode(n) } else BooleanValueNode(iterator.boolean()) } @@ -139,8 +142,10 @@ object TokenNode { } } - implicit class TokenListOps(private val tokens: Seq[TokenNode]) extends AnyVal { + implicit class TokenListOps(private val tokens: Seq[TokenNode]) + extends AnyVal { import tethys.TokenIteratorOps - def tokensAs[A: JsonReader]: A = QueueIterator(tokens).readJson[A].fold(throw _, identity) + def tokensAs[A: JsonReader]: A = + QueueIterator(tokens).readJson[A].fold(throw _, identity) } } diff --git a/modules/core/src/main/scala/tethys/package.scala b/modules/core/src/main/scala/tethys/package.scala index 86084882..ca0f45e1 100644 --- a/modules/core/src/main/scala/tethys/package.scala +++ b/modules/core/src/main/scala/tethys/package.scala @@ -8,59 +8,86 @@ import scala.Specializable.Group package object tethys { - final val specializations = new Group((Byte, Short, Int, Long, Float, Double, Boolean)) + final val specializations = new Group( + (Byte, Short, Int, Long, Float, Double, Boolean) + ) // given implicit class JsonWriterOps[A](val a: A) extends AnyVal { - def asJson(implicit jsonWriter: JsonWriter[A], tokenWriterProducer: TokenWriterProducer): String = { + def asJson(implicit + jsonWriter: JsonWriter[A], + tokenWriterProducer: TokenWriterProducer + ): String = { val stringWriter = new StringWriter() writeJson(tokenWriterProducer.forWriter(stringWriter)) stringWriter.toString } - def asJsonWith(jsonWriter: JsonWriter[A])(implicit tokenWriterProducer: TokenWriterProducer): String = { + def asJsonWith( + jsonWriter: JsonWriter[A] + )(implicit tokenWriterProducer: TokenWriterProducer): String = { asJson(jsonWriter, tokenWriterProducer) } - def writeJson(tokenWriter: TokenWriter)(implicit jsonWriter: JsonWriter[A]): Unit = { - try jsonWriter.write(a, tokenWriter) finally { + def writeJson( + tokenWriter: TokenWriter + )(implicit jsonWriter: JsonWriter[A]): Unit = { + try jsonWriter.write(a, tokenWriter) + finally { tokenWriter.flush() } } } implicit class WriterOps(val w: Writer) extends AnyVal { - def toTokenWriter(implicit tokenWriterProducer: TokenWriterProducer): TokenWriter = tokenWriterProducer.forWriter(w) + def toTokenWriter(implicit + tokenWriterProducer: TokenWriterProducer + ): TokenWriter = tokenWriterProducer.forWriter(w) } implicit class StringReaderOps(val json: String) extends AnyVal { - def jsonAs[A](implicit jsonReader: JsonReader[A], producer: TokenIteratorProducer): Either[ReaderError, A] = { + def jsonAs[A](implicit + jsonReader: JsonReader[A], + producer: TokenIteratorProducer + ): Either[ReaderError, A] = { new StringReader(json).readJson[A] } - def toTokenIterator(implicit producer: TokenIteratorProducer): Either[ReaderError, TokenIterator] = { + def toTokenIterator(implicit + producer: TokenIteratorProducer + ): Either[ReaderError, TokenIterator] = { new StringReader(json).toTokenIterator } } implicit class ReaderReaderOps(val reader: Reader) extends AnyVal { - def readJson[A](implicit jsonReader: JsonReader[A], producer: TokenIteratorProducer): Either[ReaderError, A] = { + def readJson[A](implicit + jsonReader: JsonReader[A], + producer: TokenIteratorProducer + ): Either[ReaderError, A] = { implicit val root: FieldName = FieldName() producer.fromReader(reader).right.flatMap(_.readJson[A]) } - def readJsonWith[A](jsonReader: JsonReader[A])(implicit producer: TokenIteratorProducer): Either[ReaderError, A] = { + def readJsonWith[A]( + jsonReader: JsonReader[A] + )(implicit producer: TokenIteratorProducer): Either[ReaderError, A] = { readJson[A](jsonReader, producer) } - def toTokenIterator(implicit producer: TokenIteratorProducer): Either[ReaderError, TokenIterator] = { + def toTokenIterator(implicit + producer: TokenIteratorProducer + ): Either[ReaderError, TokenIterator] = { producer.fromReader(reader) } } - implicit class TokenIteratorOps(val tokenIterator: TokenIterator) extends AnyVal { - def readJson[A](implicit jsonReader: JsonReader[A]): Either[ReaderError, A] = { + implicit class TokenIteratorOps(val tokenIterator: TokenIterator) + extends AnyVal { + def readJson[A](implicit + jsonReader: JsonReader[A] + ): Either[ReaderError, A] = { implicit val fieldName: FieldName = FieldName() ReaderError.catchNonFatal(jsonReader.read(tokenIterator)) } diff --git a/modules/core/src/main/scala/tethys/readers/JsonReaderBuilder.scala b/modules/core/src/main/scala/tethys/readers/JsonReaderBuilder.scala index 83af97ef..beb94421 100644 --- a/modules/core/src/main/scala/tethys/readers/JsonReaderBuilder.scala +++ b/modules/core/src/main/scala/tethys/readers/JsonReaderBuilder.scala @@ -4,33 +4,71 @@ import tethys.JsonReader import tethys.readers.instances.{SelectingJsonReader, SimpleJsonReader} object JsonReaderBuilder { - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder1[B] = { - new JsonReaderBuilder1[B](0, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder1[B] = { + new JsonReaderBuilder1[B]( + 0, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder1[B] = { - new JsonReaderBuilder1[B](0, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder1[B] = { + new JsonReaderBuilder1[B]( + 0, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } trait SingleJsonValueReader[A1] { - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit private[JsonReaderBuilder] def value(extracted: Array[Any]): A1 } - final class JsonReaderBuilder1[A1] private[JsonReaderBuilder](pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A1]) extends SingleJsonValueReader[A1] { - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { - arr(pos) = SimpleJsonReader.FieldDefinition[A1](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): A1 = extracted(pos).asInstanceOf[A1] - - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder2[A1, B] = { + final class JsonReaderBuilder1[A1] private[JsonReaderBuilder] ( + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A1] + ) extends SingleJsonValueReader[A1] { + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { + arr(pos) = + SimpleJsonReader.FieldDefinition[A1](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value(extracted: Array[Any]): A1 = extracted( + pos + ).asInstanceOf[A1] + + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder2[A1, B] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder2[A1, B] = { - new JsonReaderBuilder2[A1, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder2[A1, B] = { + new JsonReaderBuilder2[A1, B]( + this, + pos + 1, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } def buildReader[Res](fun: A1 => Res): JsonReader[Res] = { @@ -41,7 +79,10 @@ object JsonReaderBuilder { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: A1 => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: A1 => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) new SimpleJsonReader[Res](fieldsArray, arr => fun(value(arr)), strict) @@ -50,26 +91,48 @@ object JsonReaderBuilder { def selectReader[Res](fun: A1 => JsonReader[_ <: Res]): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[A1](fieldsArray, arr => value(arr), strict = false) + val simpleJsonReader = + new SimpleJsonReader[A1](fieldsArray, arr => value(arr), strict = false) new SelectingJsonReader[A1, Res](simpleJsonReader)(fun) } } - final class JsonReaderBuilder2[A1, A2] private[JsonReaderBuilder](prev: SingleJsonValueReader[A1], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A2]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder2[A1, A2] private[JsonReaderBuilder] ( + prev: SingleJsonValueReader[A1], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A2] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A2](name, defaultValue, jsonReader) + arr(pos) = + SimpleJsonReader.FieldDefinition[A2](name, defaultValue, jsonReader) } - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2) = (prev.value(extracted), extracted(pos).asInstanceOf[A2]) + private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2) = + (prev.value(extracted), extracted(pos).asInstanceOf[A2]) - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder3[A1, A2, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder3[A1, A2, B] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder3[A1, A2, B] = { - new JsonReaderBuilder3[A1, A2, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder3[A1, A2, B] = { + new JsonReaderBuilder3[A1, A2, B]( + this, + pos + 1, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } def buildReader[Res](fun: (A1, A2) => Res): JsonReader[Res] = { @@ -80,37 +143,71 @@ object JsonReaderBuilder { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: (A1, A2) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) } - def selectReader[Res](fun: ((A1, A2)) => JsonReader[_ <: Res]): JsonReader[Res] = { + def selectReader[Res]( + fun: ((A1, A2)) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2)](fieldsArray, arr => value(arr), strict = false) + val simpleJsonReader = new SimpleJsonReader[(A1, A2)]( + fieldsArray, + arr => value(arr), + strict = false + ) new SelectingJsonReader[(A1, A2), Res](simpleJsonReader)(fun) } } - final class JsonReaderBuilder3[A1, A2, A3] private[JsonReaderBuilder](prev: JsonReaderBuilder2[A1, A2], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A3]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder3[A1, A2, A3] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder2[A1, A2], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A3] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A3](name, defaultValue, jsonReader) + arr(pos) = + SimpleJsonReader.FieldDefinition[A3](name, defaultValue, jsonReader) } - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3) = prev.value(extracted) match { - case (a1, a2) => (a1, a2, extracted(pos).asInstanceOf[A3]) - } + private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3) = + prev.value(extracted) match { + case (a1, a2) => (a1, a2, extracted(pos).asInstanceOf[A3]) + } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder4[A1, A2, A3, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder4[A1, A2, A3, B] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder4[A1, A2, A3, B] = { - new JsonReaderBuilder4[A1, A2, A3, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder4[A1, A2, A3, B] = { + new JsonReaderBuilder4[A1, A2, A3, B]( + this, + pos + 1, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } def buildReader[Res](fun: (A1, A2, A3) => Res): JsonReader[Res] = { @@ -121,806 +218,4068 @@ object JsonReaderBuilder { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: (A1, A2, A3) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) } - def selectReader[Res](fun: ((A1, A2, A3)) => JsonReader[_ <: Res]): JsonReader[Res] = { + def selectReader[Res]( + fun: ((A1, A2, A3)) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3)](fieldsArray, arr => value(arr), strict = false) + val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3)]( + fieldsArray, + arr => value(arr), + strict = false + ) new SelectingJsonReader[(A1, A2, A3), Res](simpleJsonReader)(fun) } } - final class JsonReaderBuilder4[A1, A2, A3, A4] private[JsonReaderBuilder](prev: JsonReaderBuilder3[A1, A2, A3], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A4]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder4[A1, A2, A3, A4] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder3[A1, A2, A3], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A4] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A4](name, defaultValue, jsonReader) + arr(pos) = + SimpleJsonReader.FieldDefinition[A4](name, defaultValue, jsonReader) } - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4) = prev.value(extracted) match { + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4) = prev.value(extracted) match { case (a1, a2, a3) => (a1, a2, a3, extracted(pos).asInstanceOf[A4]) } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder5[A1, A2, A3, A4, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder5[A1, A2, A3, A4, B] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder5[A1, A2, A3, A4, B] = { - new JsonReaderBuilder5[A1, A2, A3, A4, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder5[A1, A2, A3, A4, B] = { + new JsonReaderBuilder5[A1, A2, A3, A4, B]( + this, + pos + 1, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } def buildReader[Res](fun: (A1, A2, A3, A4) => Res): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: (A1, A2, A3, A4) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: (A1, A2, A3, A4) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) } - def selectReader[Res](fun: ((A1, A2, A3, A4)) => JsonReader[_ <: Res]): JsonReader[Res] = { + def selectReader[Res]( + fun: ((A1, A2, A3, A4)) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4)](fieldsArray, arr => value(arr), strict = false) + val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4)]( + fieldsArray, + arr => value(arr), + strict = false + ) new SelectingJsonReader[(A1, A2, A3, A4), Res](simpleJsonReader)(fun) } } - final class JsonReaderBuilder5[A1, A2, A3, A4, A5] private[JsonReaderBuilder](prev: JsonReaderBuilder4[A1, A2, A3, A4], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A5]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder5[ + A1, + A2, + A3, + A4, + A5 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder4[A1, A2, A3, A4], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A5] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A5](name, defaultValue, jsonReader) + arr(pos) = + SimpleJsonReader.FieldDefinition[A5](name, defaultValue, jsonReader) } - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5) = prev.value(extracted) match { + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4, A5) = prev.value(extracted) match { case (a1, a2, a3, a4) => (a1, a2, a3, a4, extracted(pos).asInstanceOf[A5]) } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder6[A1, A2, A3, A4, A5, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder6[A1, A2, A3, A4, A5, B] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder6[A1, A2, A3, A4, A5, B] = { - new JsonReaderBuilder6[A1, A2, A3, A4, A5, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder6[A1, A2, A3, A4, A5, B] = { + new JsonReaderBuilder6[A1, A2, A3, A4, A5, B]( + this, + pos + 1, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } def buildReader[Res](fun: (A1, A2, A3, A4, A5) => Res): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: (A1, A2, A3, A4, A5) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: (A1, A2, A3, A4, A5) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) } - def selectReader[Res](fun: ((A1, A2, A3, A4, A5)) => JsonReader[_ <: Res]): JsonReader[Res] = { + def selectReader[Res]( + fun: ((A1, A2, A3, A4, A5)) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5)](fieldsArray, arr => value(arr), strict = false) + val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5)]( + fieldsArray, + arr => value(arr), + strict = false + ) new SelectingJsonReader[(A1, A2, A3, A4, A5), Res](simpleJsonReader)(fun) } } - final class JsonReaderBuilder6[A1, A2, A3, A4, A5, A6] private[JsonReaderBuilder](prev: JsonReaderBuilder5[A1, A2, A3, A4, A5], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A6]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder6[ + A1, + A2, + A3, + A4, + A5, + A6 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder5[A1, A2, A3, A4, A5], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A6] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A6](name, defaultValue, jsonReader) + arr(pos) = + SimpleJsonReader.FieldDefinition[A6](name, defaultValue, jsonReader) } - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5) => (a1, a2, a3, a4, a5, extracted(pos).asInstanceOf[A6]) + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4, A5, A6) = prev.value(extracted) match { + case (a1, a2, a3, a4, a5) => + (a1, a2, a3, a4, a5, extracted(pos).asInstanceOf[A6]) } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder7[A1, A2, A3, A4, A5, A6, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder7[A1, A2, A3, A4, A5, A6, B] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder7[A1, A2, A3, A4, A5, A6, B] = { - new JsonReaderBuilder7[A1, A2, A3, A4, A5, A6, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder7[A1, A2, A3, A4, A5, A6, B] = { + new JsonReaderBuilder7[A1, A2, A3, A4, A5, A6, B]( + this, + pos + 1, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6) => Res): JsonReader[Res] = { + def buildReader[Res]( + fun: (A1, A2, A3, A4, A5, A6) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: (A1, A2, A3, A4, A5, A6) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: (A1, A2, A3, A4, A5, A6) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) } - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6)) => JsonReader[_ <: Res]): JsonReader[Res] = { + def selectReader[Res]( + fun: ((A1, A2, A3, A4, A5, A6)) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6)]( + fieldsArray, + arr => value(arr), + strict = false + ) + new SelectingJsonReader[(A1, A2, A3, A4, A5, A6), Res](simpleJsonReader)( + fun + ) } } - final class JsonReaderBuilder7[A1, A2, A3, A4, A5, A6, A7] private[JsonReaderBuilder](prev: JsonReaderBuilder6[A1, A2, A3, A4, A5, A6], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A7]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder7[ + A1, + A2, + A3, + A4, + A5, + A6, + A7 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder6[A1, A2, A3, A4, A5, A6], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A7] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A7](name, defaultValue, jsonReader) + arr(pos) = + SimpleJsonReader.FieldDefinition[A7](name, defaultValue, jsonReader) } - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6) => (a1, a2, a3, a4, a5, a6, extracted(pos).asInstanceOf[A7]) + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4, A5, A6, A7) = prev.value(extracted) match { + case (a1, a2, a3, a4, a5, a6) => + (a1, a2, a3, a4, a5, a6, extracted(pos).asInstanceOf[A7]) } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder8[A1, A2, A3, A4, A5, A6, A7, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder8[A1, A2, A3, A4, A5, A6, A7, B] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder8[A1, A2, A3, A4, A5, A6, A7, B] = { - new JsonReaderBuilder8[A1, A2, A3, A4, A5, A6, A7, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder8[A1, A2, A3, A4, A5, A6, A7, B] = { + new JsonReaderBuilder8[A1, A2, A3, A4, A5, A6, A7, B]( + this, + pos + 1, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7) => Res): JsonReader[Res] = { + def buildReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: (A1, A2, A3, A4, A5, A6, A7) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) } - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7)) => JsonReader[_ <: Res]): JsonReader[Res] = { + def selectReader[Res]( + fun: ((A1, A2, A3, A4, A5, A6, A7)) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7)]( + fieldsArray, + arr => value(arr), + strict = false + ) + new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7), Res]( + simpleJsonReader + )(fun) } } - final class JsonReaderBuilder8[A1, A2, A3, A4, A5, A6, A7, A8] private[JsonReaderBuilder](prev: JsonReaderBuilder7[A1, A2, A3, A4, A5, A6, A7], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A8]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder8[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder7[A1, A2, A3, A4, A5, A6, A7], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A8] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A8](name, defaultValue, jsonReader) + arr(pos) = + SimpleJsonReader.FieldDefinition[A8](name, defaultValue, jsonReader) } - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7) => (a1, a2, a3, a4, a5, a6, a7, extracted(pos).asInstanceOf[A8]) + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4, A5, A6, A7, A8) = prev.value(extracted) match { + case (a1, a2, a3, a4, a5, a6, a7) => + (a1, a2, a3, a4, a5, a6, a7, extracted(pos).asInstanceOf[A8]) } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder9[A1, A2, A3, A4, A5, A6, A7, A8, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder9[A1, A2, A3, A4, A5, A6, A7, A8, B] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder9[A1, A2, A3, A4, A5, A6, A7, A8, B] = { - new JsonReaderBuilder9[A1, A2, A3, A4, A5, A6, A7, A8, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder9[A1, A2, A3, A4, A5, A6, A7, A8, B] = { + new JsonReaderBuilder9[A1, A2, A3, A4, A5, A6, A7, A8, B]( + this, + pos + 1, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8) => Res): JsonReader[Res] = { + def buildReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7, A8) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7, A8) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: (A1, A2, A3, A4, A5, A6, A7, A8) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) } - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8)) => JsonReader[_ <: Res]): JsonReader[Res] = { + def selectReader[Res]( + fun: ((A1, A2, A3, A4, A5, A6, A7, A8)) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8), Res](simpleJsonReader)(fun) + val simpleJsonReader = + new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8)]( + fieldsArray, + arr => value(arr), + strict = false + ) + new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8), Res]( + simpleJsonReader + )(fun) } } - final class JsonReaderBuilder9[A1, A2, A3, A4, A5, A6, A7, A8, A9] private[JsonReaderBuilder](prev: JsonReaderBuilder8[A1, A2, A3, A4, A5, A6, A7, A8], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A9]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder9[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder8[A1, A2, A3, A4, A5, A6, A7, A8], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A9] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A9](name, defaultValue, jsonReader) + arr(pos) = + SimpleJsonReader.FieldDefinition[A9](name, defaultValue, jsonReader) } - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8) => (a1, a2, a3, a4, a5, a6, a7, a8, extracted(pos).asInstanceOf[A9]) + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4, A5, A6, A7, A8, A9) = prev.value(extracted) match { + case (a1, a2, a3, a4, a5, a6, a7, a8) => + (a1, a2, a3, a4, a5, a6, a7, a8, extracted(pos).asInstanceOf[A9]) } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder10[A1, A2, A3, A4, A5, A6, A7, A8, A9, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder10[A1, A2, A3, A4, A5, A6, A7, A8, A9, B] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder10[A1, A2, A3, A4, A5, A6, A7, A8, A9, B] = { - new JsonReaderBuilder10[A1, A2, A3, A4, A5, A6, A7, A8, A9, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder10[A1, A2, A3, A4, A5, A6, A7, A8, A9, B] = { + new JsonReaderBuilder10[A1, A2, A3, A4, A5, A6, A7, A8, A9, B]( + this, + pos + 1, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9) => Res): JsonReader[Res] = { + def buildReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) } - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9)) => JsonReader[_ <: Res]): JsonReader[Res] = { + def selectReader[Res]( + fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9)) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9), Res](simpleJsonReader)(fun) + val simpleJsonReader = + new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9)]( + fieldsArray, + arr => value(arr), + strict = false + ) + new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9), Res]( + simpleJsonReader + )(fun) } } - final class JsonReaderBuilder10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10] private[JsonReaderBuilder](prev: JsonReaderBuilder9[A1, A2, A3, A4, A5, A6, A7, A8, A9], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A10]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder10[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder9[A1, A2, A3, A4, A5, A6, A7, A8, A9], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A10] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A10](name, defaultValue, jsonReader) + arr(pos) = + SimpleJsonReader.FieldDefinition[A10](name, defaultValue, jsonReader) } - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, extracted(pos).asInstanceOf[A10]) + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) = prev.value(extracted) match { + case (a1, a2, a3, a4, a5, a6, a7, a8, a9) => + (a1, a2, a3, a4, a5, a6, a7, a8, a9, extracted(pos).asInstanceOf[A10]) } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, B] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, B] = { - new JsonReaderBuilder11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, B] = { + new JsonReaderBuilder11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, B]( + this, + pos + 1, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) => Res): JsonReader[Res] = { + def buildReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) } - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) => JsonReader[_ <: Res]): JsonReader[Res] = { + def selectReader[Res]( + fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), Res](simpleJsonReader)(fun) + val simpleJsonReader = + new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)]( + fieldsArray, + arr => value(arr), + strict = false + ) + new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), Res]( + simpleJsonReader + )(fun) } } - final class JsonReaderBuilder11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11] private[JsonReaderBuilder](prev: JsonReaderBuilder10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A11]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder11[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A11] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A11](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, extracted(pos).asInstanceOf[A11]) - } + arr(pos) = + SimpleJsonReader.FieldDefinition[A11](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) = + prev.value(extracted) match { + case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) => + ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + extracted(pos).asInstanceOf[A11] + ) + } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, B] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, B] = { - new JsonReaderBuilder12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, B] = { + new JsonReaderBuilder12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, B]( + this, + pos + 1, + name, + readerDefaultValue.defaultValue, + jsonReader + ) } - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) => Res): JsonReader[Res] = { + def buildReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) - } - - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)) => JsonReader[_ <: Res]): JsonReader[Res] = { + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) + } + + def selectReader[Res]( + fun: ( + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) + ) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11), Res](simpleJsonReader)(fun) + val simpleJsonReader = + new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)]( + fieldsArray, + arr => value(arr), + strict = false + ) + new SelectingJsonReader[ + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11), + Res + ](simpleJsonReader)(fun) } } - final class JsonReaderBuilder12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12] private[JsonReaderBuilder](prev: JsonReaderBuilder11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A12]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder12[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A12] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A12](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, extracted(pos).asInstanceOf[A12]) - } + arr(pos) = + SimpleJsonReader.FieldDefinition[A12](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) = + prev.value(extracted) match { + case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) => + ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + extracted(pos).asInstanceOf[A12] + ) + } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder13[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder13[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + B + ] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder13[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, B] = { - new JsonReaderBuilder13[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) - } - - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) => Res): JsonReader[Res] = { + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder13[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + B + ] = { + new JsonReaderBuilder13[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + B + ](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + } + + def buildReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) - } - - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)) => JsonReader[_ <: Res]): JsonReader[Res] = { + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) + } + + def selectReader[Res]( + fun: ( + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) + ) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[ + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) + ](fieldsArray, arr => value(arr), strict = false) + new SelectingJsonReader[ + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12), + Res + ](simpleJsonReader)(fun) } } - final class JsonReaderBuilder13[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13] private[JsonReaderBuilder](prev: JsonReaderBuilder12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A13]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder13[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder12[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12 + ], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A13] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A13](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, extracted(pos).asInstanceOf[A13]) - } + arr(pos) = + SimpleJsonReader.FieldDefinition[A13](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) = + prev.value(extracted) match { + case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) => + ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + extracted(pos).asInstanceOf[A13] + ) + } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder14[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder14[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + B + ] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder14[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, B] = { - new JsonReaderBuilder14[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) - } - - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) => Res): JsonReader[Res] = { + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder14[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + B + ] = { + new JsonReaderBuilder14[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + B + ](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + } + + def buildReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) - } - - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)) => JsonReader[_ <: Res]): JsonReader[Res] = { + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) + } + + def selectReader[Res]( + fun: ( + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) + ) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[ + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) + ](fieldsArray, arr => value(arr), strict = false) + new SelectingJsonReader[ + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13), + Res + ](simpleJsonReader)(fun) } } - final class JsonReaderBuilder14[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14] private[JsonReaderBuilder](prev: JsonReaderBuilder13[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A14]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder14[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder13[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13 + ], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A14] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A14](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, extracted(pos).asInstanceOf[A14]) - } + arr(pos) = + SimpleJsonReader.FieldDefinition[A14](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) = + prev.value(extracted) match { + case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) => + ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + extracted(pos).asInstanceOf[A14] + ) + } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder15[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder15[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + B + ] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder15[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, B] = { - new JsonReaderBuilder15[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) - } - - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) => Res): JsonReader[Res] = { + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder15[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + B + ] = { + new JsonReaderBuilder15[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + B + ](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + } + + def buildReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14 + ) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14 + ) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14 + ) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) - } - - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)) => JsonReader[_ <: Res]): JsonReader[Res] = { + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) + } + + def selectReader[Res]( + fun: ( + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) + ) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[ + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) + ](fieldsArray, arr => value(arr), strict = false) + new SelectingJsonReader[ + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14), + Res + ](simpleJsonReader)(fun) } } - final class JsonReaderBuilder15[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15] private[JsonReaderBuilder](prev: JsonReaderBuilder14[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A15]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder15[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder14[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14 + ], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A15] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A15](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, extracted(pos).asInstanceOf[A15]) - } + arr(pos) = + SimpleJsonReader.FieldDefinition[A15](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) = + prev.value(extracted) match { + case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) => + ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + extracted(pos).asInstanceOf[A15] + ) + } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder16[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder16[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + B + ] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder16[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, B] = { - new JsonReaderBuilder16[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) - } - - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) => Res): JsonReader[Res] = { + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder16[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + B + ] = { + new JsonReaderBuilder16[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + B + ](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + } + + def buildReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15 + ) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15 + ) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15 + ) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) - } - - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15)) => JsonReader[_ <: Res]): JsonReader[Res] = { + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) + } + + def selectReader[Res]( + fun: ( + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) + ) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[ + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) + ](fieldsArray, arr => value(arr), strict = false) + new SelectingJsonReader[ + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15), + Res + ](simpleJsonReader)(fun) } } - final class JsonReaderBuilder16[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16] private[JsonReaderBuilder](prev: JsonReaderBuilder15[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A16]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder16[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder15[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15 + ], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A16] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A16](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, extracted(pos).asInstanceOf[A16]) - } + arr(pos) = + SimpleJsonReader.FieldDefinition[A16](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value( + extracted: Array[Any] + ): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16) = + prev.value(extracted) match { + case ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15 + ) => + ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + extracted(pos).asInstanceOf[A16] + ) + } - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder17[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, B] = { + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder17[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + B + ] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder17[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, B] = { - new JsonReaderBuilder17[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) - } - - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16) => Res): JsonReader[Res] = { + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder17[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + B + ] = { + new JsonReaderBuilder17[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + B + ](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + } + + def buildReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16 + ) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16 + ) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16 + ) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) - } - - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16)) => JsonReader[_ <: Res]): JsonReader[Res] = { + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) + } + + def selectReader[Res]( + fun: ( + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16 + ) + ) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[ + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16) + ](fieldsArray, arr => value(arr), strict = false) + new SelectingJsonReader[ + (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16), + Res + ](simpleJsonReader)(fun) } } - final class JsonReaderBuilder17[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17] private[JsonReaderBuilder](prev: JsonReaderBuilder16[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A17]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder17[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder16[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16 + ], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A17] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A17](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, extracted(pos).asInstanceOf[A17]) - } - - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder18[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, B] = { + arr(pos) = + SimpleJsonReader.FieldDefinition[A17](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value(extracted: Array[Any]): ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17 + ) = prev.value(extracted) match { + case ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16 + ) => + ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + extracted(pos).asInstanceOf[A17] + ) + } + + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder18[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + B + ] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder18[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, B] = { - new JsonReaderBuilder18[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) - } - - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17) => Res): JsonReader[Res] = { + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder18[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + B + ] = { + new JsonReaderBuilder18[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + B + ](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + } + + def buildReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17 + ) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17 + ) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17 + ) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) - } - - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17)) => JsonReader[_ <: Res]): JsonReader[Res] = { + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) + } + + def selectReader[Res]( + fun: ( + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17 + ) + ) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17 + ) + ](fieldsArray, arr => value(arr), strict = false) + new SelectingJsonReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17 + ), + Res + ](simpleJsonReader)(fun) } } - final class JsonReaderBuilder18[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18] private[JsonReaderBuilder](prev: JsonReaderBuilder17[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A18]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder18[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder17[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17 + ], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A18] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A18](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, extracted(pos).asInstanceOf[A18]) - } - - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder19[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, B] = { + arr(pos) = + SimpleJsonReader.FieldDefinition[A18](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value(extracted: Array[Any]): ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18 + ) = prev.value(extracted) match { + case ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17 + ) => + ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + extracted(pos).asInstanceOf[A18] + ) + } + + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder19[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + B + ] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder19[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, B] = { - new JsonReaderBuilder19[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) - } - - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18) => Res): JsonReader[Res] = { + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder19[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + B + ] = { + new JsonReaderBuilder19[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + B + ](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + } + + def buildReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18 + ) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18 + ) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18 + ) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) - } - - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18)) => JsonReader[_ <: Res]): JsonReader[Res] = { + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) + } + + def selectReader[Res]( + fun: ( + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18 + ) + ) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18 + ) + ](fieldsArray, arr => value(arr), strict = false) + new SelectingJsonReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18 + ), + Res + ](simpleJsonReader)(fun) } } - final class JsonReaderBuilder19[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19] private[JsonReaderBuilder](prev: JsonReaderBuilder18[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A19]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder19[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder18[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18 + ], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A19] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A19](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, extracted(pos).asInstanceOf[A19]) - } - - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder20[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, B] = { + arr(pos) = + SimpleJsonReader.FieldDefinition[A19](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value(extracted: Array[Any]): ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19 + ) = prev.value(extracted) match { + case ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + a18 + ) => + ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + a18, + extracted(pos).asInstanceOf[A19] + ) + } + + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder20[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + B + ] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder20[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, B] = { - new JsonReaderBuilder20[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) - } - - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19) => Res): JsonReader[Res] = { + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder20[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + B + ] = { + new JsonReaderBuilder20[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + B + ](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + } + + def buildReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19 + ) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19 + ) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19 + ) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) - } - - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19)) => JsonReader[_ <: Res]): JsonReader[Res] = { + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) + } + + def selectReader[Res]( + fun: ( + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19 + ) + ) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19 + ) + ](fieldsArray, arr => value(arr), strict = false) + new SelectingJsonReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19 + ), + Res + ](simpleJsonReader)(fun) } } - final class JsonReaderBuilder20[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20] private[JsonReaderBuilder](prev: JsonReaderBuilder19[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A20]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder20[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder19[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19 + ], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A20] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A20](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, extracted(pos).asInstanceOf[A20]) - } - - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder21[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, B] = { + arr(pos) = + SimpleJsonReader.FieldDefinition[A20](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value(extracted: Array[Any]): ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20 + ) = prev.value(extracted) match { + case ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + a18, + a19 + ) => + ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + a18, + a19, + extracted(pos).asInstanceOf[A20] + ) + } + + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder21[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + B + ] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder21[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, B] = { - new JsonReaderBuilder21[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) - } - - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20) => Res): JsonReader[Res] = { + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder21[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + B + ] = { + new JsonReaderBuilder21[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + B + ](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + } + + def buildReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20 + ) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20 + ) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20 + ) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) - } - - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20)) => JsonReader[_ <: Res]): JsonReader[Res] = { + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) + } + + def selectReader[Res]( + fun: ( + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20 + ) + ) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20 + ) + ](fieldsArray, arr => value(arr), strict = false) + new SelectingJsonReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20 + ), + Res + ](simpleJsonReader)(fun) } } - final class JsonReaderBuilder21[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21] private[JsonReaderBuilder](prev: JsonReaderBuilder20[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A21]) { - - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + final class JsonReaderBuilder21[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder20[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20 + ], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A21] + ) { + + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A21](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, extracted(pos).asInstanceOf[A21]) - } - - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder22[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, B] = { + arr(pos) = + SimpleJsonReader.FieldDefinition[A21](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value(extracted: Array[Any]): ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21 + ) = prev.value(extracted) match { + case ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + a18, + a19, + a20 + ) => + ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + a18, + a19, + a20, + extracted(pos).asInstanceOf[A21] + ) + } + + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder22[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + B + ] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder22[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, B] = { - new JsonReaderBuilder22[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, B](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) - } - - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21) => Res): JsonReader[Res] = { + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder22[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + B + ] = { + new JsonReaderBuilder22[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + B + ](this, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) + } + + def buildReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21 + ) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21 + ) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21 + ) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) - } - - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21)) => JsonReader[_ <: Res]): JsonReader[Res] = { + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) + } + + def selectReader[Res]( + fun: ( + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21 + ) + ) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21 + ) + ](fieldsArray, arr => value(arr), strict = false) + new SelectingJsonReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21 + ), + Res + ](simpleJsonReader)(fun) } } - final class JsonReaderBuilder22[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22] private[JsonReaderBuilder](prev: JsonReaderBuilder21[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21], pos: Int, name: String, defaultValue: Any, jsonReader: JsonReader[A22]) { + final class JsonReaderBuilder22[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ] private[JsonReaderBuilder] ( + prev: JsonReaderBuilder21[ + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21 + ], + pos: Int, + name: String, + defaultValue: Any, + jsonReader: JsonReader[A22] + ) { self => - private[JsonReaderBuilder] def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = { + private[JsonReaderBuilder] def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = { prev.fields(arr) - arr(pos) = SimpleJsonReader.FieldDefinition[A22](name, defaultValue, jsonReader) - } - - private[JsonReaderBuilder] def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22) = prev.value(extracted) match { - case (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21) => (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, extracted(pos).asInstanceOf[A22]) - } - - def addField[B](name: String, jsonReader: JsonReader[B])(implicit readerDefaultValue: JsonReaderDefaultValue[B]): JsonReaderBuilder2[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22), B] = { + arr(pos) = + SimpleJsonReader.FieldDefinition[A22](name, defaultValue, jsonReader) + } + + private[JsonReaderBuilder] def value(extracted: Array[Any]): ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ) = prev.value(extracted) match { + case ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + a18, + a19, + a20, + a21 + ) => + ( + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + a18, + a19, + a20, + a21, + extracted(pos).asInstanceOf[A22] + ) + } + + def addField[B](name: String, jsonReader: JsonReader[B])(implicit + readerDefaultValue: JsonReaderDefaultValue[B] + ): JsonReaderBuilder2[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ), + B + ] = { addField[B](name)(readerDefaultValue, jsonReader) } - def addField[B](name: String)(implicit readerDefaultValue: JsonReaderDefaultValue[B], jsonReader: JsonReader[B]): JsonReaderBuilder2[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22), B] = { - val singleJsonValueReader: SingleJsonValueReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22)] = { - new SingleJsonValueReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22)] { - private[JsonReaderBuilder] override def fields(arr: Array[SimpleJsonReader.FieldDefinition[_]]): Unit = self.fields(arr) - - override def value(extracted: Array[Any]): (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22) = { + def addField[B](name: String)(implicit + readerDefaultValue: JsonReaderDefaultValue[B], + jsonReader: JsonReader[B] + ): JsonReaderBuilder2[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ), + B + ] = { + val singleJsonValueReader: SingleJsonValueReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ) + ] = { + new SingleJsonValueReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ) + ] { + private[JsonReaderBuilder] override def fields( + arr: Array[SimpleJsonReader.FieldDefinition[_]] + ): Unit = self.fields(arr) + + override def value(extracted: Array[Any]): ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ) = { self.value(extracted) } } } - new JsonReaderBuilder2[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22), B](singleJsonValueReader, pos + 1, name, readerDefaultValue.defaultValue, jsonReader) - } - - def buildReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22) => Res): JsonReader[Res] = { + new JsonReaderBuilder2[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ), + B + ]( + singleJsonValueReader, + pos + 1, + name, + readerDefaultValue.defaultValue, + jsonReader + ) + } + + def buildReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ) => Res + ): JsonReader[Res] = { buildReader(strict = false, fun) } - def buildStrictReader[Res](fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22) => Res): JsonReader[Res] = { + def buildStrictReader[Res]( + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ) => Res + ): JsonReader[Res] = { buildReader(strict = true, fun) } - private def buildReader[Res](strict: Boolean, fun: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22) => Res): JsonReader[Res] = { + private def buildReader[Res]( + strict: Boolean, + fun: ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ) => Res + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - new SimpleJsonReader[Res](fieldsArray, arr => fun.tupled(value(arr)), strict) - } - - def selectReader[Res](fun: ((A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22)) => JsonReader[_ <: Res]): JsonReader[Res] = { + new SimpleJsonReader[Res]( + fieldsArray, + arr => fun.tupled(value(arr)), + strict + ) + } + + def selectReader[Res]( + fun: ( + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ) + ) => JsonReader[_ <: Res] + ): JsonReader[Res] = { val fieldsArray = new Array[SimpleJsonReader.FieldDefinition[_]](pos + 1) fields(fieldsArray) - val simpleJsonReader = new SimpleJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22)](fieldsArray, arr => value(arr), strict = false) - new SelectingJsonReader[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22), Res](simpleJsonReader)(fun) + val simpleJsonReader = new SimpleJsonReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ) + ](fieldsArray, arr => value(arr), strict = false) + new SelectingJsonReader[ + ( + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21, + A22 + ), + Res + ](simpleJsonReader)(fun) } } diff --git a/modules/core/src/main/scala/tethys/readers/JsonReaderDefaultValue.scala b/modules/core/src/main/scala/tethys/readers/JsonReaderDefaultValue.scala index 3bf62de6..ca402394 100644 --- a/modules/core/src/main/scala/tethys/readers/JsonReaderDefaultValue.scala +++ b/modules/core/src/main/scala/tethys/readers/JsonReaderDefaultValue.scala @@ -9,17 +9,21 @@ trait JsonReaderDefaultValue[A] { } object JsonReaderDefaultValue extends LowPriorityDefaultValue { - def apply[A](implicit dv: JsonReaderDefaultValue[A]): JsonReaderDefaultValue[A] = dv + def apply[A](implicit + dv: JsonReaderDefaultValue[A] + ): JsonReaderDefaultValue[A] = dv - //Allows easy access of default value in macro + // Allows easy access of default value in macro class ReaderDefaultValue(value: Any) extends StaticAnnotation @ReaderDefaultValue(None) class OptionDefaultValue[A] extends JsonReaderDefaultValue[Option[A]] { override def defaultValue: Any = None } - private val optionInstance: OptionDefaultValue[Nothing] = new OptionDefaultValue[Nothing] - implicit def optionDefaultValue[A]: OptionDefaultValue[A] = optionInstance.asInstanceOf[OptionDefaultValue[A]] + private val optionInstance: OptionDefaultValue[Nothing] = + new OptionDefaultValue[Nothing] + implicit def optionDefaultValue[A]: OptionDefaultValue[A] = + optionInstance.asInstanceOf[OptionDefaultValue[A]] } trait LowPriorityDefaultValue { @@ -28,6 +32,8 @@ trait LowPriorityDefaultValue { override def defaultValue: Any = null } - private val noDefaultValueInstance: NoDefaultValue[Nothing] = new NoDefaultValue[Nothing] - implicit def noDefaultValue[A]: NoDefaultValue[A] = noDefaultValueInstance.asInstanceOf[NoDefaultValue[A]] + private val noDefaultValueInstance: NoDefaultValue[Nothing] = + new NoDefaultValue[Nothing] + implicit def noDefaultValue[A]: NoDefaultValue[A] = + noDefaultValueInstance.asInstanceOf[NoDefaultValue[A]] } diff --git a/modules/core/src/main/scala/tethys/readers/KeyReader.scala b/modules/core/src/main/scala/tethys/readers/KeyReader.scala index 49aed76f..bcd25dbd 100644 --- a/modules/core/src/main/scala/tethys/readers/KeyReader.scala +++ b/modules/core/src/main/scala/tethys/readers/KeyReader.scala @@ -9,9 +9,12 @@ object KeyReader { override def read(s: String)(implicit fieldName: FieldName): String = s } - implicit lazy val uuidKeyReader: KeyReader[java.util.UUID] = new KeyReader[java.util.UUID] { - override def read(s: String)(implicit fieldName: FieldName): java.util.UUID = java.util.UUID.fromString(s) - } + implicit lazy val uuidKeyReader: KeyReader[java.util.UUID] = + new KeyReader[java.util.UUID] { + override def read(s: String)(implicit + fieldName: FieldName + ): java.util.UUID = java.util.UUID.fromString(s) + } implicit lazy val intKeyReader: KeyReader[Int] = new KeyReader[Int] { override def read(s: String)(implicit fieldName: FieldName): Int = s.toInt @@ -21,27 +24,47 @@ object KeyReader { override def read(s: String)(implicit fieldName: FieldName): Long = s.toLong } - implicit lazy val instantKeyReader: KeyReader[java.time.Instant] = new KeyReader[java.time.Instant] { - override def read(s: String)(implicit fieldName: FieldName): java.time.Instant = java.time.Instant.parse(s) - } + implicit lazy val instantKeyReader: KeyReader[java.time.Instant] = + new KeyReader[java.time.Instant] { + override def read(s: String)(implicit + fieldName: FieldName + ): java.time.Instant = java.time.Instant.parse(s) + } - implicit lazy val localDateKeyReader: KeyReader[java.time.LocalDate] = new KeyReader[java.time.LocalDate] { - override def read(s: String)(implicit fieldName: FieldName): java.time.LocalDate = - java.time.LocalDate.parse(s, java.time.format.DateTimeFormatter.ISO_LOCAL_DATE) - } + implicit lazy val localDateKeyReader: KeyReader[java.time.LocalDate] = + new KeyReader[java.time.LocalDate] { + override def read( + s: String + )(implicit fieldName: FieldName): java.time.LocalDate = + java.time.LocalDate + .parse(s, java.time.format.DateTimeFormatter.ISO_LOCAL_DATE) + } - implicit lazy val localDateTimeKeyReader: KeyReader[java.time.LocalDateTime] = new KeyReader[java.time.LocalDateTime] { - override def read(s: String)(implicit fieldName: FieldName): java.time.LocalDateTime = - java.time.LocalDateTime.parse(s, java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME) - } + implicit lazy val localDateTimeKeyReader: KeyReader[java.time.LocalDateTime] = + new KeyReader[java.time.LocalDateTime] { + override def read( + s: String + )(implicit fieldName: FieldName): java.time.LocalDateTime = + java.time.LocalDateTime + .parse(s, java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME) + } - implicit lazy val offsetDateTimeKeyReader: KeyReader[java.time.OffsetDateTime] = new KeyReader[java.time.OffsetDateTime] { - override def read(s: String)(implicit fieldName: FieldName): java.time.OffsetDateTime = - java.time.OffsetDateTime.parse(s, java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME) - } + implicit lazy val offsetDateTimeKeyReader + : KeyReader[java.time.OffsetDateTime] = + new KeyReader[java.time.OffsetDateTime] { + override def read( + s: String + )(implicit fieldName: FieldName): java.time.OffsetDateTime = + java.time.OffsetDateTime + .parse(s, java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME) + } - implicit lazy val zonedDateTimeKeyReader: KeyReader[java.time.ZonedDateTime] = new KeyReader[java.time.ZonedDateTime] { - override def read(s: String)(implicit fieldName: FieldName): java.time.ZonedDateTime = - java.time.ZonedDateTime.parse(s, java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME) - } + implicit lazy val zonedDateTimeKeyReader: KeyReader[java.time.ZonedDateTime] = + new KeyReader[java.time.ZonedDateTime] { + override def read( + s: String + )(implicit fieldName: FieldName): java.time.ZonedDateTime = + java.time.ZonedDateTime + .parse(s, java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME) + } } diff --git a/modules/core/src/main/scala/tethys/readers/ReaderError.scala b/modules/core/src/main/scala/tethys/readers/ReaderError.scala index beeb7901..bac4dce2 100644 --- a/modules/core/src/main/scala/tethys/readers/ReaderError.scala +++ b/modules/core/src/main/scala/tethys/readers/ReaderError.scala @@ -2,10 +2,16 @@ package tethys.readers import scala.util.control.NonFatal -final class ReaderError protected(message: String, cause: Throwable, field: String) extends Exception(message, cause) +final class ReaderError protected ( + message: String, + cause: Throwable, + field: String +) extends Exception(message, cause) object ReaderError { - def wrongJson(reason: String, cause: Throwable = null)(implicit fieldName: FieldName): Nothing = { + def wrongJson(reason: String, cause: Throwable = null)(implicit + fieldName: FieldName + ): Nothing = { val field = fieldName.value() throw new ReaderError( message = s"Illegal json at '$field': $reason", @@ -14,14 +20,20 @@ object ReaderError { ) } - def catchNonFatal[A](fun: => A)(implicit fieldName: FieldName): Either[ReaderError, A] = { - try Right(fun) catch { + def catchNonFatal[A]( + fun: => A + )(implicit fieldName: FieldName): Either[ReaderError, A] = { + try Right(fun) + catch { case err: ReaderError => Left(err) - case NonFatal(e) => Left(new ReaderError( - message = e.getMessage, - cause = e, - field = fieldName.value()) - ) + case NonFatal(e) => + Left( + new ReaderError( + message = e.getMessage, + cause = e, + field = fieldName.value() + ) + ) } } -} \ No newline at end of file +} diff --git a/modules/core/src/main/scala/tethys/readers/instances/AllJsonReaders.scala b/modules/core/src/main/scala/tethys/readers/instances/AllJsonReaders.scala index 56dea3c6..8aa4944a 100644 --- a/modules/core/src/main/scala/tethys/readers/instances/AllJsonReaders.scala +++ b/modules/core/src/main/scala/tethys/readers/instances/AllJsonReaders.scala @@ -5,166 +5,229 @@ import tethys.readers.tokens.TokenIterator import tethys.readers.{FieldName, ReaderError} trait AllJsonReaders extends OptionReaders { - implicit lazy val booleanReader: JsonReader[Boolean] = new JsonReader[Boolean] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): Boolean = { - if(it.currentToken().isBooleanValue) { - val res = it.boolean() - it.next() - res - } else { - ReaderError.wrongJson(s"Expected boolean value but found: ${it.currentToken()}") + implicit lazy val booleanReader: JsonReader[Boolean] = + new JsonReader[Boolean] { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): Boolean = { + if (it.currentToken().isBooleanValue) { + val res = it.boolean() + it.next() + res + } else { + ReaderError.wrongJson( + s"Expected boolean value but found: ${it.currentToken()}" + ) + } } } - } implicit lazy val stringReader: JsonReader[String] = new JsonReader[String] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): String = { - if(it.currentToken().isStringValue) { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): String = { + if (it.currentToken().isStringValue) { val res = it.string() it.next() res } else { - ReaderError.wrongJson(s"Expected string value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected string value but found: ${it.currentToken()}" + ) } } } - implicit lazy val charReader: JsonReader[Char] = stringReader.mapWithField{ implicit fieldName => { - case s if s.length == 1 => s.head - case s => ReaderError.wrongJson(s"Expected char value but found: $s") - } + implicit lazy val charReader: JsonReader[Char] = stringReader.mapWithField { + implicit fieldName => + { + case s if s.length == 1 => s.head + case s => ReaderError.wrongJson(s"Expected char value but found: $s") + } } implicit lazy val numberReader: JsonReader[Number] = new JsonReader[Number] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): Number = { - if(it.currentToken().isNumberValue) { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): Number = { + if (it.currentToken().isNumberValue) { val res = it.number() it.next() res } else { - ReaderError.wrongJson(s"Expected number value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected number value but found: ${it.currentToken()}" + ) } } } implicit lazy val byteReader: JsonReader[Byte] = new JsonReader[Byte] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): Byte = { - if(it.currentToken().isNumberValue) { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): Byte = { + if (it.currentToken().isNumberValue) { val res = it.byte() it.next() res } else { - ReaderError.wrongJson(s"Expected byte value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected byte value but found: ${it.currentToken()}" + ) } } } implicit lazy val shortReader: JsonReader[Short] = new JsonReader[Short] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): Short = { - if(it.currentToken().isNumberValue) { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): Short = { + if (it.currentToken().isNumberValue) { val res = it.short() it.next() res } else { - ReaderError.wrongJson(s"Expected short value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected short value but found: ${it.currentToken()}" + ) } } } implicit lazy val intReader: JsonReader[Int] = new JsonReader[Int] { override def read(it: TokenIterator)(implicit fieldName: FieldName): Int = { - if(it.currentToken().isNumberValue) { + if (it.currentToken().isNumberValue) { val res = it.int() it.next() res } else { - ReaderError.wrongJson(s"Expected int value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected int value but found: ${it.currentToken()}" + ) } } } implicit lazy val longReader: JsonReader[Long] = new JsonReader[Long] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): Long = { - if(it.currentToken().isNumberValue) { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): Long = { + if (it.currentToken().isNumberValue) { val res = it.long() it.next() res } else { - ReaderError.wrongJson(s"Expected long value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected long value but found: ${it.currentToken()}" + ) } } } implicit lazy val floatReader: JsonReader[Float] = new JsonReader[Float] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): Float = { - if(it.currentToken().isNumberValue) { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): Float = { + if (it.currentToken().isNumberValue) { val res = it.float() it.next() res } else { - ReaderError.wrongJson(s"Expected float value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected float value but found: ${it.currentToken()}" + ) } } } implicit lazy val doubleReader: JsonReader[Double] = new JsonReader[Double] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): Double = { - if(it.currentToken().isNumberValue) { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): Double = { + if (it.currentToken().isNumberValue) { val res = it.double() it.next() res } else { - ReaderError.wrongJson(s"Expected double value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected double value but found: ${it.currentToken()}" + ) } } } - implicit lazy val bigDecimalReader: JsonReader[BigDecimal] = numberReader.map { - case bd: BigDecimal => bd - case bi: BigInt => BigDecimal(bi) - case jbd: java.math.BigDecimal => BigDecimal(jbd) - case jint: java.lang.Integer => BigDecimal(jint) - case jbyte: java.lang.Byte => BigDecimal(jbyte.longValue()) - case jshort: java.lang.Short => BigDecimal(jshort.longValue()) - case jlong: java.lang.Long => BigDecimal(jlong) - case jbi: java.math.BigInteger => BigDecimal(jbi) - case jfloat: java.lang.Float => BigDecimal(jfloat.toDouble) - case jdouble: java.lang.Double => BigDecimal(jdouble) - case num => BigDecimal(num.doubleValue()) - } + implicit lazy val bigDecimalReader: JsonReader[BigDecimal] = + numberReader.map { + case bd: BigDecimal => bd + case bi: BigInt => BigDecimal(bi) + case jbd: java.math.BigDecimal => BigDecimal(jbd) + case jint: java.lang.Integer => BigDecimal(jint) + case jbyte: java.lang.Byte => BigDecimal(jbyte.longValue()) + case jshort: java.lang.Short => BigDecimal(jshort.longValue()) + case jlong: java.lang.Long => BigDecimal(jlong) + case jbi: java.math.BigInteger => BigDecimal(jbi) + case jfloat: java.lang.Float => BigDecimal(jfloat.toDouble) + case jdouble: java.lang.Double => BigDecimal(jdouble) + case num => BigDecimal(num.doubleValue()) + } implicit lazy val bigIntReader: JsonReader[BigInt] = numberReader.map { - case bi: BigInt => bi + case bi: BigInt => bi case jbi: java.math.BigInteger => BigInt(jbi) - case bd: BigDecimal => bd.toBigInt + case bd: BigDecimal => bd.toBigInt case jbd: java.math.BigDecimal => jbd.toBigInteger - case jint: java.lang.Integer => BigInt(jint) - case jbyte: java.lang.Byte => BigInt(jbyte.longValue()) - case jshort: java.lang.Short => BigInt(jshort.longValue()) - case jlong: java.lang.Long => BigInt(jlong) - case num => BigInt(num.longValue()) + case jint: java.lang.Integer => BigInt(jint) + case jbyte: java.lang.Byte => BigInt(jbyte.longValue()) + case jshort: java.lang.Short => BigInt(jshort.longValue()) + case jlong: java.lang.Long => BigInt(jlong) + case num => BigInt(num.longValue()) } - - implicit lazy val javaBooleanReader: JsonReader[java.lang.Boolean] = booleanReader.map(a => a) - implicit lazy val javaByteReader: JsonReader[java.lang.Byte] = byteReader.map(a => a) - implicit lazy val javaShortReader: JsonReader[java.lang.Short] = shortReader.map(a => a) - implicit lazy val javaIntReader: JsonReader[java.lang.Integer] = intReader.map(a => a) - implicit lazy val javaLongReader: JsonReader[java.lang.Long] = longReader.map(a => a) - implicit lazy val javaFloatReader: JsonReader[java.lang.Float] = floatReader.map(a => a) - implicit lazy val javaDoubleReader: JsonReader[java.lang.Double] = doubleReader.map(a => a) - implicit lazy val javaBigDecimalReader: JsonReader[java.math.BigDecimal] = bigDecimalReader.map(_.bigDecimal) - implicit lazy val javaBigIntegerReader: JsonReader[java.math.BigInteger] = bigIntReader.map(_.bigInteger) - implicit lazy val javaUUIDReader: JsonReader[java.util.UUID] = stringReader.map(java.util.UUID.fromString(_)) - - implicit lazy val javaInstantReader: JsonReader[java.time.Instant] = stringReader.map(java.time.Instant.parse) + implicit lazy val javaBooleanReader: JsonReader[java.lang.Boolean] = + booleanReader.map(a => a) + implicit lazy val javaByteReader: JsonReader[java.lang.Byte] = + byteReader.map(a => a) + implicit lazy val javaShortReader: JsonReader[java.lang.Short] = + shortReader.map(a => a) + implicit lazy val javaIntReader: JsonReader[java.lang.Integer] = + intReader.map(a => a) + implicit lazy val javaLongReader: JsonReader[java.lang.Long] = + longReader.map(a => a) + implicit lazy val javaFloatReader: JsonReader[java.lang.Float] = + floatReader.map(a => a) + implicit lazy val javaDoubleReader: JsonReader[java.lang.Double] = + doubleReader.map(a => a) + implicit lazy val javaBigDecimalReader: JsonReader[java.math.BigDecimal] = + bigDecimalReader.map(_.bigDecimal) + implicit lazy val javaBigIntegerReader: JsonReader[java.math.BigInteger] = + bigIntReader.map(_.bigInteger) + implicit lazy val javaUUIDReader: JsonReader[java.util.UUID] = + stringReader.map(java.util.UUID.fromString(_)) + + implicit lazy val javaInstantReader: JsonReader[java.time.Instant] = + stringReader.map(java.time.Instant.parse) implicit lazy val javaLocalDateReader: JsonReader[java.time.LocalDate] = - stringReader.map(java.time.LocalDate.parse(_, java.time.format.DateTimeFormatter.ISO_LOCAL_DATE)) - implicit lazy val javaLocalDateTimeReader: JsonReader[java.time.LocalDateTime] = - stringReader.map(java.time.LocalDateTime.parse(_, java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME)) - implicit lazy val javaOffsetDateTimeReader: JsonReader[java.time.OffsetDateTime] = - stringReader.map(java.time.OffsetDateTime.parse(_, java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME)) - implicit lazy val javaZonedDateTimeReader: JsonReader[java.time.ZonedDateTime] = - stringReader.map(java.time.ZonedDateTime.parse(_, java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME)) + stringReader.map( + java.time.LocalDate + .parse(_, java.time.format.DateTimeFormatter.ISO_LOCAL_DATE) + ) + implicit lazy val javaLocalDateTimeReader + : JsonReader[java.time.LocalDateTime] = + stringReader.map( + java.time.LocalDateTime + .parse(_, java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME) + ) + implicit lazy val javaOffsetDateTimeReader + : JsonReader[java.time.OffsetDateTime] = + stringReader.map( + java.time.OffsetDateTime + .parse(_, java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME) + ) + implicit lazy val javaZonedDateTimeReader + : JsonReader[java.time.ZonedDateTime] = + stringReader.map( + java.time.ZonedDateTime + .parse(_, java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME) + ) } diff --git a/modules/core/src/main/scala/tethys/readers/instances/IterableReaders.scala b/modules/core/src/main/scala/tethys/readers/instances/IterableReaders.scala index bedc0761..555a7b9e 100644 --- a/modules/core/src/main/scala/tethys/readers/instances/IterableReaders.scala +++ b/modules/core/src/main/scala/tethys/readers/instances/IterableReaders.scala @@ -12,79 +12,125 @@ import scala.language.higherKinds private[tethys] trait IterableReaders extends LowPriorityIterableReaders { implicit def byteIterableReader[C[X] <: Iterable[X]](implicit - cb: CollectionBuilder[Byte, C[Byte]]): JsonReader[C[Byte]] = new TraversableReader[Byte, C] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[Byte, C[Byte]])(implicit fieldName: FieldName): Unit = { + cb: CollectionBuilder[Byte, C[Byte]] + ): JsonReader[C[Byte]] = new TraversableReader[Byte, C] { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[Byte, C[Byte]] + )(implicit fieldName: FieldName): Unit = { builder += PrimitiveReaders.ByteJsonReader.read(it) } } implicit def shortIterableReader[C[X] <: Iterable[X]](implicit - cb: CollectionBuilder[Short, C[Short]]): JsonReader[C[Short]] = new TraversableReader[Short, C] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[Short, C[Short]])(implicit fieldName: FieldName): Unit = { + cb: CollectionBuilder[Short, C[Short]] + ): JsonReader[C[Short]] = new TraversableReader[Short, C] { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[Short, C[Short]] + )(implicit fieldName: FieldName): Unit = { builder += PrimitiveReaders.ShortJsonReader.read(it) } } implicit def intIterableReader[C[X] <: Iterable[X]](implicit - cb: CollectionBuilder[Int, C[Int]]): JsonReader[C[Int]] = new TraversableReader[Int, C] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[Int, C[Int]])(implicit fieldName: FieldName): Unit = { + cb: CollectionBuilder[Int, C[Int]] + ): JsonReader[C[Int]] = new TraversableReader[Int, C] { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[Int, C[Int]] + )(implicit fieldName: FieldName): Unit = { builder += PrimitiveReaders.IntJsonReader.read(it) } } implicit def longIterableReader[C[X] <: Iterable[X]](implicit - cb: CollectionBuilder[Long, C[Long]]): JsonReader[C[Long]] = new TraversableReader[Long, C] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[Long, C[Long]])(implicit fieldName: FieldName): Unit = { + cb: CollectionBuilder[Long, C[Long]] + ): JsonReader[C[Long]] = new TraversableReader[Long, C] { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[Long, C[Long]] + )(implicit fieldName: FieldName): Unit = { builder += PrimitiveReaders.LongJsonReader.read(it) } } implicit def floatIterableReader[C[X] <: Iterable[X]](implicit - cb: CollectionBuilder[Float, C[Float]]): JsonReader[C[Float]] = new TraversableReader[Float, C] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[Float, C[Float]])(implicit fieldName: FieldName): Unit = { + cb: CollectionBuilder[Float, C[Float]] + ): JsonReader[C[Float]] = new TraversableReader[Float, C] { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[Float, C[Float]] + )(implicit fieldName: FieldName): Unit = { builder += PrimitiveReaders.FloatJsonReader.read(it) } } implicit def doubleIterableReader[C[X] <: Iterable[X]](implicit - cb: CollectionBuilder[Double, C[Double]]): JsonReader[C[Double]] = new TraversableReader[Double, C] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[Double, C[Double]])(implicit fieldName: FieldName): Unit = { + cb: CollectionBuilder[Double, C[Double]] + ): JsonReader[C[Double]] = new TraversableReader[Double, C] { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[Double, C[Double]] + )(implicit fieldName: FieldName): Unit = { builder += PrimitiveReaders.DoubleJsonReader.read(it) } } implicit def booleanIterableReader[C[X] <: Iterable[X]](implicit - cb: CollectionBuilder[Boolean, C[Boolean]]): JsonReader[C[Boolean]] = new TraversableReader[Boolean, C] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[Boolean, C[Boolean]])(implicit fieldName: FieldName): Unit = { + cb: CollectionBuilder[Boolean, C[Boolean]] + ): JsonReader[C[Boolean]] = new TraversableReader[Boolean, C] { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[Boolean, C[Boolean]] + )(implicit fieldName: FieldName): Unit = { builder += PrimitiveReaders.BooleanJsonReader.read(it) } } } -private[tethys] trait LowPriorityIterableReaders extends LowPriorityJsonReaders { +private[tethys] trait LowPriorityIterableReaders + extends LowPriorityJsonReaders { implicit def iterableReader[A, C[X] <: Iterable[X]](implicit - jsonReader: JsonReader[A], - collectionBuilder: CollectionBuilder[A, C[A]]): JsonReader[C[A]] = new TraversableReader[A, C] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[A, C[A]])(implicit fieldName: FieldName): Unit = { + jsonReader: JsonReader[A], + collectionBuilder: CollectionBuilder[A, C[A]] + ): JsonReader[C[A]] = new TraversableReader[A, C] { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[A, C[A]] + )(implicit fieldName: FieldName): Unit = { builder += jsonReader.read(it) } } protected abstract class TraversableReader[A, C[X] <: Iterable[X]](implicit - cb: CollectionBuilder[A, C[A]]) extends JsonReader[C[A]] { - protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[A, C[A]])(implicit fieldName: FieldName): Unit + cb: CollectionBuilder[A, C[A]] + ) extends JsonReader[C[A]] { + protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[A, C[A]] + )(implicit fieldName: FieldName): Unit - override def read(it: TokenIterator)(implicit fieldName: FieldName): C[A] = { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): C[A] = { if (it.currentToken().isArrayStart) recRead(0, it.next(), cb.newBuilder) - else ReaderError.wrongJson(s"Expected array start but found: ${it.currentToken()}") + else + ReaderError.wrongJson( + s"Expected array start but found: ${it.currentToken()}" + ) } @tailrec - private def recRead(i: Int, it: TokenIterator, builder: mutable.Builder[A, C[A]]) - (implicit fieldName: FieldName): C[A] = { + private def recRead( + i: Int, + it: TokenIterator, + builder: mutable.Builder[A, C[A]] + )(implicit fieldName: FieldName): C[A] = { it.currentToken() match { - case token if token.isEmpty => ReaderError.wrongJson("Unexpected end of input") + case token if token.isEmpty => + ReaderError.wrongJson("Unexpected end of input") case token if token.isArrayEnd => it.nextToken() builder.result() diff --git a/modules/core/src/main/scala/tethys/readers/instances/LowPriorityJsonReaders.scala b/modules/core/src/main/scala/tethys/readers/instances/LowPriorityJsonReaders.scala index 77aef95f..4753bd8c 100644 --- a/modules/core/src/main/scala/tethys/readers/instances/LowPriorityJsonReaders.scala +++ b/modules/core/src/main/scala/tethys/readers/instances/LowPriorityJsonReaders.scala @@ -4,7 +4,9 @@ import tethys.JsonReader import tethys.commons.LowPriorityInstance private[tethys] trait LowPriorityJsonReaders { - implicit final def lowPriorityReader[A](implicit lowPriorityInstance: LowPriorityInstance[JsonReader[A]]): JsonReader[A] = { + implicit final def lowPriorityReader[A](implicit + lowPriorityInstance: LowPriorityInstance[JsonReader[A]] + ): JsonReader[A] = { lowPriorityInstance.instance } -} \ No newline at end of file +} diff --git a/modules/core/src/main/scala/tethys/readers/instances/MapReaders.scala b/modules/core/src/main/scala/tethys/readers/instances/MapReaders.scala index c04ea438..ce2b0de3 100644 --- a/modules/core/src/main/scala/tethys/readers/instances/MapReaders.scala +++ b/modules/core/src/main/scala/tethys/readers/instances/MapReaders.scala @@ -11,77 +11,107 @@ import scala.language.higherKinds private[tethys] trait MapReaders extends LowPriorityMapReaders { implicit def byteMapReader[K, M[X, Y] <: scala.collection.Map[X, Y]](implicit - keyReader: KeyReader[K], - cb: CollectionBuilder[(K, Byte), M[K, Byte]] - ): JsonReader[M[K, Byte]] = { + keyReader: KeyReader[K], + cb: CollectionBuilder[(K, Byte), M[K, Byte]] + ): JsonReader[M[K, Byte]] = { new MapReader[K, Byte, M] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[(K, Byte), M[K, Byte]], key: K)(implicit fieldName: FieldName): Unit = { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[(K, Byte), M[K, Byte]], + key: K + )(implicit fieldName: FieldName): Unit = { builder += key -> PrimitiveReaders.ByteJsonReader.read(it) } } } implicit def shortMapReader[K, M[X, Y] <: scala.collection.Map[X, Y]](implicit - keyReader: KeyReader[K], - cb: CollectionBuilder[(K, Short), M[K, Short]] - ): JsonReader[M[K, Short]] = { + keyReader: KeyReader[K], + cb: CollectionBuilder[(K, Short), M[K, Short]] + ): JsonReader[M[K, Short]] = { new MapReader[K, Short, M] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[(K, Short), M[K, Short]], key: K)(implicit fieldName: FieldName): Unit = { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[(K, Short), M[K, Short]], + key: K + )(implicit fieldName: FieldName): Unit = { builder += key -> PrimitiveReaders.ShortJsonReader.read(it) } } } implicit def intMapReader[K, M[X, Y] <: scala.collection.Map[X, Y]](implicit - keyReader: KeyReader[K], - cb: CollectionBuilder[(K, Int), M[K, Int]] - ): JsonReader[M[K, Int]] = { + keyReader: KeyReader[K], + cb: CollectionBuilder[(K, Int), M[K, Int]] + ): JsonReader[M[K, Int]] = { new MapReader[K, Int, M] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[(K, Int), M[K, Int]], key: K)(implicit fieldName: FieldName): Unit = { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[(K, Int), M[K, Int]], + key: K + )(implicit fieldName: FieldName): Unit = { builder += key -> PrimitiveReaders.IntJsonReader.read(it) } } } implicit def longMapReader[K, M[X, Y] <: scala.collection.Map[X, Y]](implicit - keyReader: KeyReader[K], - cb: CollectionBuilder[(K, Long), M[K, Long]] - ): JsonReader[M[K, Long]] = { + keyReader: KeyReader[K], + cb: CollectionBuilder[(K, Long), M[K, Long]] + ): JsonReader[M[K, Long]] = { new MapReader[K, Long, M] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[(K, Long), M[K, Long]], key: K)(implicit fieldName: FieldName): Unit = { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[(K, Long), M[K, Long]], + key: K + )(implicit fieldName: FieldName): Unit = { builder += key -> PrimitiveReaders.LongJsonReader.read(it) } } } implicit def floatMapReader[K, M[X, Y] <: scala.collection.Map[X, Y]](implicit - keyReader: KeyReader[K], - cb: CollectionBuilder[(K, Float), M[K, Float]] - ): JsonReader[M[K, Float]] = { + keyReader: KeyReader[K], + cb: CollectionBuilder[(K, Float), M[K, Float]] + ): JsonReader[M[K, Float]] = { new MapReader[K, Float, M] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[(K, Float), M[K, Float]], key: K)(implicit fieldName: FieldName): Unit = { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[(K, Float), M[K, Float]], + key: K + )(implicit fieldName: FieldName): Unit = { builder += key -> PrimitiveReaders.FloatJsonReader.read(it) } } } - implicit def doubleMapReader[K, M[X, Y] <: scala.collection.Map[X, Y]](implicit - keyReader: KeyReader[K], - cb: CollectionBuilder[(K, Double), M[K, Double]] - ): JsonReader[M[K, Double]] = { + implicit def doubleMapReader[K, M[X, Y] <: scala.collection.Map[X, Y]]( + implicit + keyReader: KeyReader[K], + cb: CollectionBuilder[(K, Double), M[K, Double]] + ): JsonReader[M[K, Double]] = { new MapReader[K, Double, M] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[(K, Double), M[K, Double]], key: K)(implicit fieldName: FieldName): Unit = { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[(K, Double), M[K, Double]], + key: K + )(implicit fieldName: FieldName): Unit = { builder += key -> PrimitiveReaders.DoubleJsonReader.read(it) } } } - implicit def booleanMapReader[K, M[X, Y] <: scala.collection.Map[X, Y]](implicit - keyReader: KeyReader[K], - cb: CollectionBuilder[(K, Boolean), M[K, Boolean]] - ): JsonReader[M[K, Boolean]] = { + implicit def booleanMapReader[K, M[X, Y] <: scala.collection.Map[X, Y]]( + implicit + keyReader: KeyReader[K], + cb: CollectionBuilder[(K, Boolean), M[K, Boolean]] + ): JsonReader[M[K, Boolean]] = { new MapReader[K, Boolean, M] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[(K, Boolean), M[K, Boolean]], key: K)(implicit fieldName: FieldName): Unit = { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[(K, Boolean), M[K, Boolean]], + key: K + )(implicit fieldName: FieldName): Unit = { builder += key -> PrimitiveReaders.BooleanJsonReader.read(it) } } @@ -91,34 +121,48 @@ private[tethys] trait MapReaders extends LowPriorityMapReaders { private[tethys] trait LowPriorityMapReaders extends IterableReaders { implicit def mapReader[K, A, M[X, Y] <: scala.collection.Map[X, Y]](implicit - keyReader: KeyReader[K], - jsonReader: JsonReader[A], - cb: CollectionBuilder[(K, A), M[K, A]] - ): JsonReader[M[K, A]] = { + keyReader: KeyReader[K], + jsonReader: JsonReader[A], + cb: CollectionBuilder[(K, A), M[K, A]] + ): JsonReader[M[K, A]] = { new MapReader[K, A, M] { - override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[(K, A), M[K, A]], key: K)(implicit fieldName: FieldName): Unit = { + override protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[(K, A), M[K, A]], + key: K + )(implicit fieldName: FieldName): Unit = { builder += key -> jsonReader.read(it) } } } protected abstract class MapReader[K, A, M[_, _]](implicit - keyReader: KeyReader[K], - cb: CollectionBuilder[(K, A), M[K, A]] - ) extends JsonReader[M[K, A]] { - - protected def appendBuilder(it: TokenIterator, - builder: mutable.Builder[(K, A), M[K, A]], - key: K)(implicit fieldName: FieldName): Unit - - override def read(it: TokenIterator)(implicit fieldName: FieldName): M[K, A] = { - if (it.currentToken().isObjectStart) recRead(it.next(), cb.newBuilder)(fieldName) - else ReaderError.wrongJson(s"Expected object start but found: ${it.currentToken()}") + keyReader: KeyReader[K], + cb: CollectionBuilder[(K, A), M[K, A]] + ) extends JsonReader[M[K, A]] { + + protected def appendBuilder( + it: TokenIterator, + builder: mutable.Builder[(K, A), M[K, A]], + key: K + )(implicit fieldName: FieldName): Unit + + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): M[K, A] = { + if (it.currentToken().isObjectStart) + recRead(it.next(), cb.newBuilder)(fieldName) + else + ReaderError.wrongJson( + s"Expected object start but found: ${it.currentToken()}" + ) } @tailrec - private def recRead(it: TokenIterator, builder: mutable.Builder[(K, A), M[K, A]]) - (fieldName: FieldName): M[K, A] = { + private def recRead( + it: TokenIterator, + builder: mutable.Builder[(K, A), M[K, A]] + )(fieldName: FieldName): M[K, A] = { it.currentToken() match { case token if token.isObjectEnd => it.nextToken() @@ -126,10 +170,17 @@ private[tethys] trait LowPriorityMapReaders extends IterableReaders { case token if token.isFieldName => val name = it.fieldName() val nextFieldName = fieldName.appendFieldName(name) - appendBuilder(it.next(), builder, keyReader.read(name)(nextFieldName))(nextFieldName) + appendBuilder( + it.next(), + builder, + keyReader.read(name)(nextFieldName) + )(nextFieldName) recRead(it, builder)(fieldName) - case token => ReaderError.wrongJson(s"Expect end of object or field name but '$token' found")(fieldName) + case token => + ReaderError.wrongJson( + s"Expect end of object or field name but '$token' found" + )(fieldName) } } } diff --git a/modules/core/src/main/scala/tethys/readers/instances/OptionReaders.scala b/modules/core/src/main/scala/tethys/readers/instances/OptionReaders.scala index b8d003eb..7c47825f 100644 --- a/modules/core/src/main/scala/tethys/readers/instances/OptionReaders.scala +++ b/modules/core/src/main/scala/tethys/readers/instances/OptionReaders.scala @@ -5,52 +5,77 @@ import tethys.readers.FieldName import tethys.readers.tokens.TokenIterator private[tethys] trait OptionReaders extends LowPriorityOptionReaders { - implicit lazy val byteOptionReader: JsonReader[Option[Byte]] = new OptionJsonReader[Byte] { - override protected def readSomeValue(it: TokenIterator)(implicit fieldName: FieldName): Option[Byte] = { - Some(PrimitiveReaders.ByteJsonReader.read(it)) + implicit lazy val byteOptionReader: JsonReader[Option[Byte]] = + new OptionJsonReader[Byte] { + override protected def readSomeValue( + it: TokenIterator + )(implicit fieldName: FieldName): Option[Byte] = { + Some(PrimitiveReaders.ByteJsonReader.read(it)) + } } - } - implicit lazy val shortOptionReader: JsonReader[Option[Short]] = new OptionJsonReader[Short] { - override protected def readSomeValue(it: TokenIterator)(implicit fieldName: FieldName): Option[Short] = { - Some(PrimitiveReaders.ShortJsonReader.read(it)) + implicit lazy val shortOptionReader: JsonReader[Option[Short]] = + new OptionJsonReader[Short] { + override protected def readSomeValue( + it: TokenIterator + )(implicit fieldName: FieldName): Option[Short] = { + Some(PrimitiveReaders.ShortJsonReader.read(it)) + } } - } - implicit lazy val intOptionReader: JsonReader[Option[Int]] = new OptionJsonReader[Int] { - override protected def readSomeValue(it: TokenIterator)(implicit fieldName: FieldName): Option[Int] = { - Some(PrimitiveReaders.IntJsonReader.read(it)) + implicit lazy val intOptionReader: JsonReader[Option[Int]] = + new OptionJsonReader[Int] { + override protected def readSomeValue( + it: TokenIterator + )(implicit fieldName: FieldName): Option[Int] = { + Some(PrimitiveReaders.IntJsonReader.read(it)) + } } - } - implicit lazy val longOptionReader: JsonReader[Option[Long]] = new OptionJsonReader[Long] { - override protected def readSomeValue(it: TokenIterator)(implicit fieldName: FieldName): Option[Long] = { - Some(PrimitiveReaders.LongJsonReader.read(it)) + implicit lazy val longOptionReader: JsonReader[Option[Long]] = + new OptionJsonReader[Long] { + override protected def readSomeValue( + it: TokenIterator + )(implicit fieldName: FieldName): Option[Long] = { + Some(PrimitiveReaders.LongJsonReader.read(it)) + } } - } - implicit lazy val floatOptionReader: JsonReader[Option[Float]] = new OptionJsonReader[Float] { - override protected def readSomeValue(it: TokenIterator)(implicit fieldName: FieldName): Option[Float] = { - Some(PrimitiveReaders.FloatJsonReader.read(it)) + implicit lazy val floatOptionReader: JsonReader[Option[Float]] = + new OptionJsonReader[Float] { + override protected def readSomeValue( + it: TokenIterator + )(implicit fieldName: FieldName): Option[Float] = { + Some(PrimitiveReaders.FloatJsonReader.read(it)) + } } - } - implicit lazy val doubleOptionReader: JsonReader[Option[Double]] = new OptionJsonReader[Double] { - override protected def readSomeValue(it: TokenIterator)(implicit fieldName: FieldName): Option[Double] = { - Some(PrimitiveReaders.DoubleJsonReader.read(it)) + implicit lazy val doubleOptionReader: JsonReader[Option[Double]] = + new OptionJsonReader[Double] { + override protected def readSomeValue( + it: TokenIterator + )(implicit fieldName: FieldName): Option[Double] = { + Some(PrimitiveReaders.DoubleJsonReader.read(it)) + } } - } - implicit lazy val booleanOptionReader: JsonReader[Option[Boolean]] = new OptionJsonReader[Boolean] { - override protected def readSomeValue(it: TokenIterator)(implicit fieldName: FieldName): Option[Boolean] = { - Some(PrimitiveReaders.BooleanJsonReader.read(it)) + implicit lazy val booleanOptionReader: JsonReader[Option[Boolean]] = + new OptionJsonReader[Boolean] { + override protected def readSomeValue( + it: TokenIterator + )(implicit fieldName: FieldName): Option[Boolean] = { + Some(PrimitiveReaders.BooleanJsonReader.read(it)) + } } - } } private[tethys] trait LowPriorityOptionReaders extends MapReaders { - implicit def optionReader[A](implicit jsonReader: JsonReader[A]): JsonReader[Option[A]] = new OptionJsonReader[A] { - override protected def readSomeValue(it: TokenIterator)(implicit fieldName: FieldName): Option[A] = { + implicit def optionReader[A](implicit + jsonReader: JsonReader[A] + ): JsonReader[Option[A]] = new OptionJsonReader[A] { + override protected def readSomeValue( + it: TokenIterator + )(implicit fieldName: FieldName): Option[A] = { Some(jsonReader.read(it)) } } @@ -58,9 +83,13 @@ private[tethys] trait LowPriorityOptionReaders extends MapReaders { @specialized protected abstract class OptionJsonReader[A] extends JsonReader[Option[A]] { - protected def readSomeValue(it: TokenIterator)(implicit fieldName: FieldName): Option[A] + protected def readSomeValue(it: TokenIterator)(implicit + fieldName: FieldName + ): Option[A] - override def read(it: TokenIterator)(implicit fieldName: FieldName): Option[A] = { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): Option[A] = { if (it.currentToken().isNullValue) { it.nextToken() None diff --git a/modules/core/src/main/scala/tethys/readers/instances/PrimitiveReaders.scala b/modules/core/src/main/scala/tethys/readers/instances/PrimitiveReaders.scala index 660032d5..dc1c2702 100644 --- a/modules/core/src/main/scala/tethys/readers/instances/PrimitiveReaders.scala +++ b/modules/core/src/main/scala/tethys/readers/instances/PrimitiveReaders.scala @@ -6,31 +6,35 @@ import tethys.readers.{FieldName, ReaderError} object PrimitiveReaders { object ByteJsonReader { def read(it: TokenIterator)(implicit fieldName: FieldName): Byte = { - if(it.currentToken().isNumberValue) { + if (it.currentToken().isNumberValue) { val res = it.byte() it.nextToken() res } else { - ReaderError.wrongJson(s"Expected byte value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected byte value but found: ${it.currentToken()}" + ) } } } object ShortJsonReader { def read(it: TokenIterator)(implicit fieldName: FieldName): Short = { - if(it.currentToken().isNumberValue) { + if (it.currentToken().isNumberValue) { val res = it.short() it.nextToken() res } else { - ReaderError.wrongJson(s"Expected short value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected short value but found: ${it.currentToken()}" + ) } } } object IntJsonReader { def read(it: TokenIterator)(implicit fieldName: FieldName): Int = { - if(it.currentToken().isNumberValue) { + if (it.currentToken().isNumberValue) { val res = it.int() it.nextToken() res @@ -40,54 +44,64 @@ object PrimitiveReaders { } private def error(it: TokenIterator)(implicit fieldName: FieldName) = { - ReaderError.wrongJson(s"Expected int value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected int value but found: ${it.currentToken()}" + ) } } object LongJsonReader { def read(it: TokenIterator)(implicit fieldName: FieldName): Long = { - if(it.currentToken().isNumberValue) { + if (it.currentToken().isNumberValue) { val res = it.long() it.nextToken() res } else { - ReaderError.wrongJson(s"Expected long value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected long value but found: ${it.currentToken()}" + ) } } } object FloatJsonReader { def read(it: TokenIterator)(implicit fieldName: FieldName): Float = { - if(it.currentToken().isNumberValue) { + if (it.currentToken().isNumberValue) { val res = it.float() it.nextToken() res } else { - ReaderError.wrongJson(s"Expected float value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected float value but found: ${it.currentToken()}" + ) } } } object DoubleJsonReader { def read(it: TokenIterator)(implicit fieldName: FieldName): Double = { - if(it.currentToken().isNumberValue) { + if (it.currentToken().isNumberValue) { val res = it.double() it.nextToken() res } else { - ReaderError.wrongJson(s"Expected double value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected double value but found: ${it.currentToken()}" + ) } } } object BooleanJsonReader { def read(it: TokenIterator)(implicit fieldName: FieldName): Boolean = { - if(it.currentToken().isBooleanValue) { + if (it.currentToken().isBooleanValue) { val res = it.boolean() it.nextToken() res } else { - ReaderError.wrongJson(s"Expected boolean value but found: ${it.currentToken()}") + ReaderError.wrongJson( + s"Expected boolean value but found: ${it.currentToken()}" + ) } } } diff --git a/modules/core/src/main/scala/tethys/readers/instances/SelectingJsonReader.scala b/modules/core/src/main/scala/tethys/readers/instances/SelectingJsonReader.scala index 6d870748..92cce2d9 100644 --- a/modules/core/src/main/scala/tethys/readers/instances/SelectingJsonReader.scala +++ b/modules/core/src/main/scala/tethys/readers/instances/SelectingJsonReader.scala @@ -4,7 +4,9 @@ import tethys.JsonReader import tethys.readers.FieldName import tethys.readers.tokens.TokenIterator -class SelectingJsonReader[A, B](simpleJsonReader: SimpleJsonReader[A])(selector: A => JsonReader[_ <: B]) extends JsonReader[B] { +class SelectingJsonReader[A, B](simpleJsonReader: SimpleJsonReader[A])( + selector: A => JsonReader[_ <: B] +) extends JsonReader[B] { override def read(it: TokenIterator)(implicit fieldName: FieldName): B = { val it1 = it.collectExpression() diff --git a/modules/core/src/main/scala/tethys/readers/instances/SimpleJsonReader.scala b/modules/core/src/main/scala/tethys/readers/instances/SimpleJsonReader.scala index f64bc997..bcb6e396 100644 --- a/modules/core/src/main/scala/tethys/readers/instances/SimpleJsonReader.scala +++ b/modules/core/src/main/scala/tethys/readers/instances/SimpleJsonReader.scala @@ -8,37 +8,69 @@ import tethys.readers.{FieldName, ReaderError} import scala.annotation.tailrec import scala.collection.mutable -private[readers] class SimpleJsonReader[A](fields: Array[FieldDefinition[_]], mapper: Array[Any] => A, strict: Boolean) extends JsonReader[A] { +private[readers] class SimpleJsonReader[A]( + fields: Array[FieldDefinition[_]], + mapper: Array[Any] => A, + strict: Boolean +) extends JsonReader[A] { private val defaults: Array[Any] = fields.map(_.defaultValue) override def read(it: TokenIterator)(implicit fieldName: FieldName): A = { - if(!it.currentToken().isObjectStart) ReaderError.wrongJson(s"Expected object start but found: ${it.currentToken()}") + if (!it.currentToken().isObjectStart) + ReaderError.wrongJson( + s"Expected object start but found: ${it.currentToken()}" + ) else { it.nextToken() val extracted: Array[Any] = recRead(it, defaults.clone()) - val notExtracted = collectNotExtracted(0, hasErrors = false, extracted, new mutable.StringBuilder()) - if(notExtracted.nonEmpty) ReaderError.wrongJson(s"Can not extract fields $notExtracted") + val notExtracted = collectNotExtracted( + 0, + hasErrors = false, + extracted, + new mutable.StringBuilder() + ) + if (notExtracted.nonEmpty) + ReaderError.wrongJson(s"Can not extract fields $notExtracted") else mapper(extracted) } } @tailrec - private def collectNotExtracted(i: Int, hasErrors: Boolean, extracted: Array[Any], builder: mutable.StringBuilder): String = { - if(i >= extracted.length) { - if(hasErrors) builder.append('\'').result() + private def collectNotExtracted( + i: Int, + hasErrors: Boolean, + extracted: Array[Any], + builder: mutable.StringBuilder + ): String = { + if (i >= extracted.length) { + if (hasErrors) builder.append('\'').result() else "" - } else if(extracted(i) == null) { - if(!hasErrors) collectNotExtracted(i + 1, hasErrors = true, extracted, builder.append('\'').append(fields(i).name)) - else collectNotExtracted(i + 1, hasErrors = true, extracted, builder.append("', '").append(fields(i).name)) + } else if (extracted(i) == null) { + if (!hasErrors) + collectNotExtracted( + i + 1, + hasErrors = true, + extracted, + builder.append('\'').append(fields(i).name) + ) + else + collectNotExtracted( + i + 1, + hasErrors = true, + extracted, + builder.append("', '").append(fields(i).name) + ) } else { collectNotExtracted(i + 1, hasErrors, extracted, builder) } } @tailrec - private def recRead(it: TokenIterator, extracted: Array[Any])(implicit fieldName: FieldName): Array[Any] = { + private def recRead(it: TokenIterator, extracted: Array[Any])(implicit + fieldName: FieldName + ): Array[Any] = { it.currentToken() match { case token if token.isObjectEnd => it.nextToken() @@ -47,27 +79,31 @@ private[readers] class SimpleJsonReader[A](fields: Array[FieldDefinition[_]], ma val name = it.fieldName() recRead(it, extractField(0, name, it.next(), extracted)) case token => - ReaderError.wrongJson(s"Expect end of object or field name but '$token' found") + ReaderError.wrongJson( + s"Expect end of object or field name but '$token' found" + ) } } @tailrec - private def extractField(i: Int, - name: String, - it: TokenIterator, - extracted: Array[Any]) - (implicit - fieldName: FieldName): Array[Any] = { - if(i >= extracted.length) { - if(strict) { - ReaderError.wrongJson(s"unexpected field '$name', expected one of ${fields.map(_.name).mkString("'", "', '", "'")}") + private def extractField( + i: Int, + name: String, + it: TokenIterator, + extracted: Array[Any] + )(implicit fieldName: FieldName): Array[Any] = { + if (i >= extracted.length) { + if (strict) { + ReaderError.wrongJson( + s"unexpected field '$name', expected one of ${fields.map(_.name).mkString("'", "', '", "'")}" + ) } else { it.skipExpression() extracted } } else { val field = fields(i) - if(field.name == name) { + if (field.name == name) { extracted(i) = field.reader.read(it)(fieldName.appendFieldName(name)) extracted } else { @@ -78,5 +114,9 @@ private[readers] class SimpleJsonReader[A](fields: Array[FieldDefinition[_]], ma } private[readers] object SimpleJsonReader { - case class FieldDefinition[A](name: String, defaultValue: Any, reader: JsonReader[A]) -} \ No newline at end of file + case class FieldDefinition[A]( + name: String, + defaultValue: Any, + reader: JsonReader[A] + ) +} diff --git a/modules/core/src/main/scala/tethys/readers/tokens/BaseTokenIterator.scala b/modules/core/src/main/scala/tethys/readers/tokens/BaseTokenIterator.scala index c013cccf..7f19994d 100644 --- a/modules/core/src/main/scala/tethys/readers/tokens/BaseTokenIterator.scala +++ b/modules/core/src/main/scala/tethys/readers/tokens/BaseTokenIterator.scala @@ -16,35 +16,39 @@ trait BaseTokenIterator extends TokenIterator { override def skipExpression(): this.type = { val token = currentToken() - if(token.isStructStart) skipStructure(1).next() + if (token.isStructStart) skipStructure(1).next() else next() } override def collectExpression(): TokenIterator with CopySupport = { val queue = createTokenNode() match { case (node, 0) => immutable.Queue[TokenNode](node) - case (node, _) => collectTokens(1, immutable.Queue.newBuilder[TokenNode] += node) + case (node, _) => + collectTokens(1, immutable.Queue.newBuilder[TokenNode] += node) } - nextToken()//set pointer after this expression end + nextToken() // set pointer after this expression end new QueueIterator(queue) } @tailrec private def skipStructure(started: Int): this.type = { - if(started == 0) this + if (started == 0) this else { val token = nextToken() - if(token.isStructStart) skipStructure(started + 1) - else if(token.isStructEnd) skipStructure(started - 1) + if (token.isStructStart) skipStructure(started + 1) + else if (token.isStructEnd) skipStructure(started - 1) else skipStructure(started) } } @tailrec - private def collectTokens(started: Int, builder: mutable.Builder[TokenNode, immutable.Queue[TokenNode]]): immutable.Queue[TokenNode] = { - if(started == 0) builder.result() + private def collectTokens( + started: Int, + builder: mutable.Builder[TokenNode, immutable.Queue[TokenNode]] + ): immutable.Queue[TokenNode] = { + if (started == 0) builder.result() else { nextToken() val (node, shift) = createTokenNode() @@ -54,21 +58,21 @@ trait BaseTokenIterator extends TokenIterator { private def createTokenNode(): (TokenNode, Int) = { val token = currentToken() - if(token.isArrayStart) ArrayStartNode -> 1 - else if(token.isArrayEnd) ArrayEndNode -> -1 - else if(token.isObjectStart) ObjectStartNode -> 1 - else if(token.isObjectEnd) ObjectEndNode -> -1 - else if(token.isNullValue) NullValueNode -> 0 - else if(token.isFieldName) FieldNameNode(fieldName()) -> 0 - else if(token.isStringValue) StringValueNode(string()) -> 0 - else if(token.isNumberValue) number() match { - case v: java.lang.Byte => ByteValueNode(v) -> 0 - case v: java.lang.Short => ShortValueNode(v) -> 0 + if (token.isArrayStart) ArrayStartNode -> 1 + else if (token.isArrayEnd) ArrayEndNode -> -1 + else if (token.isObjectStart) ObjectStartNode -> 1 + else if (token.isObjectEnd) ObjectEndNode -> -1 + else if (token.isNullValue) NullValueNode -> 0 + else if (token.isFieldName) FieldNameNode(fieldName()) -> 0 + else if (token.isStringValue) StringValueNode(string()) -> 0 + else if (token.isNumberValue) number() match { + case v: java.lang.Byte => ByteValueNode(v) -> 0 + case v: java.lang.Short => ShortValueNode(v) -> 0 case v: java.lang.Integer => IntValueNode(v) -> 0 - case v: java.lang.Long => LongValueNode(v) -> 0 - case v: java.lang.Float => FloatValueNode(v) -> 0 - case v: java.lang.Double => DoubleValueNode(v) -> 0 - case n => NumberValueNode(n) -> 0 + case v: java.lang.Long => LongValueNode(v) -> 0 + case v: java.lang.Float => FloatValueNode(v) -> 0 + case v: java.lang.Double => DoubleValueNode(v) -> 0 + case n => NumberValueNode(n) -> 0 } else BooleanValueNode(boolean()) -> 0 } diff --git a/modules/core/src/main/scala/tethys/readers/tokens/QueueIterator.scala b/modules/core/src/main/scala/tethys/readers/tokens/QueueIterator.scala index 922bfbf4..79f3869b 100644 --- a/modules/core/src/main/scala/tethys/readers/tokens/QueueIterator.scala +++ b/modules/core/src/main/scala/tethys/readers/tokens/QueueIterator.scala @@ -10,107 +10,111 @@ import scala.collection.mutable import scala.collection.immutable import scala.reflect.ClassTag -class QueueIterator(private var nodes: immutable.Queue[TokenNode]) extends BaseTokenIterator with CopySupport { +class QueueIterator(private var nodes: immutable.Queue[TokenNode]) + extends BaseTokenIterator + with CopySupport { override def copy(): QueueIterator = QueueIterator(nodes) - override def currentToken(): Token = if(nodes.isEmpty) Token.Empty else nodes.head.token + override def currentToken(): Token = + if (nodes.isEmpty) Token.Empty else nodes.head.token - override def nextToken(): Token = if(nodes.isEmpty) Token.Empty else { + override def nextToken(): Token = if (nodes.isEmpty) Token.Empty + else { nodes = nodes.tail currentToken() } override def fieldName(): String = nodes.front match { case FieldNameNode(name) => name - case node => fail[FieldNameNode](node) + case node => fail[FieldNameNode](node) } override def string(): String = nodes.front match { case StringValueNode(value) => value - case node => fail[StringValueNode](node) + case node => fail[StringValueNode](node) } override def boolean(): Boolean = nodes.front match { case BooleanValueNode(value) => value - case node => fail[BooleanValueNode](node) + case node => fail[BooleanValueNode](node) } override def number(): Number = nodes.front match { case NumberValueNode(value) => value - case ByteValueNode(value) => value - case ShortValueNode(value) => value - case IntValueNode(value) => value - case LongValueNode(value) => value - case FloatValueNode(value) => value + case ByteValueNode(value) => value + case ShortValueNode(value) => value + case IntValueNode(value) => value + case LongValueNode(value) => value + case FloatValueNode(value) => value case DoubleValueNode(value) => value - case node => fail[NumberValueNode](node) + case node => fail[NumberValueNode](node) } override def byte(): Byte = nodes.front match { - case ByteValueNode(value) => value + case ByteValueNode(value) => value case NumberValueNode(value) => value.byteValue() - case ShortValueNode(value) => value.toByte - case IntValueNode(value) => value.toByte - case LongValueNode(value) => value.toByte - case FloatValueNode(value) => value.toByte + case ShortValueNode(value) => value.toByte + case IntValueNode(value) => value.toByte + case LongValueNode(value) => value.toByte + case FloatValueNode(value) => value.toByte case DoubleValueNode(value) => value.toByte - case node => fail[ByteValueNode](node) + case node => fail[ByteValueNode](node) } override def short(): Short = nodes.front match { - case ShortValueNode(value) => value + case ShortValueNode(value) => value case NumberValueNode(value) => value.shortValue() - case ByteValueNode(value) => value.toShort - case IntValueNode(value) => value.toShort - case LongValueNode(value) => value.toShort - case FloatValueNode(value) => value.toShort + case ByteValueNode(value) => value.toShort + case IntValueNode(value) => value.toShort + case LongValueNode(value) => value.toShort + case FloatValueNode(value) => value.toShort case DoubleValueNode(value) => value.toShort - case node => fail[ShortValueNode](node) + case node => fail[ShortValueNode](node) } override def int(): Int = nodes.front match { - case IntValueNode(value) => value + case IntValueNode(value) => value case NumberValueNode(value) => value.intValue() - case ByteValueNode(value) => value.toInt - case ShortValueNode(value) => value.toInt - case LongValueNode(value) => value.toInt - case FloatValueNode(value) => value.toInt + case ByteValueNode(value) => value.toInt + case ShortValueNode(value) => value.toInt + case LongValueNode(value) => value.toInt + case FloatValueNode(value) => value.toInt case DoubleValueNode(value) => value.toInt - case node => fail[IntValueNode](node) + case node => fail[IntValueNode](node) } override def long(): Long = nodes.front match { - case LongValueNode(value) => value + case LongValueNode(value) => value case NumberValueNode(value) => value.longValue() - case ByteValueNode(value) => value.toLong - case ShortValueNode(value) => value.toLong - case IntValueNode(value) => value.toLong - case FloatValueNode(value) => value.toLong + case ByteValueNode(value) => value.toLong + case ShortValueNode(value) => value.toLong + case IntValueNode(value) => value.toLong + case FloatValueNode(value) => value.toLong case DoubleValueNode(value) => value.toLong - case node => fail[LongValueNode](node) + case node => fail[LongValueNode](node) } override def float(): Float = nodes.front match { - case FloatValueNode(value) => value + case FloatValueNode(value) => value case NumberValueNode(value) => value.floatValue() - case ByteValueNode(value) => value.toFloat - case ShortValueNode(value) => value.toFloat - case IntValueNode(value) => value.toFloat - case LongValueNode(value) => value.toFloat + case ByteValueNode(value) => value.toFloat + case ShortValueNode(value) => value.toFloat + case IntValueNode(value) => value.toFloat + case LongValueNode(value) => value.toFloat case DoubleValueNode(value) => value.toFloat - case node => fail[FloatValueNode](node) + case node => fail[FloatValueNode](node) } override def double(): Double = nodes.front match { case DoubleValueNode(value) => value case NumberValueNode(value) => value.doubleValue() - case ByteValueNode(value) => value.toDouble - case ShortValueNode(value) => value.toDouble - case IntValueNode(value) => value.toDouble - case LongValueNode(value) => value.toDouble - case FloatValueNode(value) => value.toDouble - case node => fail[DoubleValueNode](node) + case ByteValueNode(value) => value.toDouble + case ShortValueNode(value) => value.toDouble + case IntValueNode(value) => value.toDouble + case LongValueNode(value) => value.toDouble + case FloatValueNode(value) => value.toDouble + case node => fail[DoubleValueNode](node) } override def collectExpression(): TokenIterator with CopySupport = { @@ -124,8 +128,11 @@ class QueueIterator(private var nodes: immutable.Queue[TokenNode]) extends BaseT } @tailrec - private def collectTokens(started: Int, builder: mutable.Builder[TokenNode, immutable.Queue[TokenNode]]): immutable.Queue[TokenNode] = { - if(started == 0) builder.result() + private def collectTokens( + started: Int, + builder: mutable.Builder[TokenNode, immutable.Queue[TokenNode]] + ): immutable.Queue[TokenNode] = { + if (started == 0) builder.result() else { val node = currentNode() collectTokens(started + getTokenShift(node), builder += node) @@ -133,7 +140,8 @@ class QueueIterator(private var nodes: immutable.Queue[TokenNode]) extends BaseT } private def currentNode(): TokenNode = { - if(nodes.isEmpty) throw new NoSuchElementException("Can not finish expression") + if (nodes.isEmpty) + throw new NoSuchElementException("Can not finish expression") else { val (head, tail) = nodes.dequeue nodes = tail @@ -143,17 +151,23 @@ class QueueIterator(private var nodes: immutable.Queue[TokenNode]) extends BaseT private def getTokenShift(node: TokenNode): Int = node match { case ArrayStartNode | ObjectStartNode => 1 - case ArrayEndNode | ObjectEndNode => -1 - case _ => 0 + case ArrayEndNode | ObjectEndNode => -1 + case _ => 0 } - private def fail[A <: TokenNode](actual: TokenNode)(implicit ct: ClassTag[A]): Nothing = { - throw new WrongTokenError(s"Expected '${ct.toString()}' but '$actual' found") + private def fail[A <: TokenNode]( + actual: TokenNode + )(implicit ct: ClassTag[A]): Nothing = { + throw new WrongTokenError( + s"Expected '${ct.toString()}' but '$actual' found" + ) } } -object QueueIterator{ - def apply(nodes: Seq[TokenNode]): QueueIterator = new QueueIterator(immutable.Queue[TokenNode](nodes: _*)) +object QueueIterator { + def apply(nodes: Seq[TokenNode]): QueueIterator = new QueueIterator( + immutable.Queue[TokenNode](nodes: _*) + ) final class WrongTokenError(message: String) extends Exception(message, null) } diff --git a/modules/core/src/main/scala/tethys/writers/EmptyWriters.scala b/modules/core/src/main/scala/tethys/writers/EmptyWriters.scala index f69d93ff..51553c31 100644 --- a/modules/core/src/main/scala/tethys/writers/EmptyWriters.scala +++ b/modules/core/src/main/scala/tethys/writers/EmptyWriters.scala @@ -5,7 +5,8 @@ import tethys.writers.tokens.TokenWriter trait EmptyWriters { def emptyWriter[A]: JsonWriter[A] = new JsonWriter[A] { - override def write(name: String, value: A, tokenWriter: TokenWriter): Unit = () + override def write(name: String, value: A, tokenWriter: TokenWriter): Unit = + () override def write(value: A, tokenWriter: TokenWriter): Unit = () } } diff --git a/modules/core/src/main/scala/tethys/writers/instances/AllJsonWriters.scala b/modules/core/src/main/scala/tethys/writers/instances/AllJsonWriters.scala index c399cdc4..1ceb1704 100644 --- a/modules/core/src/main/scala/tethys/writers/instances/AllJsonWriters.scala +++ b/modules/core/src/main/scala/tethys/writers/instances/AllJsonWriters.scala @@ -5,120 +5,197 @@ import tethys.writers.tokens.TokenWriter trait AllJsonWriters extends OptionWriters with EitherWriters { implicit lazy val intWriter: JsonWriter[Int] = new JsonWriter[Int] { - override def write(value: Int, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) + override def write(value: Int, tokenWriter: TokenWriter): Unit = + tokenWriter.writeNumber(value) } implicit lazy val longWriter: JsonWriter[Long] = new JsonWriter[Long] { - override def write(value: Long, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) + override def write(value: Long, tokenWriter: TokenWriter): Unit = + tokenWriter.writeNumber(value) } implicit lazy val byteWriter: JsonWriter[Byte] = new JsonWriter[Byte] { - override def write(value: Byte, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) + override def write(value: Byte, tokenWriter: TokenWriter): Unit = + tokenWriter.writeNumber(value) } implicit lazy val shortWriter: JsonWriter[Short] = new JsonWriter[Short] { - override def write(value: Short, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) + override def write(value: Short, tokenWriter: TokenWriter): Unit = + tokenWriter.writeNumber(value) } implicit lazy val doubleWriter: JsonWriter[Double] = new JsonWriter[Double] { - override def write(value: Double, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) + override def write(value: Double, tokenWriter: TokenWriter): Unit = + tokenWriter.writeNumber(value) } implicit lazy val floatWriter: JsonWriter[Float] = new JsonWriter[Float] { - override def write(value: Float, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) + override def write(value: Float, tokenWriter: TokenWriter): Unit = + tokenWriter.writeNumber(value) } - implicit lazy val bigDecimalWriter: JsonWriter[BigDecimal] = new JsonWriter[BigDecimal] { - override def write(value: BigDecimal, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) - } + implicit lazy val bigDecimalWriter: JsonWriter[BigDecimal] = + new JsonWriter[BigDecimal] { + override def write(value: BigDecimal, tokenWriter: TokenWriter): Unit = + tokenWriter.writeNumber(value) + } implicit lazy val bigIntWriter: JsonWriter[BigInt] = new JsonWriter[BigInt] { - override def write(value: BigInt, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) + override def write(value: BigInt, tokenWriter: TokenWriter): Unit = + tokenWriter.writeNumber(value) } - implicit lazy val booleanWriter: JsonWriter[Boolean] = new JsonWriter[Boolean] { - override def write(value: Boolean, tokenWriter: TokenWriter): Unit = tokenWriter.writeBoolean(value) - } + implicit lazy val booleanWriter: JsonWriter[Boolean] = + new JsonWriter[Boolean] { + override def write(value: Boolean, tokenWriter: TokenWriter): Unit = + tokenWriter.writeBoolean(value) + } implicit lazy val stringWriter: JsonWriter[String] = new JsonWriter[String] { - override def write(value: String, tokenWriter: TokenWriter): Unit = tokenWriter.writeString(value) + override def write(value: String, tokenWriter: TokenWriter): Unit = + tokenWriter.writeString(value) } implicit lazy val charWriter: JsonWriter[Char] = new JsonWriter[Char] { - override def write(value: Char, tokenWriter: TokenWriter): Unit = tokenWriter.writeString(value.toString) + override def write(value: Char, tokenWriter: TokenWriter): Unit = + tokenWriter.writeString(value.toString) } - implicit lazy val javaIntWriter: JsonWriter[java.lang.Integer] = new JsonWriter[java.lang.Integer] { - override def write(value: java.lang.Integer, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) - } + implicit lazy val javaIntWriter: JsonWriter[java.lang.Integer] = + new JsonWriter[java.lang.Integer] { + override def write( + value: java.lang.Integer, + tokenWriter: TokenWriter + ): Unit = tokenWriter.writeNumber(value) + } - implicit lazy val javaLongWriter: JsonWriter[java.lang.Long] = new JsonWriter[java.lang.Long] { - override def write(value: java.lang.Long, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) - } + implicit lazy val javaLongWriter: JsonWriter[java.lang.Long] = + new JsonWriter[java.lang.Long] { + override def write( + value: java.lang.Long, + tokenWriter: TokenWriter + ): Unit = tokenWriter.writeNumber(value) + } - implicit lazy val javaByteWriter: JsonWriter[java.lang.Byte] = new JsonWriter[java.lang.Byte] { - override def write(value: java.lang.Byte, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) - } + implicit lazy val javaByteWriter: JsonWriter[java.lang.Byte] = + new JsonWriter[java.lang.Byte] { + override def write( + value: java.lang.Byte, + tokenWriter: TokenWriter + ): Unit = tokenWriter.writeNumber(value) + } - implicit lazy val javaShortWriter: JsonWriter[java.lang.Short] = new JsonWriter[java.lang.Short] { - override def write(value: java.lang.Short, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) - } + implicit lazy val javaShortWriter: JsonWriter[java.lang.Short] = + new JsonWriter[java.lang.Short] { + override def write( + value: java.lang.Short, + tokenWriter: TokenWriter + ): Unit = tokenWriter.writeNumber(value) + } - implicit lazy val javaDoubleWriter: JsonWriter[java.lang.Double] = new JsonWriter[java.lang.Double] { - override def write(value: java.lang.Double, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) - } + implicit lazy val javaDoubleWriter: JsonWriter[java.lang.Double] = + new JsonWriter[java.lang.Double] { + override def write( + value: java.lang.Double, + tokenWriter: TokenWriter + ): Unit = tokenWriter.writeNumber(value) + } - implicit lazy val javaFloatWriter: JsonWriter[java.lang.Float] = new JsonWriter[java.lang.Float] { - override def write(value: java.lang.Float, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) - } + implicit lazy val javaFloatWriter: JsonWriter[java.lang.Float] = + new JsonWriter[java.lang.Float] { + override def write( + value: java.lang.Float, + tokenWriter: TokenWriter + ): Unit = tokenWriter.writeNumber(value) + } - implicit lazy val javaBigDecimalWriter: JsonWriter[java.math.BigDecimal] = new JsonWriter[java.math.BigDecimal] { - override def write(value: java.math.BigDecimal, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) - } + implicit lazy val javaBigDecimalWriter: JsonWriter[java.math.BigDecimal] = + new JsonWriter[java.math.BigDecimal] { + override def write( + value: java.math.BigDecimal, + tokenWriter: TokenWriter + ): Unit = tokenWriter.writeNumber(value) + } - implicit lazy val javaBigIntegerWriter: JsonWriter[java.math.BigInteger] = new JsonWriter[java.math.BigInteger] { - override def write(value: java.math.BigInteger, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value) - } + implicit lazy val javaBigIntegerWriter: JsonWriter[java.math.BigInteger] = + new JsonWriter[java.math.BigInteger] { + override def write( + value: java.math.BigInteger, + tokenWriter: TokenWriter + ): Unit = tokenWriter.writeNumber(value) + } - implicit lazy val javaBooleanWriter: JsonWriter[java.lang.Boolean] = new JsonWriter[java.lang.Boolean] { - override def write(value: java.lang.Boolean, tokenWriter: TokenWriter): Unit = tokenWriter.writeBoolean(value) - } + implicit lazy val javaBooleanWriter: JsonWriter[java.lang.Boolean] = + new JsonWriter[java.lang.Boolean] { + override def write( + value: java.lang.Boolean, + tokenWriter: TokenWriter + ): Unit = tokenWriter.writeBoolean(value) + } - implicit lazy val uuidWriter: JsonWriter[java.util.UUID] = new JsonWriter[java.util.UUID] { - override def write(value: java.util.UUID, tokenWriter: TokenWriter): Unit = tokenWriter.writeString(value.toString) - } + implicit lazy val uuidWriter: JsonWriter[java.util.UUID] = + new JsonWriter[java.util.UUID] { + override def write( + value: java.util.UUID, + tokenWriter: TokenWriter + ): Unit = tokenWriter.writeString(value.toString) + } implicit lazy val nullWriter: JsonWriter[Null] = new JsonWriter[Null] { - override def write(value: Null, tokenWriter: TokenWriter): Unit = tokenWriter.writeNull() + override def write(value: Null, tokenWriter: TokenWriter): Unit = + tokenWriter.writeNull() } implicit lazy val instantWriter: JsonWriter[java.time.Instant] = new JsonWriter[java.time.Instant] { - override def write(value: java.time.Instant, tokenWriter: TokenWriter): Unit = + override def write( + value: java.time.Instant, + tokenWriter: TokenWriter + ): Unit = tokenWriter.writeString(value.toString) } implicit lazy val localDateWriter: JsonWriter[java.time.LocalDate] = new JsonWriter[java.time.LocalDate] { - override def write(value: java.time.LocalDate, tokenWriter: TokenWriter): Unit = - tokenWriter.writeString(value.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE)) + override def write( + value: java.time.LocalDate, + tokenWriter: TokenWriter + ): Unit = + tokenWriter.writeString( + value.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE) + ) } implicit lazy val localDateTimeWriter: JsonWriter[java.time.LocalDateTime] = new JsonWriter[java.time.LocalDateTime] { - override def write(value: java.time.LocalDateTime, tokenWriter: TokenWriter): Unit = - tokenWriter.writeString(value.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME)) + override def write( + value: java.time.LocalDateTime, + tokenWriter: TokenWriter + ): Unit = + tokenWriter.writeString( + value.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME) + ) } implicit lazy val offsetDateTimeWriter: JsonWriter[java.time.OffsetDateTime] = new JsonWriter[java.time.OffsetDateTime] { - override def write(value: java.time.OffsetDateTime, tokenWriter: TokenWriter): Unit = - tokenWriter.writeString(value.format(java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME)) + override def write( + value: java.time.OffsetDateTime, + tokenWriter: TokenWriter + ): Unit = + tokenWriter.writeString( + value.format(java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME) + ) } implicit lazy val zonedDateTimeWriter: JsonWriter[java.time.ZonedDateTime] = new JsonWriter[java.time.ZonedDateTime] { - override def write(value: java.time.ZonedDateTime, tokenWriter: TokenWriter): Unit = - tokenWriter.writeString(value.format(java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME)) + override def write( + value: java.time.ZonedDateTime, + tokenWriter: TokenWriter + ): Unit = + tokenWriter.writeString( + value.format(java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME) + ) } } diff --git a/modules/core/src/main/scala/tethys/writers/instances/EitherWriters.scala b/modules/core/src/main/scala/tethys/writers/instances/EitherWriters.scala index d5bb422b..a07bdc00 100644 --- a/modules/core/src/main/scala/tethys/writers/instances/EitherWriters.scala +++ b/modules/core/src/main/scala/tethys/writers/instances/EitherWriters.scala @@ -4,8 +4,15 @@ import tethys.JsonWriter import tethys.writers.tokens.TokenWriter private[tethys] trait EitherWriters { - implicit def eitherWriter[L, R](implicit L: JsonWriter[L], R: JsonWriter[R]): JsonWriter[Either[L, R]] = new JsonWriter[Either[L, R]] { - override def write(name: String, value: Either[L, R], tokenWriter: TokenWriter): Unit = { + implicit def eitherWriter[L, R](implicit + L: JsonWriter[L], + R: JsonWriter[R] + ): JsonWriter[Either[L, R]] = new JsonWriter[Either[L, R]] { + override def write( + name: String, + value: Either[L, R], + tokenWriter: TokenWriter + ): Unit = { value match { case Left(left) => L.write(name, left, tokenWriter) case Right(right) => R.write(name, right, tokenWriter) diff --git a/modules/core/src/main/scala/tethys/writers/instances/IterableWriters.scala b/modules/core/src/main/scala/tethys/writers/instances/IterableWriters.scala index d6b718f4..82f0491e 100644 --- a/modules/core/src/main/scala/tethys/writers/instances/IterableWriters.scala +++ b/modules/core/src/main/scala/tethys/writers/instances/IterableWriters.scala @@ -6,18 +6,21 @@ import tethys.writers.tokens.TokenWriter import scala.language.higherKinds private[tethys] trait IterableWriters extends LowPriorityJsonWriters { - final implicit def iterableWriter[A, C[X] <: Iterable[X]](implicit valueWriter: JsonWriter[A]): JsonWriter[C[A]] = new IterableWriter[A, C](valueWriter) { + final implicit def iterableWriter[A, C[X] <: Iterable[X]](implicit + valueWriter: JsonWriter[A] + ): JsonWriter[C[A]] = new IterableWriter[A, C](valueWriter) { override def iterator(c: C[A]): Iterator[A] = c.iterator } - abstract class IterableWriter[A, C[_]](valueWriter: JsonWriter[A]) extends JsonWriter[C[A]] { + abstract class IterableWriter[A, C[_]](valueWriter: JsonWriter[A]) + extends JsonWriter[C[A]] { def iterator(c: C[A]): Iterator[A] override def write(value: C[A], tokenWriter: TokenWriter): Unit = { tokenWriter.writeArrayStart() val valueIterator = iterator(value) - while(valueIterator.hasNext) { + while (valueIterator.hasNext) { val v = valueIterator.next() valueWriter.write(v, tokenWriter) } @@ -25,4 +28,4 @@ private[tethys] trait IterableWriters extends LowPriorityJsonWriters { tokenWriter.writeArrayEnd() } } -} \ No newline at end of file +} diff --git a/modules/core/src/main/scala/tethys/writers/instances/LowPriorityJsonWriters.scala b/modules/core/src/main/scala/tethys/writers/instances/LowPriorityJsonWriters.scala index 02c13101..0471fcd2 100644 --- a/modules/core/src/main/scala/tethys/writers/instances/LowPriorityJsonWriters.scala +++ b/modules/core/src/main/scala/tethys/writers/instances/LowPriorityJsonWriters.scala @@ -4,7 +4,9 @@ import tethys._ import tethys.commons.LowPriorityInstance private[tethys] trait LowPriorityJsonWriters { - implicit final def lowPriorityWriter[A](implicit lowPriorityInstance: LowPriorityInstance[JsonObjectWriter[A]]): JsonWriter[A] = { + implicit final def lowPriorityWriter[A](implicit + lowPriorityInstance: LowPriorityInstance[JsonObjectWriter[A]] + ): JsonWriter[A] = { lowPriorityInstance.instance } -} \ No newline at end of file +} diff --git a/modules/core/src/main/scala/tethys/writers/instances/MapWriters.scala b/modules/core/src/main/scala/tethys/writers/instances/MapWriters.scala index fcc8dac7..89537434 100644 --- a/modules/core/src/main/scala/tethys/writers/instances/MapWriters.scala +++ b/modules/core/src/main/scala/tethys/writers/instances/MapWriters.scala @@ -5,10 +5,16 @@ import tethys.writers.KeyWriter import tethys.writers.tokens.TokenWriter private[tethys] trait MapWriters extends IterableWriters { - implicit def mapWriter[K, A](implicit keyWriter: KeyWriter[K], valueWriter: JsonWriter[A]): JsonObjectWriter[Map[K, A]] = new JsonObjectWriter[Map[K, A]] { - override def writeValues(value: Map[K, A], tokenWriter: TokenWriter): Unit = { + implicit def mapWriter[K, A](implicit + keyWriter: KeyWriter[K], + valueWriter: JsonWriter[A] + ): JsonObjectWriter[Map[K, A]] = new JsonObjectWriter[Map[K, A]] { + override def writeValues( + value: Map[K, A], + tokenWriter: TokenWriter + ): Unit = { val valueIterator = value.iterator - while(valueIterator.hasNext) { + while (valueIterator.hasNext) { val v = valueIterator.next() tokenWriter.writeFieldName(keyWriter.toKey(v._1)) valueWriter.write(v._2, tokenWriter) diff --git a/modules/core/src/main/scala/tethys/writers/instances/OptionWriters.scala b/modules/core/src/main/scala/tethys/writers/instances/OptionWriters.scala index 0aa7fc15..3047316e 100644 --- a/modules/core/src/main/scala/tethys/writers/instances/OptionWriters.scala +++ b/modules/core/src/main/scala/tethys/writers/instances/OptionWriters.scala @@ -4,27 +4,41 @@ import tethys.JsonWriter import tethys.writers.tokens.TokenWriter private[tethys] trait OptionWriters extends MapWriters { - implicit lazy val noneWriter: JsonWriter[None.type] = new JsonWriter[None.type] { - override def write(name: String, value: None.type, tokenWriter: TokenWriter): Unit = () - override def write(value: None.type, tokenWriter: TokenWriter): Unit = tokenWriter.writeNull() - } + implicit lazy val noneWriter: JsonWriter[None.type] = + new JsonWriter[None.type] { + override def write( + name: String, + value: None.type, + tokenWriter: TokenWriter + ): Unit = () + override def write(value: None.type, tokenWriter: TokenWriter): Unit = + tokenWriter.writeNull() + } - implicit def someWriter[A](implicit jsonWriter: JsonWriter[A]): JsonWriter[Some[A]] = new JsonWriter[Some[A]] { + implicit def someWriter[A](implicit + jsonWriter: JsonWriter[A] + ): JsonWriter[Some[A]] = new JsonWriter[Some[A]] { override def write(value: Some[A], tokenWriter: TokenWriter): Unit = { jsonWriter.write(value.get, tokenWriter) } } - implicit def optionalWriter[A](implicit valueWriter: JsonWriter[A]): JsonWriter[Option[A]] = new JsonWriter[Option[A]] { + implicit def optionalWriter[A](implicit + valueWriter: JsonWriter[A] + ): JsonWriter[Option[A]] = new JsonWriter[Option[A]] { - override def write(name: String, value: Option[A], tokenWriter: TokenWriter): Unit = { - if(value.nonEmpty) { + override def write( + name: String, + value: Option[A], + tokenWriter: TokenWriter + ): Unit = { + if (value.nonEmpty) { valueWriter.write(name, value.get, tokenWriter) } } override def write(value: Option[A], tokenWriter: TokenWriter): Unit = { - if(value.isEmpty) tokenWriter.writeNull() + if (value.isEmpty) tokenWriter.writeNull() else valueWriter.write(value.get, tokenWriter) } } diff --git a/modules/core/src/main/scala/tethys/writers/instances/SimpleJsonObjectWriter.scala b/modules/core/src/main/scala/tethys/writers/instances/SimpleJsonObjectWriter.scala index 5003c168..f780339b 100644 --- a/modules/core/src/main/scala/tethys/writers/instances/SimpleJsonObjectWriter.scala +++ b/modules/core/src/main/scala/tethys/writers/instances/SimpleJsonObjectWriter.scala @@ -6,11 +6,12 @@ import tethys.writers.tokens.TokenWriter import scala.collection.immutable -class SimpleJsonObjectWriter[A](val fields: Seq[JsonFieldObjectField[A, _]]) extends JsonObjectWriter[A] { +class SimpleJsonObjectWriter[A](val fields: Seq[JsonFieldObjectField[A, _]]) + extends JsonObjectWriter[A] { override def writeValues(value: A, tokenWriter: TokenWriter): Unit = { val it = fields.iterator - while(it.hasNext) { + while (it.hasNext) { it.next() match { case JsonFieldObjectField(name, fun, jsonWriter) => jsonWriter.write(name, fun.apply(value), tokenWriter) @@ -18,20 +19,34 @@ class SimpleJsonObjectWriter[A](val fields: Seq[JsonFieldObjectField[A, _]]) ext } } - def addField[B](name: String)(fun: A => B)(implicit jsonWriter: JsonWriter[B]): SimpleJsonObjectWriter[A] = { - SimpleJsonObjectWriter(fields :+ JsonFieldObjectField[A, B](name, fun, jsonWriter)) + def addField[B](name: String)( + fun: A => B + )(implicit jsonWriter: JsonWriter[B]): SimpleJsonObjectWriter[A] = { + SimpleJsonObjectWriter( + fields :+ JsonFieldObjectField[A, B](name, fun, jsonWriter) + ) } - def ++(that: SimpleJsonObjectWriter[A]): SimpleJsonObjectWriter[A] = concat(that) + def ++(that: SimpleJsonObjectWriter[A]): SimpleJsonObjectWriter[A] = concat( + that + ) - def concat(that: SimpleJsonObjectWriter[A]): SimpleJsonObjectWriter[A] = SimpleJsonObjectWriter(this.fields ++ that.fields) + def concat(that: SimpleJsonObjectWriter[A]): SimpleJsonObjectWriter[A] = + SimpleJsonObjectWriter(this.fields ++ that.fields) } object SimpleJsonObjectWriter { - def apply[A]: SimpleJsonObjectWriter[A] = new SimpleJsonObjectWriter[A](immutable.Queue.empty) + def apply[A]: SimpleJsonObjectWriter[A] = + new SimpleJsonObjectWriter[A](immutable.Queue.empty) - def apply[A](fields: Seq[JsonFieldObjectField[A, _]]): SimpleJsonObjectWriter[A] = new SimpleJsonObjectWriter[A](fields) + def apply[A]( + fields: Seq[JsonFieldObjectField[A, _]] + ): SimpleJsonObjectWriter[A] = new SimpleJsonObjectWriter[A](fields) - case class JsonFieldObjectField[A, B](name: String, fun: A => B, jsonWriter: JsonWriter[B]) + case class JsonFieldObjectField[A, B]( + name: String, + fun: A => B, + jsonWriter: JsonWriter[B] + ) } diff --git a/modules/core/src/main/scala/tethys/writers/tokens/SimpleTokenWriter.scala b/modules/core/src/main/scala/tethys/writers/tokens/SimpleTokenWriter.scala index c70b3142..e72be059 100644 --- a/modules/core/src/main/scala/tethys/writers/tokens/SimpleTokenWriter.scala +++ b/modules/core/src/main/scala/tethys/writers/tokens/SimpleTokenWriter.scala @@ -10,39 +10,69 @@ import scala.collection.mutable class SimpleTokenWriter extends TokenWriter { val tokens: mutable.ArrayBuffer[TokenNode] = mutable.ArrayBuffer.empty - override def writeArrayStart(): SimpleTokenWriter.this.type = append(ArrayStartNode) + override def writeArrayStart(): SimpleTokenWriter.this.type = append( + ArrayStartNode + ) - override def writeArrayEnd(): SimpleTokenWriter.this.type = append(ArrayEndNode) + override def writeArrayEnd(): SimpleTokenWriter.this.type = append( + ArrayEndNode + ) - override def writeObjectStart(): SimpleTokenWriter.this.type = append(ObjectStartNode) + override def writeObjectStart(): SimpleTokenWriter.this.type = append( + ObjectStartNode + ) - override def writeObjectEnd(): SimpleTokenWriter.this.type = append(ObjectEndNode) + override def writeObjectEnd(): SimpleTokenWriter.this.type = append( + ObjectEndNode + ) - override def writeFieldName(name: String): SimpleTokenWriter.this.type = append(FieldNameNode(name)) + override def writeFieldName(name: String): SimpleTokenWriter.this.type = + append(FieldNameNode(name)) - override def writeString(v: String): SimpleTokenWriter.this.type = append(StringValueNode(v)) + override def writeString(v: String): SimpleTokenWriter.this.type = append( + StringValueNode(v) + ) - override def writeNumber(v: Byte): SimpleTokenWriter.this.type = append(ByteValueNode(v)) + override def writeNumber(v: Byte): SimpleTokenWriter.this.type = append( + ByteValueNode(v) + ) - override def writeNumber(v: Short): SimpleTokenWriter.this.type = append(ShortValueNode(v)) + override def writeNumber(v: Short): SimpleTokenWriter.this.type = append( + ShortValueNode(v) + ) - override def writeNumber(v: Int): SimpleTokenWriter.this.type = append(IntValueNode(v)) + override def writeNumber(v: Int): SimpleTokenWriter.this.type = append( + IntValueNode(v) + ) - override def writeNumber(v: Long): SimpleTokenWriter.this.type = append(LongValueNode(v)) + override def writeNumber(v: Long): SimpleTokenWriter.this.type = append( + LongValueNode(v) + ) - override def writeNumber(v: BigInt): SimpleTokenWriter.this.type = append(NumberValueNode(v)) + override def writeNumber(v: BigInt): SimpleTokenWriter.this.type = append( + NumberValueNode(v) + ) - override def writeNumber(v: Double): SimpleTokenWriter.this.type = append(DoubleValueNode(v)) + override def writeNumber(v: Double): SimpleTokenWriter.this.type = append( + DoubleValueNode(v) + ) - override def writeNumber(v: Float): SimpleTokenWriter.this.type = append(FloatValueNode(v)) + override def writeNumber(v: Float): SimpleTokenWriter.this.type = append( + FloatValueNode(v) + ) - override def writeNumber(v: BigDecimal): SimpleTokenWriter.this.type = append(NumberValueNode(v)) + override def writeNumber(v: BigDecimal): SimpleTokenWriter.this.type = append( + NumberValueNode(v) + ) - override def writeBoolean(v: Boolean): SimpleTokenWriter.this.type = append(BooleanValueNode(v)) + override def writeBoolean(v: Boolean): SimpleTokenWriter.this.type = append( + BooleanValueNode(v) + ) override def writeNull(): SimpleTokenWriter.this.type = append(NullValueNode) - override def writeRawJson(json: String): SimpleTokenWriter.this.type = throw new UnsupportedOperationException("SimpleTokenWriter.writeRawJson") + override def writeRawJson(json: String): SimpleTokenWriter.this.type = + throw new UnsupportedOperationException("SimpleTokenWriter.writeRawJson") override def close(): Unit = () @@ -53,7 +83,9 @@ class SimpleTokenWriter extends TokenWriter { this } - def withRawJsonSupport(implicit producer: TokenIteratorProducer): SimpleTokenWriter = new SimpleTokenWriter { + def withRawJsonSupport(implicit + producer: TokenIteratorProducer + ): SimpleTokenWriter = new SimpleTokenWriter { import tethys._ override def writeRawJson(json: String): this.type = { val tokenIterator = json.toTokenIterator.fold(throw _, identity) diff --git a/modules/core/src/main/scala/tethys/writers/tokens/TokenWriter.scala b/modules/core/src/main/scala/tethys/writers/tokens/TokenWriter.scala index c8b09755..d1172d0a 100644 --- a/modules/core/src/main/scala/tethys/writers/tokens/TokenWriter.scala +++ b/modules/core/src/main/scala/tethys/writers/tokens/TokenWriter.scala @@ -31,16 +31,16 @@ trait TokenWriter { def writeRawNumber(n: Number): this.type = n match { case jbd: java.math.BigDecimal => writeNumber(BigDecimal(jbd)) - case jint: java.lang.Integer => writeNumber(jint.intValue()) - case jbyte: java.lang.Byte => writeNumber(jbyte.longValue()) - case jshort: java.lang.Short => writeNumber(jshort.longValue()) - case jlong: java.lang.Long => writeNumber(jlong.longValue()) + case jint: java.lang.Integer => writeNumber(jint.intValue()) + case jbyte: java.lang.Byte => writeNumber(jbyte.longValue()) + case jshort: java.lang.Short => writeNumber(jshort.longValue()) + case jlong: java.lang.Long => writeNumber(jlong.longValue()) case jbi: java.math.BigInteger => writeNumber(BigInt(jbi)) - case jfloat: java.lang.Float => writeNumber(jfloat.floatValue()) + case jfloat: java.lang.Float => writeNumber(jfloat.floatValue()) case jdouble: java.lang.Double => writeNumber(jdouble.doubleValue()) - case bd: BigDecimal => writeNumber(bd) - case bi: BigInt => writeNumber(bi) - case num => writeNumber(num.doubleValue()) + case bd: BigDecimal => writeNumber(bd) + case bi: BigInt => writeNumber(bi) + case num => writeNumber(num.doubleValue()) } def writeBoolean(v: Boolean): this.type diff --git a/modules/core/src/test/scala-3/tethys/derivation/ADTWithWrongType.scala b/modules/core/src/test/scala-3/tethys/derivation/ADTWithWrongType.scala index ff242e00..66aa5d9e 100644 --- a/modules/core/src/test/scala-3/tethys/derivation/ADTWithWrongType.scala +++ b/modules/core/src/test/scala-3/tethys/derivation/ADTWithWrongType.scala @@ -6,6 +6,7 @@ object ADTWithWrongType { case class ADTWithWrongTypeA[A](a: A) extends ADTWithWrongType[A] - case class ADTWithWrongTypeB[A, B](a: A, b: ADTWithWrongType[B]) extends ADTWithWrongType[A] + case class ADTWithWrongTypeB[A, B](a: A, b: ADTWithWrongType[B]) + extends ADTWithWrongType[A] } diff --git a/modules/core/src/test/scala-3/tethys/derivation/DerivationSpec.scala b/modules/core/src/test/scala-3/tethys/derivation/DerivationSpec.scala index ff17fb5d..981dac19 100644 --- a/modules/core/src/test/scala-3/tethys/derivation/DerivationSpec.scala +++ b/modules/core/src/test/scala-3/tethys/derivation/DerivationSpec.scala @@ -21,7 +21,13 @@ class DerivationSpec extends AnyFlatSpec with Matchers { } it should "compile and correctly write and read product" in { - case class Person(id: Int, name: String, phone: Option[String], default: String = "") derives JsonObjectWriter, JsonReader + case class Person( + id: Int, + name: String, + phone: Option[String], + default: String = "" + ) derives JsonObjectWriter, + JsonReader case class Wrapper(person: Person) derives JsonObjectWriter, JsonReader @@ -35,7 +41,11 @@ class DerivationSpec extends AnyFlatSpec with Matchers { "person" -> obj("id" -> 3, "name" -> "Parker", "default" -> "abc") ) - read[Person](obj("id" -> 1, "name" -> "abc")) shouldBe Person(1, "abc", None) + read[Person](obj("id" -> 1, "name" -> "abc")) shouldBe Person( + 1, + "abc", + None + ) read[Person]( obj( @@ -61,7 +71,6 @@ class DerivationSpec extends AnyFlatSpec with Matchers { case class C(c: String) extends A derives JsonObjectWriter - (B(2, "abc"): A).asTokenList shouldBe obj( "b" -> 2, "i" -> "abc" @@ -120,7 +129,8 @@ class DerivationSpec extends AnyFlatSpec with Matchers { it should "correctly read case classes with default parameters" in { object Mod { - case class WithOpt(x: Int, y: Option[String] = Some("default")) derives JsonReader + case class WithOpt(x: Int, y: Option[String] = Some("default")) + derives JsonReader } read[Mod.WithOpt](obj("x" -> 5)) shouldBe Mod.WithOpt(5) @@ -130,19 +140,23 @@ class DerivationSpec extends AnyFlatSpec with Matchers { case class WithArg[A](x: Int, y: Option[A] = None) derives JsonReader read[WithArg[Int]](obj("x" -> 5)) shouldBe WithArg[Int](5) - read[WithArg[String]](obj("x" -> 5, "y" -> "lool")) shouldBe WithArg[String](5, Some("lool")) + read[WithArg[String]](obj("x" -> 5, "y" -> "lool")) shouldBe WithArg[ + String + ](5, Some("lool")) } it should "write/read sum types with provided json discriminator" in { enum Disc derives StringEnumJsonWriter, StringEnumJsonReader: case A, B - sealed trait Choose(@selector val discriminator: Disc) derives JsonObjectWriter, JsonReader + sealed trait Choose(@selector val discriminator: Disc) + derives JsonObjectWriter, + JsonReader object Choose: case class AA() extends Choose(Disc.A) case class BB() extends Choose(Disc.B) - + (Choose.AA(): Choose).asTokenList shouldBe obj("discriminator" -> "A") (Choose.BB(): Choose).asTokenList shouldBe obj("discriminator" -> "B") @@ -151,7 +165,9 @@ class DerivationSpec extends AnyFlatSpec with Matchers { } it should "write/read sum types with provided json discriminator of simple type" in { - enum Choose(@selector val discriminator: Int) derives JsonObjectWriter, JsonReader: + enum Choose(@selector val discriminator: Int) + derives JsonObjectWriter, + JsonReader: case AA() extends Choose(0) case BB() extends Choose(1) @@ -177,23 +193,25 @@ class DerivationSpec extends AnyFlatSpec with Matchers { | |""" shouldNot compile - } it should "derive readers for simple case class hierarchy" in { implicit val dReader: JsonReader[D] = JsonReader.derived[D] implicit val cReader: JsonReader[C] = JsonReader.derived[C] - implicit val jsonTreeTestDataReader: JsonReader[JsonTreeTestData] = JsonReader.derived[JsonTreeTestData] + implicit val jsonTreeTestDataReader: JsonReader[JsonTreeTestData] = + JsonReader.derived[JsonTreeTestData] - read[JsonTreeTestData](obj( - "a" -> 1, - "b" -> true, - "c" -> obj( - "d" -> obj( - "a" -> 2 + read[JsonTreeTestData]( + obj( + "a" -> 1, + "b" -> true, + "c" -> obj( + "d" -> obj( + "a" -> 2 + ) ) ) - )) shouldBe JsonTreeTestData( + ) shouldBe JsonTreeTestData( a = 1, b = true, c = C(D(2)) @@ -203,198 +221,244 @@ class DerivationSpec extends AnyFlatSpec with Matchers { it should "derive reader for recursive type" in { given JsonReader[RecursiveType] = JsonReader.derived[RecursiveType] - read[RecursiveType](obj( - "a" -> 1, - "children" -> arr( - obj( - "a" -> 2, - "children" -> arr() - ), - obj( - "a" -> 3, - "children" -> arr() + read[RecursiveType]( + obj( + "a" -> 1, + "children" -> arr( + obj( + "a" -> 2, + "children" -> arr() + ), + obj( + "a" -> 3, + "children" -> arr() + ) ) ) - )) shouldBe RecursiveType(1, Seq(RecursiveType(2), RecursiveType(3))) + ) shouldBe RecursiveType(1, Seq(RecursiveType(2), RecursiveType(3))) } it should "derive reader for A => B => A cycle" in { - implicit lazy val testReader1: JsonReader[ComplexRecursionA] = JsonReader.derived[ComplexRecursionA] - implicit lazy val testReader2: JsonReader[ComplexRecursionB] = JsonReader.derived[ComplexRecursionB] + implicit lazy val testReader1: JsonReader[ComplexRecursionA] = + JsonReader.derived[ComplexRecursionA] + implicit lazy val testReader2: JsonReader[ComplexRecursionB] = + JsonReader.derived[ComplexRecursionB] - read[ComplexRecursionA](obj( - "a" -> 1, - "b" -> obj( - "b" -> 2, - "a" -> obj( - "a" -> 3 + read[ComplexRecursionA]( + obj( + "a" -> 1, + "b" -> obj( + "b" -> 2, + "a" -> obj( + "a" -> 3 + ) ) ) - )) shouldBe ComplexRecursionA(1, Some(ComplexRecursionB(2, ComplexRecursionA(3, None)))) + ) shouldBe ComplexRecursionA( + 1, + Some(ComplexRecursionB(2, ComplexRecursionA(3, None))) + ) } it should "derive reader for extract as description" in { given JsonReader[SimpleType] = JsonReader.derived[SimpleType] { ReaderBuilder[SimpleType] - .extract(_.i).as[Option[Int]](_.getOrElse(2)) + .extract(_.i) + .as[Option[Int]](_.getOrElse(2)) } + read[SimpleType]( + obj( + "i" -> 1, + "s" -> "str", + "d" -> 1.0 + ) + ) shouldBe SimpleType(1, "str", 1.0) - read[SimpleType](obj( - "i" -> 1, - "s" -> "str", - "d" -> 1.0 - )) shouldBe SimpleType(1, "str", 1.0) - - read[SimpleType](obj( - "s" -> "str", - "d" -> 1.0 - )) shouldBe SimpleType(2, "str", 1.0) + read[SimpleType]( + obj( + "s" -> "str", + "d" -> 1.0 + ) + ) shouldBe SimpleType(2, "str", 1.0) } - it should "work for deprecated ReaderBuilder" in { import tethys.derivation.builder.ReaderBuilder given JsonReader[SimpleType] = JsonReader.derived[SimpleType] { ReaderBuilder[SimpleType] - .extract(_.i).as[Option[Int]](_.getOrElse(2)) + .extract(_.i) + .as[Option[Int]](_.getOrElse(2)) } + read[SimpleType]( + obj( + "i" -> 1, + "s" -> "str", + "d" -> 1.0 + ) + ) shouldBe SimpleType(1, "str", 1.0) - read[SimpleType](obj( - "i" -> 1, - "s" -> "str", - "d" -> 1.0 - )) shouldBe SimpleType(1, "str", 1.0) - - read[SimpleType](obj( - "s" -> "str", - "d" -> 1.0 - )) shouldBe SimpleType(2, "str", 1.0) + read[SimpleType]( + obj( + "s" -> "str", + "d" -> 1.0 + ) + ) shouldBe SimpleType(2, "str", 1.0) } - - it should "derive reader for extract from description" in { given JsonReader[SimpleType] = JsonReader.derived { ReaderBuilder[SimpleType] - .extract(_.i).from(_.s).and(_.d).apply((_, _) => 2) + .extract(_.i) + .from(_.s) + .and(_.d) + .apply((_, _) => 2) } - read[SimpleType](obj( - "i" -> 1, - "s" -> "str", - "d" -> 1.0 - )) shouldBe SimpleType(2, "str", 1.0) + read[SimpleType]( + obj( + "i" -> 1, + "s" -> "str", + "d" -> 1.0 + ) + ) shouldBe SimpleType(2, "str", 1.0) - read[SimpleType](obj( - "s" -> "str", - "d" -> 1.0 - )) shouldBe SimpleType(2, "str", 1.0) + read[SimpleType]( + obj( + "s" -> "str", + "d" -> 1.0 + ) + ) shouldBe SimpleType(2, "str", 1.0) } - it should "derive reader for extract from description with synthetic field" in { given JsonReader[SimpleType] = JsonReader.derived[SimpleType] { ReaderBuilder[SimpleType] - .extract(_.i).from(_.d).and[Double]("e")((d, e) => (d + e).toInt) + .extract(_.i) + .from(_.d) + .and[Double]("e")((d, e) => (d + e).toInt) } - read[SimpleType](obj( + read[SimpleType]( + obj( "i" -> 1, "s" -> "str", "d" -> 1.0, "e" -> 2.0 - )) shouldBe SimpleType(3, "str", 1.0) + ) + ) shouldBe SimpleType(3, "str", 1.0) - read[SimpleType](obj( + read[SimpleType]( + obj( "s" -> "str", "d" -> 1.0, "e" -> 3.0 - )) shouldBe SimpleType(4, "str", 1.0) + ) + ) shouldBe SimpleType(4, "str", 1.0) } - it should "extract and build product" in { + it should "extract and build product" in { case class Person(name: String, age: Int) case class Wrapper(person: Person) derives JsonReader inline given ReaderBuilder[Wrapper] = ReaderBuilder[Wrapper] - .extract(_.person).from[String]("name").and[Int]("age").product + .extract(_.person) + .from[String]("name") + .and[Int]("age") + .product - - read[Wrapper](obj( - "name" -> "str", - "age" -> 2 - )) shouldBe Wrapper(Person("str", 2)) + read[Wrapper]( + obj( + "name" -> "str", + "age" -> 2 + ) + ) shouldBe Wrapper(Person("str", 2)) } - it should "derive reader for extract reader from description" in { - given JsonReader[SimpleTypeWithAny] = JsonReader.derived[SimpleTypeWithAny] { - ReaderBuilder[SimpleTypeWithAny] - .extractReader(_.any).from(_.d) { - case 1.0 => JsonReader[String] - case 2.0 => JsonReader[Int] - } - } + given JsonReader[SimpleTypeWithAny] = + JsonReader.derived[SimpleTypeWithAny] { + ReaderBuilder[SimpleTypeWithAny] + .extractReader(_.any) + .from(_.d) { + case 1.0 => JsonReader[String] + case 2.0 => JsonReader[Int] + } + } - read[SimpleTypeWithAny](obj( - "i" -> 1, - "s" -> "str", - "d" -> 1.0, - "any" -> "anyStr" - )) shouldBe SimpleTypeWithAny(1, "str", 1.0, "anyStr") + read[SimpleTypeWithAny]( + obj( + "i" -> 1, + "s" -> "str", + "d" -> 1.0, + "any" -> "anyStr" + ) + ) shouldBe SimpleTypeWithAny(1, "str", 1.0, "anyStr") - read[SimpleTypeWithAny](obj( - "i" -> 1, - "s" -> "str", - "d" -> 2.0, - "any" -> 2 - )) shouldBe SimpleTypeWithAny(1, "str", 2.0, 2) + read[SimpleTypeWithAny]( + obj( + "i" -> 1, + "s" -> "str", + "d" -> 2.0, + "any" -> 2 + ) + ) shouldBe SimpleTypeWithAny(1, "str", 2.0, 2) } it should "derive reader for complex extraction case" in { - given JsonReader[SimpleTypeWithAny] = JsonReader.derived[SimpleTypeWithAny] { - ReaderBuilder[SimpleTypeWithAny] - .extractReader(_.any).from(_.i) { - case 1 => JsonReader[String] - case 2 => JsonReader[Int] - case _ => JsonReader[Option[Boolean]] - } - .extract(_.i).from(_.d).and[Int]("e")((d, e) => d.toInt + e) - .extract(_.d).as[Option[Double]](_.getOrElse(1.0)) - } - - read[SimpleTypeWithAny](obj( - "s" -> "str", - "d" -> 1.0, - "e" -> 0, - "any" -> "anyStr" - )) shouldBe SimpleTypeWithAny(1, "str", 1.0, "anyStr") + given JsonReader[SimpleTypeWithAny] = + JsonReader.derived[SimpleTypeWithAny] { + ReaderBuilder[SimpleTypeWithAny] + .extractReader(_.any) + .from(_.i) { + case 1 => JsonReader[String] + case 2 => JsonReader[Int] + case _ => JsonReader[Option[Boolean]] + } + .extract(_.i) + .from(_.d) + .and[Int]("e")((d, e) => d.toInt + e) + .extract(_.d) + .as[Option[Double]](_.getOrElse(1.0)) + } + read[SimpleTypeWithAny]( + obj( + "s" -> "str", + "d" -> 1.0, + "e" -> 0, + "any" -> "anyStr" + ) + ) shouldBe SimpleTypeWithAny(1, "str", 1.0, "anyStr") - read[SimpleTypeWithAny](obj( - "s" -> "str", - "d" -> 1.0, - "e" -> 1, - "any" -> 3 - )) shouldBe SimpleTypeWithAny(2, "str", 1.0, 3) + read[SimpleTypeWithAny]( + obj( + "s" -> "str", + "d" -> 1.0, + "e" -> 1, + "any" -> 3 + ) + ) shouldBe SimpleTypeWithAny(2, "str", 1.0, 3) - read[SimpleTypeWithAny](obj( - "s" -> "str", - "d" -> 1.0, - "e" -> 2, - "any" -> true - )) shouldBe SimpleTypeWithAny(3, "str", 1.0, Some(true)) + read[SimpleTypeWithAny]( + obj( + "s" -> "str", + "d" -> 1.0, + "e" -> 2, + "any" -> true + ) + ) shouldBe SimpleTypeWithAny(3, "str", 1.0, Some(true)) - read[SimpleTypeWithAny](obj( - "s" -> "str", - "d" -> 1.0, - "e" -> 2 - )) shouldBe SimpleTypeWithAny(3, "str", 1.0, None) + read[SimpleTypeWithAny]( + obj( + "s" -> "str", + "d" -> 1.0, + "e" -> 2 + ) + ) shouldBe SimpleTypeWithAny(3, "str", 1.0, None) } - it should "derive reader for fieldStyle from description" in { given JsonReader[CamelCaseNames] = JsonReader.derived[CamelCaseNames] { @@ -402,11 +466,13 @@ class DerivationSpec extends AnyFlatSpec with Matchers { .fieldStyle(FieldStyle.LowerSnakeCase) } - read[CamelCaseNames](obj( - "some_param" -> 1, - "id_param" -> 2, - "simple" -> 3 - )) shouldBe CamelCaseNames( + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "id_param" -> 2, + "simple" -> 3 + ) + ) shouldBe CamelCaseNames( someParam = 1, IDParam = 2, simple = 3 @@ -419,18 +485,19 @@ class DerivationSpec extends AnyFlatSpec with Matchers { .fieldStyle(FieldStyle.Capitalize) } - read[CamelCaseNames](obj( - "SomeParam" -> 1, - "IDParam" -> 2, - "Simple" -> 3 - )) shouldBe CamelCaseNames( + read[CamelCaseNames]( + obj( + "SomeParam" -> 1, + "IDParam" -> 2, + "Simple" -> 3 + ) + ) shouldBe CamelCaseNames( someParam = 1, IDParam = 2, simple = 3 ) } - it should "derive reader for reader config" in { given JsonReader[CamelCaseNames] = JsonReader.derived[CamelCaseNames]( ReaderBuilder[CamelCaseNames] @@ -438,54 +505,59 @@ class DerivationSpec extends AnyFlatSpec with Matchers { .strict ) - read[CamelCaseNames](obj( - "some_param" -> 1, - "id_param" -> 2, - "simple" -> 3 - )) shouldBe CamelCaseNames( + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "id_param" -> 2, + "simple" -> 3 + ) + ) shouldBe CamelCaseNames( someParam = 1, IDParam = 2, simple = 3 ) (the[ReaderError] thrownBy { - read[CamelCaseNames](obj( - "some_param" -> 1, - "not_id_param" -> 2, - "simple" -> 3 - )) + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "not_id_param" -> 2, + "simple" -> 3 + ) + ) }).getMessage shouldBe "Illegal json at '[ROOT]': unexpected field 'not_id_param', expected one of 'some_param', 'id_param', 'simple'" } - it should "derive reader for reader config from builder" in { - implicit val reader: JsonReader[CamelCaseNames] = JsonReader.derived[CamelCaseNames]( - ReaderBuilder[CamelCaseNames] - .strict - .fieldStyle(FieldStyle.LowerSnakeCase) - ) + implicit val reader: JsonReader[CamelCaseNames] = + JsonReader.derived[CamelCaseNames]( + ReaderBuilder[CamelCaseNames].strict + .fieldStyle(FieldStyle.LowerSnakeCase) + ) - read[CamelCaseNames](obj( - "some_param" -> 1, - "id_param" -> 2, - "simple" -> 3 - )) shouldBe CamelCaseNames( + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "id_param" -> 2, + "simple" -> 3 + ) + ) shouldBe CamelCaseNames( someParam = 1, IDParam = 2, simple = 3 ) (the[ReaderError] thrownBy { - read[CamelCaseNames](obj( - "some_param" -> 1, - "not_id_param" -> 2, - "simple" -> 3 - )) + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "not_id_param" -> 2, + "simple" -> 3 + ) + ) }).getMessage shouldBe "Illegal json at '[ROOT]': unexpected field 'not_id_param', expected one of 'some_param', 'id_param', 'simple'" } - - it should "generate proper writer from WriterDescription" in { def freeVariable: String = "e" @@ -496,7 +568,8 @@ class DerivationSpec extends AnyFlatSpec with Matchers { implicit val testWriter: JsonWriter[JsonTreeTestData] = JsonWriter.derived { WriterBuilder[JsonTreeTestData] .remove(_.b) - .update(_.a).fromRoot(d => d.a.toDouble + d.c.d.a) + .update(_.a) + .fromRoot(d => d.a.toDouble + d.c.d.a) .update(_.c)(_.d) .add("d")(_.a * 2) .add(freeVariable)(_.b) @@ -522,7 +595,8 @@ class DerivationSpec extends AnyFlatSpec with Matchers { implicit val testWriter: JsonWriter[JsonTreeTestData] = JsonWriter.derived { WriterBuilder[JsonTreeTestData] .remove(_.b) - .update(_.a).fromRoot(d => d.a.toDouble + d.c.d.a) + .update(_.a) + .fromRoot(d => d.a.toDouble + d.c.d.a) .update(_.c)(_.d) .add("d")(_.a * 2) .add(freeVariable)(_.b) @@ -537,14 +611,13 @@ class DerivationSpec extends AnyFlatSpec with Matchers { ) } - it should "derive writer for update partial" in { inline given WriterBuilder[D] = WriterBuilder[D] .update(_.a) { - case 1 => "uno!" - case 2 => 1 + case 1 => "uno!" + case 2 => 1 case v if v > 0 => v * 2 - case _ => throw new IllegalArgumentException("Wrong value!") + case _ => throw new IllegalArgumentException("Wrong value!") } given JsonWriter[D] = JsonWriter.derived @@ -561,13 +634,14 @@ class DerivationSpec extends AnyFlatSpec with Matchers { it should "derive writer for update partial from root" in { implicit val partialWriter: JsonWriter[D] = JsonWriter.derived[D] { WriterBuilder[D] - .update(_.a).fromRoot { + .update(_.a) + .fromRoot { case d if d.a == 1 => "uno!" case d if d.a == 2 => 1 - case d if d.a > 0 => d.a * 2 + case d if d.a > 0 => d.a * 2 case _ => throw new IllegalArgumentException("Wrong value!") } - } + } D(1).asTokenList shouldBe obj("a" -> "uno!") D(2).asTokenList shouldBe obj("a" -> 1) @@ -583,7 +657,8 @@ class DerivationSpec extends AnyFlatSpec with Matchers { } it should "derive writer for recursive type" in { - implicit lazy val testWriter: JsonWriter[RecursiveType] = JsonWriter.derived[RecursiveType] + implicit lazy val testWriter: JsonWriter[RecursiveType] = + JsonWriter.derived[RecursiveType] RecursiveType(1, Seq(RecursiveType(2))).asTokenList shouldBe obj( "a" -> 1, @@ -597,10 +672,15 @@ class DerivationSpec extends AnyFlatSpec with Matchers { } it should "derive writer for A => B => A cycle" in { - implicit lazy val testWriter1: JsonWriter[ComplexRecursionA] = JsonWriter.derived[ComplexRecursionA] - implicit lazy val testWriter2: JsonWriter[ComplexRecursionB] = JsonWriter.derived[ComplexRecursionB] - - ComplexRecursionA(1, Some(ComplexRecursionB(2, ComplexRecursionA(3, None)))).asTokenList shouldBe obj( + implicit lazy val testWriter1: JsonWriter[ComplexRecursionA] = + JsonWriter.derived[ComplexRecursionA] + implicit lazy val testWriter2: JsonWriter[ComplexRecursionB] = + JsonWriter.derived[ComplexRecursionB] + + ComplexRecursionA( + 1, + Some(ComplexRecursionB(2, ComplexRecursionA(3, None))) + ).asTokenList shouldBe obj( "a" -> 1, "b" -> obj( "b" -> 2, @@ -612,13 +692,20 @@ class DerivationSpec extends AnyFlatSpec with Matchers { } it should "derive writer for sealed cyclic trait with type parameter" in { - implicit def recursionTraitWithTypeWriter[B: JsonWriter]: JsonObjectWriter[ADTWithType[B]] = JsonWriter.derived[ADTWithType[B]] + implicit def recursionTraitWithTypeWriter[B: JsonWriter] + : JsonObjectWriter[ADTWithType[B]] = JsonWriter.derived[ADTWithType[B]] - implicit def recursionTraitWithTypeAWriter[B: JsonWriter]: JsonObjectWriter[ADTWithTypeA[B]] = JsonWriter.derived[ADTWithTypeA[B]] + implicit def recursionTraitWithTypeAWriter[B: JsonWriter] + : JsonObjectWriter[ADTWithTypeA[B]] = + JsonWriter.derived[ADTWithTypeA[B]] - implicit def recursionTraitWithTypeBWriter[B: JsonWriter]: JsonObjectWriter[ADTWithTypeB[B]] = JsonWriter.derived[ADTWithTypeB[B]] + implicit def recursionTraitWithTypeBWriter[B: JsonWriter] + : JsonObjectWriter[ADTWithTypeB[B]] = + JsonWriter.derived[ADTWithTypeB[B]] - (ADTWithTypeB[Int](1, ADTWithTypeA[Int](2)): ADTWithType[Int]).asTokenList shouldBe obj( + (ADTWithTypeB[Int](1, ADTWithTypeA[Int](2)): ADTWithType[ + Int + ]).asTokenList shouldBe obj( "a" -> 1, "b" -> obj( "a" -> 2 @@ -627,19 +714,27 @@ class DerivationSpec extends AnyFlatSpec with Matchers { } it should "derive writer that normally concatenates with other JsonWriter.derived's" in { - implicit def recursionTraitWithTypeWriter[B: JsonWriter]: JsonWriter[ADTWithType[B]] = { - val simpleJsonWriter = SimpleJsonObjectWriter[ADTWithType[B]].addField("clazz") { - case _: ADTWithTypeA[B] => "ADTWithTypeA" - case _: ADTWithTypeB[B] => "ADTWithTypeB" - } + implicit def recursionTraitWithTypeWriter[B: JsonWriter] + : JsonWriter[ADTWithType[B]] = { + val simpleJsonWriter = + SimpleJsonObjectWriter[ADTWithType[B]].addField("clazz") { + case _: ADTWithTypeA[B] => "ADTWithTypeA" + case _: ADTWithTypeB[B] => "ADTWithTypeB" + } simpleJsonWriter ++ JsonWriter.derived[ADTWithType[B]] } - implicit def recursionTraitWithTypeAWriter[B: JsonWriter]: JsonObjectWriter[ADTWithTypeA[B]] = JsonWriter.derived[ADTWithTypeA[B]] + implicit def recursionTraitWithTypeAWriter[B: JsonWriter] + : JsonObjectWriter[ADTWithTypeA[B]] = + JsonWriter.derived[ADTWithTypeA[B]] - implicit def recursionTraitWithTypeBWriter[B: JsonWriter]: JsonObjectWriter[ADTWithTypeB[B]] = JsonWriter.derived[ADTWithTypeB[B]] + implicit def recursionTraitWithTypeBWriter[B: JsonWriter] + : JsonObjectWriter[ADTWithTypeB[B]] = + JsonWriter.derived[ADTWithTypeB[B]] - (ADTWithTypeB[Int](1, ADTWithTypeA[Int](2)): ADTWithType[Int]).asTokenList shouldBe obj( + (ADTWithTypeB[Int](1, ADTWithTypeA[Int](2)): ADTWithType[ + Int + ]).asTokenList shouldBe obj( "clazz" -> "ADTWithTypeB", "a" -> 1, "b" -> obj( @@ -658,44 +753,64 @@ class DerivationSpec extends AnyFlatSpec with Matchers { } it should "derive writer for simple sealed trait with hierarchy" in { - implicit val caseClassWriter: JsonObjectWriter[CaseClass] = JsonWriter.derived[CaseClass] - implicit val simpleClassWriter: JsonObjectWriter[SimpleClass] = JsonWriter.obj[SimpleClass].addField("b")(_.b) - implicit val justObjectWriter: JsonObjectWriter[JustObject.type] = JsonWriter.obj.addField("type")(_ => "JustObject") - implicit val subChildWriter: JsonObjectWriter[SubChild] = JsonWriter.derived[SubChild] - - implicit val sealedSubWriter: JsonObjectWriter[SimpleSealedTypeSub] = JsonWriter.derived[SimpleSealedTypeSub] - implicit val sealedWriter: JsonWriter[SimpleSealedType] = JsonWriter.derived[SimpleSealedType] - - def write(simpleSealedType: SimpleSealedType): List[TokenNode] = simpleSealedType.asTokenList + implicit val caseClassWriter: JsonObjectWriter[CaseClass] = + JsonWriter.derived[CaseClass] + implicit val simpleClassWriter: JsonObjectWriter[SimpleClass] = + JsonWriter.obj[SimpleClass].addField("b")(_.b) + implicit val justObjectWriter: JsonObjectWriter[JustObject.type] = + JsonWriter.obj.addField("type")(_ => "JustObject") + implicit val subChildWriter: JsonObjectWriter[SubChild] = + JsonWriter.derived[SubChild] + + implicit val sealedSubWriter: JsonObjectWriter[SimpleSealedTypeSub] = + JsonWriter.derived[SimpleSealedTypeSub] + implicit val sealedWriter: JsonWriter[SimpleSealedType] = + JsonWriter.derived[SimpleSealedType] + + def write(simpleSealedType: SimpleSealedType): List[TokenNode] = + simpleSealedType.asTokenList write(CaseClass(1)) shouldBe obj("__type" -> "CaseClass", "a" -> 1) write(SimpleClass(2)) shouldBe obj("__type" -> "SimpleClass", "b" -> 2) - write(JustObject) shouldBe obj("__type" -> "JustObject", "type" -> "JustObject") + write(JustObject) shouldBe obj( + "__type" -> "JustObject", + "type" -> "JustObject" + ) write(SubChild(3)) shouldBe obj("__type" -> "SubChild", "c" -> 3) } it should "derive reader/writer for simple sealed trait with hierarchy with discriminator" in { - implicit val caseClassWriter: JsonObjectWriter[CaseClass] = JsonWriter.derived[CaseClass] - implicit val simpleClassWriter: JsonObjectWriter[SimpleClass] = JsonWriter.obj[SimpleClass].addField("b")(_.b) - implicit val justObjectWriter: JsonObjectWriter[JustObject.type] = JsonWriter.obj - implicit val subChildWriter: JsonObjectWriter[SubChild] = JsonWriter.derived[SubChild] + implicit val caseClassWriter: JsonObjectWriter[CaseClass] = + JsonWriter.derived[CaseClass] + implicit val simpleClassWriter: JsonObjectWriter[SimpleClass] = + JsonWriter.obj[SimpleClass].addField("b")(_.b) + implicit val justObjectWriter: JsonObjectWriter[JustObject.type] = + JsonWriter.obj + implicit val subChildWriter: JsonObjectWriter[SubChild] = + JsonWriter.derived[SubChild] given JsonReader[SimpleSealedType] = JsonReader.derived[SimpleSealedType] - implicit val sealedWriter: JsonWriter[SimpleSealedType] = JsonWriter.derived[SimpleSealedType] + implicit val sealedWriter: JsonWriter[SimpleSealedType] = + JsonWriter.derived[SimpleSealedType] - def write(simpleSealedType: SimpleSealedType): List[TokenNode] = simpleSealedType.asTokenList + def write(simpleSealedType: SimpleSealedType): List[TokenNode] = + simpleSealedType.asTokenList write(CaseClass(1)) shouldBe obj("__type" -> "CaseClass", "a" -> 1) write(SimpleClass(2)) shouldBe obj("__type" -> "SimpleClass", "b" -> 2) write(JustObject) shouldBe obj("__type" -> "JustObject") write(SubChild(3)) shouldBe obj("__type" -> "SubChild", "c" -> 3) - read[SimpleSealedType](obj("__type" -> "CaseClass", "a" -> 1)) shouldBe CaseClass(1) - read[SimpleSealedType](obj("__type" -> "SimpleClass", "b" -> 2)) shouldBe SimpleClass(2) + read[SimpleSealedType]( + obj("__type" -> "CaseClass", "a" -> 1) + ) shouldBe CaseClass(1) + read[SimpleSealedType]( + obj("__type" -> "SimpleClass", "b" -> 2) + ) shouldBe SimpleClass(2) read[SimpleSealedType](obj("__type" -> "JustObject")) shouldBe JustObject - read[SimpleSealedType](obj("__type" -> "SubChild", "c" -> 3)) shouldBe SubChild(3) + read[SimpleSealedType]( + obj("__type" -> "SubChild", "c" -> 3) + ) shouldBe SubChild(3) } - - } diff --git a/modules/core/src/test/scala-3/tethys/derivation/SimpleSealedType.scala b/modules/core/src/test/scala-3/tethys/derivation/SimpleSealedType.scala index 4294b6af..9059a7c9 100644 --- a/modules/core/src/test/scala-3/tethys/derivation/SimpleSealedType.scala +++ b/modules/core/src/test/scala-3/tethys/derivation/SimpleSealedType.scala @@ -7,5 +7,6 @@ case class CaseClass(a: Int) extends SimpleSealedType("CaseClass") case class SimpleClass(val b: Int) extends SimpleSealedType("SimpleClass") case object JustObject extends SimpleSealedType("JustObject") -sealed abstract class SimpleSealedTypeSub(override val `__type`: String) extends SimpleSealedType(`__type`) +sealed abstract class SimpleSealedTypeSub(override val `__type`: String) + extends SimpleSealedType(`__type`) case class SubChild(c: Int) extends SimpleSealedTypeSub("SubChild") diff --git a/modules/core/src/test/scala/tethys/readers/DefaultReadersTest.scala b/modules/core/src/test/scala/tethys/readers/DefaultReadersTest.scala index c67e857d..354d12c5 100644 --- a/modules/core/src/test/scala/tethys/readers/DefaultReadersTest.scala +++ b/modules/core/src/test/scala/tethys/readers/DefaultReadersTest.scala @@ -19,58 +19,97 @@ class DefaultReadersTest extends AnyFlatSpec { private val offsetDateTimeNow = java.time.OffsetDateTime.now() private val zonedDateTimeNow = java.time.ZonedDateTime.now() - private def test[A](result: A)(implicit jsonReader: JsonReader[A], ct: ClassTag[A]): TestDefinition[A] = { + private def test[A]( + result: A + )(implicit jsonReader: JsonReader[A], ct: ClassTag[A]): TestDefinition[A] = { TestDefinition(result, jsonReader, ct.toString()) } - private def test[A](result: A, name: String)(implicit jsonReader: JsonReader[A]): TestDefinition[A] = { + private def test[A](result: A, name: String)(implicit + jsonReader: JsonReader[A] + ): TestDefinition[A] = { TestDefinition(result, jsonReader, name) } - private val cases: List[(TestDefinition[_], List[TokenNode])] = List[(TestDefinition[_], List[TokenNode])]( - test("1") -> value("1"), - test('1') -> value("1"), - test(1) -> value(1), - test(1: Byte) -> value(1: Byte), - test(1: Short) -> value(1: Short), - test(1L) -> value(1L), - test(1f) -> value(1f), - test(1d) -> value(1d), - test(1: BigDecimal) -> value(1: BigDecimal), - test(true, "true") -> value(true), - test(false, "false") -> value(false), - test(List(1, 2, 3)) -> arr(1, 2, 3), - test(List[Int](), "Seq.empty") -> arr(), - test(Map("a" -> 1, "b" -> 2)) -> obj("a" -> 1, "b" -> 2), - test(Map(randomUUID -> 1),"Map with UUID keys") -> obj(randomUUID.toString -> 1), - test(Map(instantNow -> 1), "Map with Instant keys") -> obj(instantNow.toString -> 1), - test(Map(localDateNow -> 1), "Map with LocalDate keys") -> - obj(localDateNow.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE) -> 1), - test(Map(localDateTimeNow -> 1), "Map with LocalDateTime keys") -> - obj(localDateTimeNow.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME) -> 1), - test(Map(offsetDateTimeNow -> 1), "Map with OffsetDateTime keys") -> - obj(offsetDateTimeNow.format(java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME) -> 1), - test(Map(zonedDateTimeNow -> 1), "Map with ZonedDateTime keys") -> - obj(zonedDateTimeNow.format(java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME) -> 1), - test(Map(1L -> 1), "Map with Long keys") -> obj("1" -> 1), - test(Map(1 -> 1), "Map with Int keys") -> obj("1" -> 1), - test(Option(1), "Option.nonEmpty") -> value(1), - test(Option.empty[Int], "Option.empty") -> List(NullValueNode) , - test(1: java.lang.Integer) -> value(1), - test(java.lang.Byte.valueOf(1: Byte)) -> value(1: Byte), - test(java.lang.Short.valueOf(1: Short)) -> value(1: Short), - test(1L: java.lang.Long) -> value(1L), - test(1f: java.lang.Float) -> value(1f), - test(1d: java.lang.Double) -> value(1d), - test(java.math.BigDecimal.valueOf(1)) -> value(1: BigDecimal), - test(java.math.BigInteger.valueOf(1)) -> value(1: BigInt), - test(randomUUID) -> value(randomUUID.toString), - test(instantNow) -> value(instantNow.toString), - test(localDateNow) -> value(localDateNow.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE)), - test(localDateTimeNow) -> value(localDateTimeNow.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME)), - test(offsetDateTimeNow) -> value(offsetDateTimeNow.format(java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME)), - test(zonedDateTimeNow) -> value(zonedDateTimeNow.format(java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME)) - ) + private val cases: List[(TestDefinition[_], List[TokenNode])] = + List[(TestDefinition[_], List[TokenNode])]( + test("1") -> value("1"), + test('1') -> value("1"), + test(1) -> value(1), + test(1: Byte) -> value(1: Byte), + test(1: Short) -> value(1: Short), + test(1L) -> value(1L), + test(1f) -> value(1f), + test(1d) -> value(1d), + test(1: BigDecimal) -> value(1: BigDecimal), + test(true, "true") -> value(true), + test(false, "false") -> value(false), + test(List(1, 2, 3)) -> arr(1, 2, 3), + test(List[Int](), "Seq.empty") -> arr(), + test(Map("a" -> 1, "b" -> 2)) -> obj("a" -> 1, "b" -> 2), + test(Map(randomUUID -> 1), "Map with UUID keys") -> obj( + randomUUID.toString -> 1 + ), + test(Map(instantNow -> 1), "Map with Instant keys") -> obj( + instantNow.toString -> 1 + ), + test(Map(localDateNow -> 1), "Map with LocalDate keys") -> + obj( + localDateNow.format( + java.time.format.DateTimeFormatter.ISO_LOCAL_DATE + ) -> 1 + ), + test(Map(localDateTimeNow -> 1), "Map with LocalDateTime keys") -> + obj( + localDateTimeNow.format( + java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME + ) -> 1 + ), + test(Map(offsetDateTimeNow -> 1), "Map with OffsetDateTime keys") -> + obj( + offsetDateTimeNow.format( + java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME + ) -> 1 + ), + test(Map(zonedDateTimeNow -> 1), "Map with ZonedDateTime keys") -> + obj( + zonedDateTimeNow.format( + java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME + ) -> 1 + ), + test(Map(1L -> 1), "Map with Long keys") -> obj("1" -> 1), + test(Map(1 -> 1), "Map with Int keys") -> obj("1" -> 1), + test(Option(1), "Option.nonEmpty") -> value(1), + test(Option.empty[Int], "Option.empty") -> List(NullValueNode), + test(1: java.lang.Integer) -> value(1), + test(java.lang.Byte.valueOf(1: Byte)) -> value(1: Byte), + test(java.lang.Short.valueOf(1: Short)) -> value(1: Short), + test(1L: java.lang.Long) -> value(1L), + test(1f: java.lang.Float) -> value(1f), + test(1d: java.lang.Double) -> value(1d), + test(java.math.BigDecimal.valueOf(1)) -> value(1: BigDecimal), + test(java.math.BigInteger.valueOf(1)) -> value(1: BigInt), + test(randomUUID) -> value(randomUUID.toString), + test(instantNow) -> value(instantNow.toString), + test(localDateNow) -> value( + localDateNow.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE) + ), + test(localDateTimeNow) -> value( + localDateTimeNow.format( + java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME + ) + ), + test(offsetDateTimeNow) -> value( + offsetDateTimeNow.format( + java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME + ) + ), + test(zonedDateTimeNow) -> value( + zonedDateTimeNow.format( + java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME + ) + ) + ) behavior of "Default readers" @@ -86,9 +125,12 @@ class DefaultReadersTest extends AnyFlatSpec { fail("oops") } - } object DefaultReadersTest { - case class TestDefinition[A](result: A, jsonReader: JsonReader[A], name: String) + case class TestDefinition[A]( + result: A, + jsonReader: JsonReader[A], + name: String + ) } diff --git a/modules/core/src/test/scala/tethys/readers/JsonReaderBuilderTest.scala b/modules/core/src/test/scala/tethys/readers/JsonReaderBuilderTest.scala index 4b6e476a..587c0cd5 100644 --- a/modules/core/src/test/scala/tethys/readers/JsonReaderBuilderTest.scala +++ b/modules/core/src/test/scala/tethys/readers/JsonReaderBuilderTest.scala @@ -68,26 +68,26 @@ class JsonReaderBuilderTest extends AnyFlatSpec with Matchers { .buildReader(FatClass.apply) } - read[FatClass](obj( - "a" -> 1, - "b" -> "s", - "c" -> true, - "d" -> arr("a", "b", "c"), - "e" -> 4, - "f" -> "c" - )) shouldBe FatClass( + read[FatClass]( + obj( + "a" -> 1, + "b" -> "s", + "c" -> true, + "d" -> arr("a", "b", "c"), + "e" -> 4, + "f" -> "c" + ) + ) shouldBe FatClass( a = 1, b = "s", c = true, d = Seq("a", "b", "c"), - e = 4.0D, + e = 4.0d, f = 'c', opt = None ) } - - it should "build strict reader from fields" in { implicit val reader: JsonReader[B] = { JsonReader.builder @@ -95,12 +95,43 @@ class JsonReaderBuilderTest extends AnyFlatSpec with Matchers { .buildStrictReader(i => B(i.getOrElse(0))) } - val thrown = the [ReaderError] thrownBy read[B](obj("j" -> 1)) - thrown.getMessage should equal ("Illegal json at '[ROOT]': unexpected field 'j', expected one of 'i'") + val thrown = the[ReaderError] thrownBy read[B](obj("j" -> 1)) + thrown.getMessage should equal( + "Illegal json at '[ROOT]': unexpected field 'j', expected one of 'i'" + ) } it should "allow to build reader with more than 22 fields" in { - implicit val reader: JsonReader[((Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int), Int, Int)] = { + implicit val reader: JsonReader[ + ( + ( + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int, + Int + ), + Int, + Int + ) + ] = { JsonReader.builder .addField[Int]("f1") .addField[Int]("f2") @@ -129,32 +160,35 @@ class JsonReaderBuilderTest extends AnyFlatSpec with Matchers { .buildReader((tuple, f23, f24) => (tuple, f23, f24)) } - read(obj( - "f1" -> 1, - "f2" -> 2, - "f3" -> 3, - "f4" -> 4, - "f5" -> 5, - "f6" -> 6, - "f7" -> 7, - "f8" -> 8, - "f9" -> 9, - "f10" -> 10, - "f11" -> 11, - "f12" -> 12, - "f13" -> 13, - "f14" -> 14, - "f15" -> 15, - "f16" -> 16, - "f17" -> 17, - "f18" -> 18, - "f19" -> 19, - "f20" -> 20, - "f21" -> 21, - "f22" -> 22, - "f23" -> 23, - "f24" -> 24 - ))(reader) shouldBe ((1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11 ,12 ,13 ,14 ,15 ,16 ,17 ,18 ,19 ,20 ,21 ,22), 23, 24) + read( + obj( + "f1" -> 1, + "f2" -> 2, + "f3" -> 3, + "f4" -> 4, + "f5" -> 5, + "f6" -> 6, + "f7" -> 7, + "f8" -> 8, + "f9" -> 9, + "f10" -> 10, + "f11" -> 11, + "f12" -> 12, + "f13" -> 13, + "f14" -> 14, + "f15" -> 15, + "f16" -> 16, + "f17" -> 17, + "f18" -> 18, + "f19" -> 19, + "f20" -> 20, + "f21" -> 21, + "f22" -> 22, + "f23" -> 23, + "f24" -> 24 + ) + )(reader) shouldBe ((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22), 23, 24) } } @@ -163,11 +197,13 @@ object JsonReaderBuilderTest { case class B(i: Int) extends A case class C(s: String) extends A - case class FatClass(a: Int, - b: String, - c: Boolean, - d: Seq[String], - e: Double, - f: Char, - opt: Option[Int]) + case class FatClass( + a: Int, + b: String, + c: Boolean, + d: Seq[String], + e: Double, + f: Char, + opt: Option[Int] + ) } diff --git a/modules/core/src/test/scala/tethys/readers/QueueIteratorTest.scala b/modules/core/src/test/scala/tethys/readers/QueueIteratorTest.scala index 1933a9ac..79c7aaa9 100644 --- a/modules/core/src/test/scala/tethys/readers/QueueIteratorTest.scala +++ b/modules/core/src/test/scala/tethys/readers/QueueIteratorTest.scala @@ -112,7 +112,6 @@ class QueueIteratorTest extends AnyFlatSpec with Matchers { b.nextToken().isArrayEnd shouldBe true b.nextToken().isEmpty shouldBe true - it.currentToken().isObjectEnd shouldBe true it.nextToken().isEmpty shouldBe true diff --git a/modules/core/src/test/scala/tethys/writers/DefaultWritersTest.scala b/modules/core/src/test/scala/tethys/writers/DefaultWritersTest.scala index 6d38244e..fa5ff855 100644 --- a/modules/core/src/test/scala/tethys/writers/DefaultWritersTest.scala +++ b/modules/core/src/test/scala/tethys/writers/DefaultWritersTest.scala @@ -18,61 +18,102 @@ class DefaultWritersTest extends AnyFlatSpec { private val offsetDateTimeNow = java.time.OffsetDateTime.now() private val zonedDateTimeNow = java.time.ZonedDateTime.now() - private def test[A](value: A)(implicit jsonWriter: JsonWriter[A], ct: ClassTag[A]): TestDefinition[A] = { + private def test[A]( + value: A + )(implicit jsonWriter: JsonWriter[A], ct: ClassTag[A]): TestDefinition[A] = { TestDefinition(value, jsonWriter, ct.toString()) } - private def test[A](value: A, name: String)(implicit jsonWriter: JsonWriter[A]): TestDefinition[A] = { + private def test[A](value: A, name: String)(implicit + jsonWriter: JsonWriter[A] + ): TestDefinition[A] = { TestDefinition(value, jsonWriter, name) } - private val cases: List[(TestDefinition[_], List[TokenNode])] = List[(TestDefinition[_], List[TokenNode])]( - test("1") -> value("1"), - test('1') -> value("1"), - test(1) -> value(1), - test(1: Byte) -> value(1: Byte), - test(1: Short) -> value(1: Short), - test(1L) -> value(1L), - test(1f) -> value(1f), - test(1d) -> value(1d), - test(1: BigDecimal) -> value(1: BigDecimal), - test(1: BigInt) -> value(1: BigInt), - test(true, "true") -> value(true), - test(false, "false") -> value(false), - test(List(1, 2, 3)) -> arr(1, 2, 3), - test(List[Int](), "Seq.empty") -> arr(), - test(Map("a" -> 1, "b" -> 2)) -> obj("a" -> 1, "b" -> 2), - test(Map(randomUUID -> 1),"Map with UUID keys") -> obj(randomUUID.toString -> 1), - test(Map(1L -> 1), "Map with Long keys") -> obj("1" -> 1), - test(Map(1 -> 1), "Map with Int keys") -> obj("1" -> 1), - test(Map(instantNow -> 1), "Map with Instant keys") -> obj(instantNow.toString -> 1), - test(Map(localDateNow -> 1), "Map with LocalDate keys") -> - obj(localDateNow.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE) -> 1), - test(Map(localDateTimeNow -> 1), "Map with LocalDateTime keys") -> - obj(localDateTimeNow.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME) -> 1), - test(Map(offsetDateTimeNow -> 1), "Map with OffsetDateTime keys") -> - obj(offsetDateTimeNow.format(java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME) -> 1), - test(Map(zonedDateTimeNow -> 1), "Map with ZonedDateTime keys") -> - obj(zonedDateTimeNow.format(java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME) -> 1), - test(Option(1), "Option.nonEmpty") -> value(1), - test(Option.empty[Int], "Option.empty") -> List(NullValueNode), - test(Right(1): Either[String, Int], "Either.right") -> value(1), - test(Left("Not an Int"): Either[String, Int], "Either.left") -> value("Not an Int"), - test(1: java.lang.Integer) -> value(1), - test(java.lang.Byte.valueOf(1: Byte)) -> value(1: Byte), - test(java.lang.Short.valueOf(1: Short)) -> value(1: Short), - test(1L: java.lang.Long) -> value(1L), - test(1f: java.lang.Float) -> value(1f), - test(1d: java.lang.Double) -> value(1d), - test(java.math.BigDecimal.valueOf(1)) -> value(1: BigDecimal), - test(java.math.BigInteger.valueOf(1)) -> value(1: BigInt), - test(randomUUID) -> value(randomUUID.toString), - test(instantNow) -> value(instantNow.toString), - test(localDateNow) -> value(localDateNow.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE)), - test(localDateTimeNow) -> value(localDateTimeNow.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME)), - test(offsetDateTimeNow) -> value(offsetDateTimeNow.format(java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME)), - test(zonedDateTimeNow) -> value(zonedDateTimeNow.format(java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME)) - ) + private val cases: List[(TestDefinition[_], List[TokenNode])] = + List[(TestDefinition[_], List[TokenNode])]( + test("1") -> value("1"), + test('1') -> value("1"), + test(1) -> value(1), + test(1: Byte) -> value(1: Byte), + test(1: Short) -> value(1: Short), + test(1L) -> value(1L), + test(1f) -> value(1f), + test(1d) -> value(1d), + test(1: BigDecimal) -> value(1: BigDecimal), + test(1: BigInt) -> value(1: BigInt), + test(true, "true") -> value(true), + test(false, "false") -> value(false), + test(List(1, 2, 3)) -> arr(1, 2, 3), + test(List[Int](), "Seq.empty") -> arr(), + test(Map("a" -> 1, "b" -> 2)) -> obj("a" -> 1, "b" -> 2), + test(Map(randomUUID -> 1), "Map with UUID keys") -> obj( + randomUUID.toString -> 1 + ), + test(Map(1L -> 1), "Map with Long keys") -> obj("1" -> 1), + test(Map(1 -> 1), "Map with Int keys") -> obj("1" -> 1), + test(Map(instantNow -> 1), "Map with Instant keys") -> obj( + instantNow.toString -> 1 + ), + test(Map(localDateNow -> 1), "Map with LocalDate keys") -> + obj( + localDateNow.format( + java.time.format.DateTimeFormatter.ISO_LOCAL_DATE + ) -> 1 + ), + test(Map(localDateTimeNow -> 1), "Map with LocalDateTime keys") -> + obj( + localDateTimeNow.format( + java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME + ) -> 1 + ), + test(Map(offsetDateTimeNow -> 1), "Map with OffsetDateTime keys") -> + obj( + offsetDateTimeNow.format( + java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME + ) -> 1 + ), + test(Map(zonedDateTimeNow -> 1), "Map with ZonedDateTime keys") -> + obj( + zonedDateTimeNow.format( + java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME + ) -> 1 + ), + test(Option(1), "Option.nonEmpty") -> value(1), + test(Option.empty[Int], "Option.empty") -> List(NullValueNode), + test(Right(1): Either[String, Int], "Either.right") -> value(1), + test(Left("Not an Int"): Either[String, Int], "Either.left") -> value( + "Not an Int" + ), + test(1: java.lang.Integer) -> value(1), + test(java.lang.Byte.valueOf(1: Byte)) -> value(1: Byte), + test(java.lang.Short.valueOf(1: Short)) -> value(1: Short), + test(1L: java.lang.Long) -> value(1L), + test(1f: java.lang.Float) -> value(1f), + test(1d: java.lang.Double) -> value(1d), + test(java.math.BigDecimal.valueOf(1)) -> value(1: BigDecimal), + test(java.math.BigInteger.valueOf(1)) -> value(1: BigInt), + test(randomUUID) -> value(randomUUID.toString), + test(instantNow) -> value(instantNow.toString), + test(localDateNow) -> value( + localDateNow.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE) + ), + test(localDateTimeNow) -> value( + localDateTimeNow.format( + java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME + ) + ), + test(offsetDateTimeNow) -> value( + offsetDateTimeNow.format( + java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME + ) + ), + test(zonedDateTimeNow) -> value( + zonedDateTimeNow.format( + java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME + ) + ) + ) behavior of "Default writers" @@ -86,9 +127,12 @@ class DefaultWritersTest extends AnyFlatSpec { fail("oops") } - } object DefaultWritersTest { - case class TestDefinition[A](value: A, jsonWriter: JsonWriter[A], name: String) + case class TestDefinition[A]( + value: A, + jsonWriter: JsonWriter[A], + name: String + ) } diff --git a/modules/core/src/test/scala/tethys/writers/SimpleJsonObjectWriterTest.scala b/modules/core/src/test/scala/tethys/writers/SimpleJsonObjectWriterTest.scala index 59473fc9..468f6416 100644 --- a/modules/core/src/test/scala/tethys/writers/SimpleJsonObjectWriterTest.scala +++ b/modules/core/src/test/scala/tethys/writers/SimpleJsonObjectWriterTest.scala @@ -13,7 +13,8 @@ class SimpleJsonObjectWriterTest extends AnyFlatSpec { it should "write correct object to TokenWriter" in { implicit val testWriter: SimpleJsonObjectWriter[TestData] = { - JsonWriter.obj[TestData] + JsonWriter + .obj[TestData] .addField("a")(_.a) .addField("b")(_.b) .addField("c")(_.b.isEmpty) @@ -28,7 +29,9 @@ class SimpleJsonObjectWriterTest extends AnyFlatSpec { it should "write correct object to TokenWriter for concatenated writers" in { implicit val testWriter: JsonObjectWriter[TestData] = { - JsonWriter.obj[TestData].addField("a")(_.a) + JsonWriter + .obj[TestData] + .addField("a")(_.a) .concat(JsonWriter.obj[TestData].addField("b")(_.b)) .addField("c")(_.b.isEmpty) } @@ -42,7 +45,8 @@ class SimpleJsonObjectWriterTest extends AnyFlatSpec { it should "write correct object with char field" in { implicit val charWriter: SimpleJsonObjectWriter[CharData] = { - JsonWriter.obj[CharData] + JsonWriter + .obj[CharData] .addField("c")(_.c) } diff --git a/modules/jackson-backend/src/main/scala/tethys/jackson/JacksonTokenIterator.scala b/modules/jackson-backend/src/main/scala/tethys/jackson/JacksonTokenIterator.scala index 6833f17d..3bbb60fa 100644 --- a/modules/jackson-backend/src/main/scala/tethys/jackson/JacksonTokenIterator.scala +++ b/modules/jackson-backend/src/main/scala/tethys/jackson/JacksonTokenIterator.scala @@ -7,14 +7,15 @@ import tethys.readers.tokens.{BaseTokenIterator, TokenIterator} import scala.annotation.switch -final class JacksonTokenIterator(jsonParser: JsonParser) extends BaseTokenIterator { +final class JacksonTokenIterator(jsonParser: JsonParser) + extends BaseTokenIterator { private[this] var token: Token = fromId(jsonParser.currentTokenId()) override def currentToken(): Token = token override def nextToken(): Token = { val t = jsonParser.nextToken() token = { - if(t == null) Token.Empty + if (t == null) Token.Empty else fromId(t.id()) } token @@ -42,23 +43,23 @@ final class JacksonTokenIterator(jsonParser: JsonParser) extends BaseTokenIterat private def fromId(tokenId: Int): Token = (tokenId: @switch) match { case JsonTokenId.ID_START_OBJECT => ObjectStartToken - case JsonTokenId.ID_END_OBJECT => ObjectEndToken - case JsonTokenId.ID_START_ARRAY => ArrayStartToken - case JsonTokenId.ID_END_ARRAY => ArrayEndToken - case JsonTokenId.ID_FIELD_NAME => FieldNameToken - case JsonTokenId.ID_STRING => StringValueToken - case JsonTokenId.ID_NUMBER_INT => NumberValueToken + case JsonTokenId.ID_END_OBJECT => ObjectEndToken + case JsonTokenId.ID_START_ARRAY => ArrayStartToken + case JsonTokenId.ID_END_ARRAY => ArrayEndToken + case JsonTokenId.ID_FIELD_NAME => FieldNameToken + case JsonTokenId.ID_STRING => StringValueToken + case JsonTokenId.ID_NUMBER_INT => NumberValueToken case JsonTokenId.ID_NUMBER_FLOAT => NumberValueToken - case JsonTokenId.ID_TRUE => BooleanValueToken - case JsonTokenId.ID_FALSE => BooleanValueToken - case JsonTokenId.ID_NULL => NullValueToken - case _ => Token.Empty + case JsonTokenId.ID_TRUE => BooleanValueToken + case JsonTokenId.ID_FALSE => BooleanValueToken + case JsonTokenId.ID_NULL => NullValueToken + case _ => Token.Empty } } object JacksonTokenIterator { def fromFreshParser(parser: JsonParser): TokenIterator = { - parser.nextToken()// move parser to first token + parser.nextToken() // move parser to first token new JacksonTokenIterator(parser) } -} \ No newline at end of file +} diff --git a/modules/jackson-backend/src/main/scala/tethys/jackson/package.scala b/modules/jackson-backend/src/main/scala/tethys/jackson/package.scala index 472cccc8..78720394 100644 --- a/modules/jackson-backend/src/main/scala/tethys/jackson/package.scala +++ b/modules/jackson-backend/src/main/scala/tethys/jackson/package.scala @@ -14,16 +14,23 @@ package object jackson { f } - - implicit def jacksonTokenWriterProducer(implicit jsonFactory: JsonFactory = defaultJsonFactory): TokenWriterProducer = new TokenWriterProducer { + implicit def jacksonTokenWriterProducer(implicit + jsonFactory: JsonFactory = defaultJsonFactory + ): TokenWriterProducer = new TokenWriterProducer { override def forWriter(writer: Writer): TokenWriter = { new JacksonTokenWriter(jsonFactory.createGenerator(writer)) } } - implicit def jacksonTokenIteratorProducer(implicit jsonFactory: JsonFactory = defaultJsonFactory): TokenIteratorProducer = new TokenIteratorProducer { - override def fromReader(reader: Reader): Either[ReaderError, TokenIterator] = { - ReaderError.catchNonFatal(JacksonTokenIterator.fromFreshParser(jsonFactory.createParser(reader)))(FieldName()) + implicit def jacksonTokenIteratorProducer(implicit + jsonFactory: JsonFactory = defaultJsonFactory + ): TokenIteratorProducer = new TokenIteratorProducer { + override def fromReader( + reader: Reader + ): Either[ReaderError, TokenIterator] = { + ReaderError.catchNonFatal( + JacksonTokenIterator.fromFreshParser(jsonFactory.createParser(reader)) + )(FieldName()) } } } diff --git a/modules/jackson-backend/src/main/scala/tethys/jackson/pretty/package.scala b/modules/jackson-backend/src/main/scala/tethys/jackson/pretty/package.scala index f7183779..6bb86bd3 100644 --- a/modules/jackson-backend/src/main/scala/tethys/jackson/pretty/package.scala +++ b/modules/jackson-backend/src/main/scala/tethys/jackson/pretty/package.scala @@ -7,12 +7,18 @@ import tethys.readers.tokens.TokenIteratorProducer import tethys.writers.tokens.{TokenWriter, TokenWriterProducer} package object pretty { - implicit def prettyJacksonTokenWriterProducer(implicit jsonFactory: JsonFactory = defaultJsonFactory): TokenWriterProducer = new TokenWriterProducer { + implicit def prettyJacksonTokenWriterProducer(implicit + jsonFactory: JsonFactory = defaultJsonFactory + ): TokenWriterProducer = new TokenWriterProducer { override def forWriter(writer: Writer): TokenWriter = { - new JacksonTokenWriter(jsonFactory.createGenerator(writer).useDefaultPrettyPrinter()) + new JacksonTokenWriter( + jsonFactory.createGenerator(writer).useDefaultPrettyPrinter() + ) } } - implicit def jacksonTokenIteratorProducer(implicit jsonFactory: JsonFactory = defaultJsonFactory): TokenIteratorProducer = + implicit def jacksonTokenIteratorProducer(implicit + jsonFactory: JsonFactory = defaultJsonFactory + ): TokenIteratorProducer = tethys.jackson.jacksonTokenIteratorProducer } diff --git a/modules/jackson-backend/src/test/scala/tethys/jackson/JacksonTokenIteratorTest.scala b/modules/jackson-backend/src/test/scala/tethys/jackson/JacksonTokenIteratorTest.scala index db373092..060b7b89 100644 --- a/modules/jackson-backend/src/test/scala/tethys/jackson/JacksonTokenIteratorTest.scala +++ b/modules/jackson-backend/src/test/scala/tethys/jackson/JacksonTokenIteratorTest.scala @@ -104,7 +104,6 @@ class JacksonTokenIteratorTest extends AnyFlatSpec with Matchers { b.nextToken().isArrayEnd shouldBe true b.nextToken().isEmpty shouldBe true - it.currentToken().isObjectEnd shouldBe true it.nextToken().isEmpty shouldBe true diff --git a/modules/jackson-backend/src/test/scala/tethys/jackson/JacksonTokenWriterTest.scala b/modules/jackson-backend/src/test/scala/tethys/jackson/JacksonTokenWriterTest.scala index cf51f79a..290a05d6 100644 --- a/modules/jackson-backend/src/test/scala/tethys/jackson/JacksonTokenWriterTest.scala +++ b/modules/jackson-backend/src/test/scala/tethys/jackson/JacksonTokenWriterTest.scala @@ -76,7 +76,9 @@ class JacksonTokenWriterTest extends AnyFlatSpec with Matchers { } it should "write raw json" in { - iterate(_.writeRawJson("""{"some" : "raw json"}""")) shouldBe """{"some" : "raw json"}""" + iterate( + _.writeRawJson("""{"some" : "raw json"}""") + ) shouldBe """{"some" : "raw json"}""" } it should "write complex object structure" in { diff --git a/modules/jackson-backend/src/test/scala/tethys/jackson/RawJsonTest.scala b/modules/jackson-backend/src/test/scala/tethys/jackson/RawJsonTest.scala index 23e6c682..409ba23d 100644 --- a/modules/jackson-backend/src/test/scala/tethys/jackson/RawJsonTest.scala +++ b/modules/jackson-backend/src/test/scala/tethys/jackson/RawJsonTest.scala @@ -28,7 +28,9 @@ class RawJsonTest extends AnyFlatSpec with Matchers { "null".jsonAs[RawJson] shouldBe Right(RawJson("null")) } it should "read arrays" in { - "[1, 2, true,3.0,\"a\"]".jsonAs[RawJson] shouldBe Right(RawJson("[1,2,true,3.0,\"a\"]")) + "[1, 2, true,3.0,\"a\"]".jsonAs[RawJson] shouldBe Right( + RawJson("[1,2,true,3.0,\"a\"]") + ) } it should "read objects" in { """ @@ -39,7 +41,9 @@ class RawJsonTest extends AnyFlatSpec with Matchers { "e": { "f": null }, "g": [1,2,3] } - """.jsonAs[RawJson] shouldBe Right(RawJson("""{"a":1,"b":false,"c":"d","e":{"f":null},"g":[1,2,3]}""")) + """.jsonAs[RawJson] shouldBe Right( + RawJson("""{"a":1,"b":false,"c":"d","e":{"f":null},"g":[1,2,3]}""") + ) } behavior of "RawJson.writer" @@ -56,7 +60,8 @@ class RawJsonTest extends AnyFlatSpec with Matchers { } it should "write json as is in middle of object" in { case class Foo(a: Int, b: RawJson, c: Boolean) - implicit val fooWriter: JsonWriter[Foo] = JsonWriter.obj[Foo] + implicit val fooWriter: JsonWriter[Foo] = JsonWriter + .obj[Foo] .addField("a")(_.a) .addField("b")(_.b) .addField("c")(_.c) @@ -84,7 +89,10 @@ class RawJsonTest extends AnyFlatSpec with Matchers { tokenWriter.writeArrayStart() JsonWriter.intWriter.write(value(0).asInstanceOf[Int], tokenWriter) RawJson.rawJsonWriter.write(value(1).asInstanceOf[RawJson], tokenWriter) - JsonWriter.booleanWriter.write(value(2).asInstanceOf[Boolean], tokenWriter) + JsonWriter.booleanWriter.write( + value(2).asInstanceOf[Boolean], + tokenWriter + ) tokenWriter.writeArrayEnd() } } diff --git a/modules/json4s/src/main/scala/tethys/json4s/ast/Json4sSupport.scala b/modules/json4s/src/main/scala/tethys/json4s/ast/Json4sSupport.scala index e230e414..c91fb1fe 100644 --- a/modules/json4s/src/main/scala/tethys/json4s/ast/Json4sSupport.scala +++ b/modules/json4s/src/main/scala/tethys/json4s/ast/Json4sSupport.scala @@ -9,96 +9,145 @@ import tethys.writers.tokens.TokenWriter trait Json4sSupport { - implicit lazy val json4sJNothingWriter: JsonWriter[JNothing.type] = new JsonWriter[JsonAST.JNothing.type] { - override def write(name: String, value: JsonAST.JNothing.type, tokenWriter: TokenWriter): Unit = () - override def write(value: JsonAST.JNothing.type, tokenWriter: TokenWriter): Unit = () - } - implicit lazy val json4sJNullWriter: JsonWriter[JNull.type] = new JsonWriter[JsonAST.JNull.type] { - override def write(value: JsonAST.JNull.type, tokenWriter: TokenWriter): Unit = tokenWriter.writeNull() - } - implicit lazy val json4sJStringWriter: JsonWriter[JString] = JsonWriter[String].contramap(_.s) - implicit lazy val json4sJDoubleWriter: JsonWriter[JDouble] = JsonWriter[Double].contramap(_.num) - implicit lazy val json4sJDecimalWriter: JsonWriter[JDecimal] = JsonWriter[BigDecimal].contramap(_.num) - implicit lazy val json4sJLongWriter: JsonWriter[JLong] = JsonWriter[Long].contramap(_.num) - implicit lazy val json4sJIntWriter: JsonWriter[JInt] = JsonWriter[BigInt].contramap(_.num) - implicit lazy val json4sJBoolWriter: JsonWriter[JBool] = JsonWriter[Boolean].contramap(_.value) - implicit lazy val json4sJObjectWriter: JsonWriter[JObject] = new JsonObjectWriter[JObject] { - override def writeValues(value: JObject, tokenWriter: TokenWriter): Unit = value.obj.foreach { t => - json4sJValueWriter.write(t._1, t._2, tokenWriter) + implicit lazy val json4sJNothingWriter: JsonWriter[JNothing.type] = + new JsonWriter[JsonAST.JNothing.type] { + override def write( + name: String, + value: JsonAST.JNothing.type, + tokenWriter: TokenWriter + ): Unit = () + override def write( + value: JsonAST.JNothing.type, + tokenWriter: TokenWriter + ): Unit = () } - } - implicit lazy val json4sJArrayWriter: JsonWriter[JArray] = JsonWriter[List[JValue]].contramap(_.arr) - implicit lazy val json4sJSetWriter: JsonWriter[JSet] = JsonWriter[Set[JValue]].contramap(_.set) + implicit lazy val json4sJNullWriter: JsonWriter[JNull.type] = + new JsonWriter[JsonAST.JNull.type] { + override def write( + value: JsonAST.JNull.type, + tokenWriter: TokenWriter + ): Unit = tokenWriter.writeNull() + } + implicit lazy val json4sJStringWriter: JsonWriter[JString] = + JsonWriter[String].contramap(_.s) + implicit lazy val json4sJDoubleWriter: JsonWriter[JDouble] = + JsonWriter[Double].contramap(_.num) + implicit lazy val json4sJDecimalWriter: JsonWriter[JDecimal] = + JsonWriter[BigDecimal].contramap(_.num) + implicit lazy val json4sJLongWriter: JsonWriter[JLong] = + JsonWriter[Long].contramap(_.num) + implicit lazy val json4sJIntWriter: JsonWriter[JInt] = + JsonWriter[BigInt].contramap(_.num) + implicit lazy val json4sJBoolWriter: JsonWriter[JBool] = + JsonWriter[Boolean].contramap(_.value) + implicit lazy val json4sJObjectWriter: JsonWriter[JObject] = + new JsonObjectWriter[JObject] { + override def writeValues(value: JObject, tokenWriter: TokenWriter): Unit = + value.obj.foreach { t => + json4sJValueWriter.write(t._1, t._2, tokenWriter) + } + } + implicit lazy val json4sJArrayWriter: JsonWriter[JArray] = + JsonWriter[List[JValue]].contramap(_.arr) + implicit lazy val json4sJSetWriter: JsonWriter[JSet] = + JsonWriter[Set[JValue]].contramap(_.set) - implicit lazy val json4sJValueWriter: JsonWriter[JValue] = new JsonWriter[JValue] { - override def write(value: JValue, tokenWriter: TokenWriter): Unit = value match { - case JNothing => JsonWriter[JNothing.type].write(JNothing, tokenWriter) - case JNull => JsonWriter[JNull.type].write(JNull, tokenWriter) - case x: JString => JsonWriter[JString].write(x, tokenWriter) - case x: JDouble => JsonWriter[JDouble].write(x, tokenWriter) - case x: JDecimal => JsonWriter[JDecimal].write(x, tokenWriter) - case x: JLong => JsonWriter[JLong].write(x, tokenWriter) - case x: JInt => JsonWriter[JInt].write(x, tokenWriter) - case x: JBool => JsonWriter[JBool].write(x, tokenWriter) - case x: JObject => JsonWriter[JObject].write(x, tokenWriter) - case x: JArray => JsonWriter[JArray].write(x, tokenWriter) - case x: JSet => JsonWriter[JSet].write(x, tokenWriter) + implicit lazy val json4sJValueWriter: JsonWriter[JValue] = + new JsonWriter[JValue] { + override def write(value: JValue, tokenWriter: TokenWriter): Unit = + value match { + case JNothing => + JsonWriter[JNothing.type].write(JNothing, tokenWriter) + case JNull => JsonWriter[JNull.type].write(JNull, tokenWriter) + case x: JString => JsonWriter[JString].write(x, tokenWriter) + case x: JDouble => JsonWriter[JDouble].write(x, tokenWriter) + case x: JDecimal => JsonWriter[JDecimal].write(x, tokenWriter) + case x: JLong => JsonWriter[JLong].write(x, tokenWriter) + case x: JInt => JsonWriter[JInt].write(x, tokenWriter) + case x: JBool => JsonWriter[JBool].write(x, tokenWriter) + case x: JObject => JsonWriter[JObject].write(x, tokenWriter) + case x: JArray => JsonWriter[JArray].write(x, tokenWriter) + case x: JSet => JsonWriter[JSet].write(x, tokenWriter) + } } - } - implicit lazy val json4sJStringReader: JsonReader[JString] = JsonReader[String].map(JString(_)) - implicit lazy val json4sJDoubleReader: JsonReader[JDouble] = JsonReader[Double].map(JDouble(_)) - implicit lazy val json4sJDecimalReader: JsonReader[JDecimal] = JsonReader[BigDecimal].map(JDecimal(_)) - implicit lazy val json4sJLongReader: JsonReader[JLong] = JsonReader[Long].map(JLong(_)) - implicit lazy val json4sJIntReader: JsonReader[JInt] = JsonReader[BigInt].map(JInt(_)) - implicit lazy val json4sJBoolReader: JsonReader[JBool] = JsonReader[Boolean].map(b => if(b) JBool.True else JBool.False) - implicit lazy val json4sJObjectReader: JsonReader[JObject] = new JsonReader[JObject] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): JObject = { - if (!it.currentToken().isObjectStart) ReaderError.wrongJson(s"Expected object start but found: ${it.currentToken()}") - else { - it.next() - val builder = List.newBuilder[(String, JValue)] - while(!it.currentToken().isObjectEnd) { - val token = it.currentToken() - if(token.isFieldName) { - val name = it.fieldName() - val value = json4sJValueReader.read(it.next())(fieldName.appendFieldName(name)) - builder += name -> value - } else { - ReaderError.wrongJson(s"Expect end of object or field name but '$token' found")(fieldName) + implicit lazy val json4sJStringReader: JsonReader[JString] = + JsonReader[String].map(JString(_)) + implicit lazy val json4sJDoubleReader: JsonReader[JDouble] = + JsonReader[Double].map(JDouble(_)) + implicit lazy val json4sJDecimalReader: JsonReader[JDecimal] = + JsonReader[BigDecimal].map(JDecimal(_)) + implicit lazy val json4sJLongReader: JsonReader[JLong] = + JsonReader[Long].map(JLong(_)) + implicit lazy val json4sJIntReader: JsonReader[JInt] = + JsonReader[BigInt].map(JInt(_)) + implicit lazy val json4sJBoolReader: JsonReader[JBool] = + JsonReader[Boolean].map(b => if (b) JBool.True else JBool.False) + implicit lazy val json4sJObjectReader: JsonReader[JObject] = + new JsonReader[JObject] { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): JObject = { + if (!it.currentToken().isObjectStart) + ReaderError.wrongJson( + s"Expected object start but found: ${it.currentToken()}" + ) + else { + it.next() + val builder = List.newBuilder[(String, JValue)] + while (!it.currentToken().isObjectEnd) { + val token = it.currentToken() + if (token.isFieldName) { + val name = it.fieldName() + val value = json4sJValueReader.read(it.next())( + fieldName.appendFieldName(name) + ) + builder += name -> value + } else { + ReaderError.wrongJson( + s"Expect end of object or field name but '$token' found" + )(fieldName) + } } + it.next() + JObject(builder.result()) } - it.next() - JObject(builder.result()) } } - } - implicit lazy val json4sJArrayReader: JsonReader[JArray] = JsonReader[List[JValue]].map(JArray(_)) - implicit lazy val json4sJSetReader: JsonReader[JSet] = JsonReader[Set[JValue]].map(JSet(_)) + implicit lazy val json4sJArrayReader: JsonReader[JArray] = + JsonReader[List[JValue]].map(JArray(_)) + implicit lazy val json4sJSetReader: JsonReader[JSet] = + JsonReader[Set[JValue]].map(JSet(_)) - implicit lazy val json4sJValueReader: JsonReader[JValue] = new JsonReader[JValue] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): JValue = { - val token = it.currentToken() - if(token.isObjectStart) JsonReader[JObject].read(it) - else if (token.isArrayStart) JsonReader[JArray].read(it) - else if (token.isStringValue) JsonReader[JString].read(it) - else if (token.isBooleanValue) JsonReader[JBool].read(it) - else if (token.isNumberValue) JsonReader[Number].read(it) match { - case x@(_: java.lang.Short | _: java.lang.Integer | _: java.lang.Long) => JLong(x.longValue()) - case x@(_: java.lang.Float | _: java.lang.Double) => JDouble(x.doubleValue()) + implicit lazy val json4sJValueReader: JsonReader[JValue] = + new JsonReader[JValue] { + override def read( + it: TokenIterator + )(implicit fieldName: FieldName): JValue = { + val token = it.currentToken() + if (token.isObjectStart) JsonReader[JObject].read(it) + else if (token.isArrayStart) JsonReader[JArray].read(it) + else if (token.isStringValue) JsonReader[JString].read(it) + else if (token.isBooleanValue) JsonReader[JBool].read(it) + else if (token.isNumberValue) JsonReader[Number].read(it) match { + case x @ (_: java.lang.Short | _: java.lang.Integer | + _: java.lang.Long) => + JLong(x.longValue()) + case x @ (_: java.lang.Float | _: java.lang.Double) => + JDouble(x.doubleValue()) - case x: java.math.BigInteger => JInt(x) - case x: BigInt => JInt(x) + case x: java.math.BigInteger => JInt(x) + case x: BigInt => JInt(x) - case x: java.math.BigDecimal=> JDecimal(x) - case x: BigDecimal => JDecimal(x) - case x => JDecimal(x.doubleValue()) - } - else if (token.isNullValue) { - it.next() - JNull + case x: java.math.BigDecimal => JDecimal(x) + case x: BigDecimal => JDecimal(x) + case x => JDecimal(x.doubleValue()) + } + else if (token.isNullValue) { + it.next() + JNull + } else + ReaderError.wrongJson(s"Unexpected token found: $token")(fieldName) } - else ReaderError.wrongJson(s"Unexpected token found: $token")(fieldName) } - } } diff --git a/modules/json4s/src/test/scala/tethys/json4s/Json4sSupportTest.scala b/modules/json4s/src/test/scala/tethys/json4s/Json4sSupportTest.scala index 8d80e984..459c059b 100644 --- a/modules/json4s/src/test/scala/tethys/json4s/Json4sSupportTest.scala +++ b/modules/json4s/src/test/scala/tethys/json4s/Json4sSupportTest.scala @@ -18,11 +18,11 @@ class Json4sSupportTest extends AnyFlatSpec with Matchers { } it should "parse JDouble" in { - token(100.0D).tokensAs[JDouble] shouldBe JDouble(100.0D) + token(100.0d).tokensAs[JDouble] shouldBe JDouble(100.0d) } it should "parse JDecimal" in { - token(100.0D).tokensAs[JDecimal] shouldBe JDecimal(100.0D) + token(100.0d).tokensAs[JDecimal] shouldBe JDecimal(100.0d) } it should "parse JString" in { @@ -38,19 +38,26 @@ class Json4sSupportTest extends AnyFlatSpec with Matchers { } it should "parse JArray" in { - arr(1, 2L, 3).tokensAs[JArray] shouldBe JArray(List(JLong(1), JLong(2), JLong(3))) + arr(1, 2L, 3).tokensAs[JArray] shouldBe JArray( + List(JLong(1), JLong(2), JLong(3)) + ) } it should "parse JArray of JObject" in { - arr(obj("a" -> "b", "c" -> "d")).tokensAs[JValue] shouldBe JArray(List(JObject("a" -> JString("b"), "c" -> JString("d")))) + arr(obj("a" -> "b", "c" -> "d")).tokensAs[JValue] shouldBe JArray( + List(JObject("a" -> JString("b"), "c" -> JString("d"))) + ) } it should "parse JSet" in { - arr(1, 2L, 3).tokensAs[JSet] shouldBe JSet(Set(JLong(1), JLong(2), JLong(3))) + arr(1, 2L, 3).tokensAs[JSet] shouldBe JSet( + Set(JLong(1), JLong(2), JLong(3)) + ) } it should "parse JObject" in { - obj("a" -> arr(1), "b" -> obj("c" -> null)).tokensAs[JObject] shouldBe JObject( + obj("a" -> arr(1), "b" -> obj("c" -> null)) + .tokensAs[JObject] shouldBe JObject( "a" -> JArray(List(JLong(1L))), "b" -> JObject("c" -> JNull) ) @@ -66,11 +73,11 @@ class Json4sSupportTest extends AnyFlatSpec with Matchers { } it should "write JDouble" in { - JDouble(100.0D).asTokenList shouldBe token(100.0D) + JDouble(100.0d).asTokenList shouldBe token(100.0d) } it should "write JDecimal" in { - JDecimal(100.0D).asTokenList shouldBe token(BigDecimal(100.0D)) + JDecimal(100.0d).asTokenList shouldBe token(BigDecimal(100.0d)) } it should "write JString" in { @@ -86,7 +93,11 @@ class Json4sSupportTest extends AnyFlatSpec with Matchers { } it should "write JArray" in { - JArray(List(JLong(1), JLong(2), JLong(3))).asTokenList shouldBe arr(1L, 2L, 3L) + JArray(List(JLong(1), JLong(2), JLong(3))).asTokenList shouldBe arr( + 1L, + 2L, + 3L + ) } it should "write JSet" in { diff --git a/modules/macro-derivation/src/main/scala-3/tethys/derivation/AutoDerivation.scala b/modules/macro-derivation/src/main/scala-3/tethys/derivation/AutoDerivation.scala index a648ce88..fbb08636 100644 --- a/modules/macro-derivation/src/main/scala-3/tethys/derivation/AutoDerivation.scala +++ b/modules/macro-derivation/src/main/scala-3/tethys/derivation/AutoDerivation.scala @@ -4,11 +4,15 @@ import tethys.{JsonObjectWriter, JsonReader} import tethys.commons.LowPriorityInstance import scala.deriving.Mirror -@deprecated("Auto derivation is deprecated and will be removed in future versions. Use `derives` instead") +@deprecated( + "Auto derivation is deprecated and will be removed in future versions. Use `derives` instead" +) trait AutoDerivation { - implicit inline def jsonWriterMaterializer[T: Mirror.Of]: LowPriorityInstance[JsonObjectWriter[T]] = + implicit inline def jsonWriterMaterializer[T: Mirror.Of] + : LowPriorityInstance[JsonObjectWriter[T]] = LowPriorityInstance[JsonObjectWriter[T]](JsonObjectWriter.derived[T]) - implicit inline def jsonReaderMaterializer[T: Mirror.ProductOf]: LowPriorityInstance[JsonReader[T]] = + implicit inline def jsonReaderMaterializer[T: Mirror.ProductOf] + : LowPriorityInstance[JsonReader[T]] = LowPriorityInstance[JsonReader[T]](JsonReader.derived[T]) } diff --git a/modules/macro-derivation/src/main/scala-3/tethys/derivation/SemiautoDerivation.scala b/modules/macro-derivation/src/main/scala-3/tethys/derivation/SemiautoDerivation.scala index dd97ec7a..1bd98230 100644 --- a/modules/macro-derivation/src/main/scala-3/tethys/derivation/SemiautoDerivation.scala +++ b/modules/macro-derivation/src/main/scala-3/tethys/derivation/SemiautoDerivation.scala @@ -1,7 +1,12 @@ package tethys.derivation import tethys.{JsonObjectWriter, JsonReader, ReaderBuilder, WriterBuilder} -import tethys.derivation.builder.{ReaderDerivationConfig, ReaderDescription, WriterDerivationConfig, WriterDescription} +import tethys.derivation.builder.{ + ReaderDerivationConfig, + ReaderDescription, + WriterDerivationConfig, + WriterDescription +} import scala.deriving.Mirror @@ -39,27 +44,33 @@ trait SemiautoDerivation { """ ) - - @deprecated("Use JsonObjectWriter.derived instead") inline def jsonWriter[T](using mirror: Mirror.Of[T]): JsonObjectWriter[T] = failWriterDerivationForEnum[T] JsonObjectWriter.derived[T] - inline def jsonWriter[T](inline description: WriterDescription[T]): JsonObjectWriter[T] = + inline def jsonWriter[T]( + inline description: WriterDescription[T] + ): JsonObjectWriter[T] = scala.compiletime.error("Use WriterBuilder[T] directly") @deprecated("Use JsonObjectWriter.derived or derives instead") - inline def jsonWriter[T](inline builder: WriterBuilder[T])(using mirror: Mirror.ProductOf[T]): JsonObjectWriter[T] = + inline def jsonWriter[T](inline builder: WriterBuilder[T])(using + mirror: Mirror.ProductOf[T] + ): JsonObjectWriter[T] = failWriterDerivationForEnum[T] JsonObjectWriter.derived[T](builder) @deprecated("Use JsonObjectWriter.derived or derives instead") - inline def jsonWriter[T](inline config: WriterDerivationConfig)(using mirror: Mirror.Of[T]): JsonObjectWriter[T] = + inline def jsonWriter[T](inline config: WriterDerivationConfig)(using + mirror: Mirror.Of[T] + ): JsonObjectWriter[T] = JsonObjectWriter.derived[T](config) @deprecated("Use WriterBuilder[T] directly") - inline def describe[T <: Product](inline builder: WriterBuilder[T]): WriterBuilder[T] = + inline def describe[T <: Product]( + inline builder: WriterBuilder[T] + ): WriterBuilder[T] = scala.compiletime.error("Use WriterBuilder[T] directly") @deprecated("Use JsonReader.derived instead") @@ -67,19 +78,27 @@ trait SemiautoDerivation { failReaderDerivationForEnum[T] JsonReader.derived[T] - inline def jsonReader[T](inline description: ReaderDescription[T]): JsonReader[T] = + inline def jsonReader[T]( + inline description: ReaderDescription[T] + ): JsonReader[T] = scala.compiletime.error("Use ReaderBuilder[T] instead") @deprecated("Use JsonReader.derived or derives instead") - inline def jsonReader[T](inline config: ReaderDerivationConfig)(using mirror: Mirror.ProductOf[T]): JsonReader[T] = + inline def jsonReader[T](inline config: ReaderDerivationConfig)(using + mirror: Mirror.ProductOf[T] + ): JsonReader[T] = JsonReader.derived[T](config) @deprecated("Use JsonReader.derived and derives instead") - inline def jsonReader[T](inline builder: ReaderBuilder[T])(using mirror: Mirror.ProductOf[T]): JsonReader[T] = + inline def jsonReader[T](inline builder: ReaderBuilder[T])(using + mirror: Mirror.ProductOf[T] + ): JsonReader[T] = failReaderDerivationForEnum[T] JsonReader.derived(builder) @deprecated("Use ReaderBuilder[T] directly") - inline def describe[T <: Product](inline builder: ReaderBuilder[T]): ReaderBuilder[T] = + inline def describe[T <: Product]( + inline builder: ReaderBuilder[T] + ): ReaderBuilder[T] = builder } diff --git a/modules/macro-derivation/src/test/scala-3/tethys/derivation/ADTWithWrongType.scala b/modules/macro-derivation/src/test/scala-3/tethys/derivation/ADTWithWrongType.scala index ff242e00..66aa5d9e 100644 --- a/modules/macro-derivation/src/test/scala-3/tethys/derivation/ADTWithWrongType.scala +++ b/modules/macro-derivation/src/test/scala-3/tethys/derivation/ADTWithWrongType.scala @@ -6,6 +6,7 @@ object ADTWithWrongType { case class ADTWithWrongTypeA[A](a: A) extends ADTWithWrongType[A] - case class ADTWithWrongTypeB[A, B](a: A, b: ADTWithWrongType[B]) extends ADTWithWrongType[A] + case class ADTWithWrongTypeB[A, B](a: A, b: ADTWithWrongType[B]) + extends ADTWithWrongType[A] } diff --git a/modules/macro-derivation/src/test/scala-3/tethys/derivation/AutoReaderDerivationTest.scala b/modules/macro-derivation/src/test/scala-3/tethys/derivation/AutoReaderDerivationTest.scala index c9e26ebc..1b7cc6f8 100644 --- a/modules/macro-derivation/src/test/scala-3/tethys/derivation/AutoReaderDerivationTest.scala +++ b/modules/macro-derivation/src/test/scala-3/tethys/derivation/AutoReaderDerivationTest.scala @@ -18,18 +18,19 @@ class AutoReaderDerivationTest extends AnyFlatSpec with Matchers { res } - behavior of "auto derivation" it should "derive readers for simple case class hierarchy" in { - read[JsonTreeTestData](obj( - "a" -> 1, - "b" -> true, - "c" -> obj( - "d" -> obj( - "a" -> 2 + read[JsonTreeTestData]( + obj( + "a" -> 1, + "b" -> true, + "c" -> obj( + "d" -> obj( + "a" -> 2 + ) ) ) - )) shouldBe JsonTreeTestData( + ) shouldBe JsonTreeTestData( a = 1, b = true, c = C(D(2)) diff --git a/modules/macro-derivation/src/test/scala-3/tethys/derivation/AutoWriterDerivationTest.scala b/modules/macro-derivation/src/test/scala-3/tethys/derivation/AutoWriterDerivationTest.scala index 83cf9225..fa2a9dcf 100644 --- a/modules/macro-derivation/src/test/scala-3/tethys/derivation/AutoWriterDerivationTest.scala +++ b/modules/macro-derivation/src/test/scala-3/tethys/derivation/AutoWriterDerivationTest.scala @@ -27,29 +27,41 @@ class AutoWriterDerivationTest extends AnyFlatSpec with Matchers { } it should "auto derive writers for a lot of embedded classes" in { - Seq(SeqMaster1(Seq(SeqMaster2(Seq(SeqMaster3(Seq(SeqMaster4(Seq(1))))))))).asTokenList shouldBe arr( + Seq( + SeqMaster1(Seq(SeqMaster2(Seq(SeqMaster3(Seq(SeqMaster4(Seq(1)))))))) + ).asTokenList shouldBe arr( obj( - "a" -> arr(obj( - "a" -> arr(obj( - "a" -> arr(obj( - "a" -> arr(1) - )) - )) - )) + "a" -> arr( + obj( + "a" -> arr( + obj( + "a" -> arr( + obj( + "a" -> arr(1) + ) + ) + ) + ) + ) + ) ) ) } it should "auto derive writer that normally concatenates with other JsonObjectWriter's" in { - implicit def recursionTraitWithTypeWriter[B: JsonWriter]: JsonObjectWriter[ADTWithType[B]] = { - val simpleJsonObjectWriter = SimpleJsonObjectWriter[ADTWithType[B]].addField("clazz") { - case _: ADTWithTypeA[B] => "ADTWithTypeA" - case _: ADTWithTypeB[B] => "ADTWithTypeB" - } + implicit def recursionTraitWithTypeWriter[B: JsonWriter] + : JsonObjectWriter[ADTWithType[B]] = { + val simpleJsonObjectWriter = + SimpleJsonObjectWriter[ADTWithType[B]].addField("clazz") { + case _: ADTWithTypeA[B] => "ADTWithTypeA" + case _: ADTWithTypeB[B] => "ADTWithTypeB" + } simpleJsonObjectWriter ++ jsonWriter[ADTWithType[B]] } - (ADTWithTypeB[Int](1, ADTWithTypeA[Int](2)): ADTWithType[Int]).asTokenList shouldBe obj( + (ADTWithTypeB[Int](1, ADTWithTypeA[Int](2)): ADTWithType[ + Int + ]).asTokenList shouldBe obj( "clazz" -> "ADTWithTypeB", "a" -> 1, "b" -> obj( @@ -64,12 +76,16 @@ class AutoWriterDerivationTest extends AnyFlatSpec with Matchers { } it should "auto derive writer for simple sealed trait with hierarchy" in { - implicit val simpleClassWriter: JsonObjectWriter[SimpleClass] = JsonWriter.obj[SimpleClass].addField("b")(_.b) - implicit val justObjectWriter: JsonObjectWriter[JustObject.type] = JsonWriter.obj.addField("type")(_ => "JustObject") + implicit val simpleClassWriter: JsonObjectWriter[SimpleClass] = + JsonWriter.obj[SimpleClass].addField("b")(_.b) + implicit val justObjectWriter: JsonObjectWriter[JustObject.type] = + JsonWriter.obj.addField("type")(_ => "JustObject") - implicit val sealedWriter: JsonWriter[SimpleSealedType] = jsonWriter[SimpleSealedType] + implicit val sealedWriter: JsonWriter[SimpleSealedType] = + jsonWriter[SimpleSealedType] - def write(simpleSealedType: SimpleSealedType): List[TokenNode] = simpleSealedType.asTokenList + def write(simpleSealedType: SimpleSealedType): List[TokenNode] = + simpleSealedType.asTokenList write(CaseClass(1)) shouldBe obj("a" -> 1) write(new SimpleClass(2)) shouldBe obj("b" -> 2) diff --git a/modules/macro-derivation/src/test/scala-3/tethys/derivation/RedundantJsonReaderTest.scala b/modules/macro-derivation/src/test/scala-3/tethys/derivation/RedundantJsonReaderTest.scala index 89f8f657..c0518ea7 100644 --- a/modules/macro-derivation/src/test/scala-3/tethys/derivation/RedundantJsonReaderTest.scala +++ b/modules/macro-derivation/src/test/scala-3/tethys/derivation/RedundantJsonReaderTest.scala @@ -30,13 +30,16 @@ class RedundantJsonReaderTest extends AnyFlatSpec with Matchers { implicit val reader: JsonReader[BaseClass] = jsonReader[BaseClass] { describe { ReaderBuilder[BaseClass] - .extract(_.r).from[Int]("intField")(RedundantClass.apply) + .extract(_.r) + .from[Int]("intField")(RedundantClass.apply) } } - read[BaseClass](obj( - "intField" -> 1 - )) shouldBe BaseClass(RedundantClass(1)) + read[BaseClass]( + obj( + "intField" -> 1 + ) + ) shouldBe BaseClass(RedundantClass(1)) } } diff --git a/modules/macro-derivation/src/test/scala-3/tethys/derivation/SemiautoReaderDerivationTest.scala b/modules/macro-derivation/src/test/scala-3/tethys/derivation/SemiautoReaderDerivationTest.scala index f7d63ec6..573a03da 100644 --- a/modules/macro-derivation/src/test/scala-3/tethys/derivation/SemiautoReaderDerivationTest.scala +++ b/modules/macro-derivation/src/test/scala-3/tethys/derivation/SemiautoReaderDerivationTest.scala @@ -19,22 +19,24 @@ class SemiautoReaderDerivationTest extends AnyFlatSpec with Matchers { res } - behavior of "semiauto derivation" it should "derive readers for simple case class hierarchy" in { implicit val dReader: JsonReader[D] = jsonReader[D] implicit val cReader: JsonReader[C] = jsonReader[C] - implicit val jsonTreeTestDataReader: JsonReader[JsonTreeTestData] = jsonReader[JsonTreeTestData] - - read[JsonTreeTestData](obj( - "a" -> 1, - "b" -> true, - "c" -> obj( - "d" -> obj( - "a" -> 2 + implicit val jsonTreeTestDataReader: JsonReader[JsonTreeTestData] = + jsonReader[JsonTreeTestData] + + read[JsonTreeTestData]( + obj( + "a" -> 1, + "b" -> true, + "c" -> obj( + "d" -> obj( + "a" -> 2 + ) ) ) - )) shouldBe JsonTreeTestData( + ) shouldBe JsonTreeTestData( a = 1, b = true, c = C(D(2)) @@ -44,183 +46,231 @@ class SemiautoReaderDerivationTest extends AnyFlatSpec with Matchers { it should "derive reader for recursive type" in { given JsonReader[RecursiveType] = jsonReader[RecursiveType] - read[RecursiveType](obj( - "a" -> 1, - "children" -> arr( - obj( - "a" -> 2, - "children" -> arr() - ), - obj( - "a" -> 3, - "children" -> arr() + read[RecursiveType]( + obj( + "a" -> 1, + "children" -> arr( + obj( + "a" -> 2, + "children" -> arr() + ), + obj( + "a" -> 3, + "children" -> arr() + ) ) ) - )) shouldBe RecursiveType(1, Seq(RecursiveType(2), RecursiveType(3))) + ) shouldBe RecursiveType(1, Seq(RecursiveType(2), RecursiveType(3))) } it should "derive reader for A => B => A cycle" in { - implicit lazy val testReader1: JsonReader[ComplexRecursionA] = jsonReader[ComplexRecursionA] - implicit lazy val testReader2: JsonReader[ComplexRecursionB] = jsonReader[ComplexRecursionB] - - read[ComplexRecursionA](obj( - "a" -> 1, - "b" -> obj( - "b" -> 2, - "a" -> obj( - "a" -> 3 + implicit lazy val testReader1: JsonReader[ComplexRecursionA] = + jsonReader[ComplexRecursionA] + implicit lazy val testReader2: JsonReader[ComplexRecursionB] = + jsonReader[ComplexRecursionB] + + read[ComplexRecursionA]( + obj( + "a" -> 1, + "b" -> obj( + "b" -> 2, + "a" -> obj( + "a" -> 3 + ) ) ) - )) shouldBe ComplexRecursionA(1, Some(ComplexRecursionB(2, ComplexRecursionA(3, None)))) + ) shouldBe ComplexRecursionA( + 1, + Some(ComplexRecursionB(2, ComplexRecursionA(3, None))) + ) } it should "derive reader for extract as description" in { implicit val reader: JsonReader[SimpleType] = jsonReader[SimpleType] { describe { ReaderBuilder[SimpleType] - .extract(_.i).as[Option[Int]](_.getOrElse(2)) + .extract(_.i) + .as[Option[Int]](_.getOrElse(2)) } } - read[SimpleType](obj( - "i" -> 1, - "s" -> "str", - "d" -> 1.0 - )) shouldBe SimpleType(1, "str", 1.0) + read[SimpleType]( + obj( + "i" -> 1, + "s" -> "str", + "d" -> 1.0 + ) + ) shouldBe SimpleType(1, "str", 1.0) - read[SimpleType](obj( - "s" -> "str", - "d" -> 1.0 - )) shouldBe SimpleType(2, "str", 1.0) + read[SimpleType]( + obj( + "s" -> "str", + "d" -> 1.0 + ) + ) shouldBe SimpleType(2, "str", 1.0) } it should "derive reader for extract from description" in { implicit val reader: JsonReader[SimpleType] = jsonReader[SimpleType] { describe { ReaderBuilder[SimpleType] - .extract(_.i).from(_.s).and(_.d)((_, _) => 2) + .extract(_.i) + .from(_.s) + .and(_.d)((_, _) => 2) } } - read[SimpleType](obj( - "i" -> 1, - "s" -> "str", - "d" -> 1.0 - )) shouldBe SimpleType(2, "str", 1.0) + read[SimpleType]( + obj( + "i" -> 1, + "s" -> "str", + "d" -> 1.0 + ) + ) shouldBe SimpleType(2, "str", 1.0) - read[SimpleType](obj( - "s" -> "str", - "d" -> 1.0 - )) shouldBe SimpleType(2, "str", 1.0) + read[SimpleType]( + obj( + "s" -> "str", + "d" -> 1.0 + ) + ) shouldBe SimpleType(2, "str", 1.0) } - it should "derive reader for extract from description with synthetic field" in { implicit val reader: JsonReader[SimpleType] = jsonReader[SimpleType] { describe { ReaderBuilder[SimpleType] - .extract(_.i).from(_.d).and[Double]("e")((d, e) => (d + e).toInt) + .extract(_.i) + .from(_.d) + .and[Double]("e")((d, e) => (d + e).toInt) } } - read[SimpleType](obj( - "i" -> 1, - "s" -> "str", - "d" -> 1.0, - "e" -> 2.0 - )) shouldBe SimpleType(3, "str", 1.0) - - read[SimpleType](obj( - "s" -> "str", - "d" -> 1.0, - "e" -> 3.0 - )) shouldBe SimpleType(4, "str", 1.0) - } + read[SimpleType]( + obj( + "i" -> 1, + "s" -> "str", + "d" -> 1.0, + "e" -> 2.0 + ) + ) shouldBe SimpleType(3, "str", 1.0) + read[SimpleType]( + obj( + "s" -> "str", + "d" -> 1.0, + "e" -> 3.0 + ) + ) shouldBe SimpleType(4, "str", 1.0) + } it should "derive reader for extract reader from description" in { - implicit val reader: JsonReader[SimpleTypeWithAny] = jsonReader[SimpleTypeWithAny] { - describe { - ReaderBuilder[SimpleTypeWithAny] - .extractReader(_.any).from(_.d) { - case 1.0 => JsonReader[String] - case 2.0 => JsonReader[Int] + implicit val reader: JsonReader[SimpleTypeWithAny] = + jsonReader[SimpleTypeWithAny] { + describe { + ReaderBuilder[SimpleTypeWithAny] + .extractReader(_.any) + .from(_.d) { + case 1.0 => JsonReader[String] + case 2.0 => JsonReader[Int] + } } } - } - read[SimpleTypeWithAny](obj( - "i" -> 1, - "s" -> "str", - "d" -> 1.0, - "any" -> "anyStr" - )) shouldBe SimpleTypeWithAny(1, "str", 1.0, "anyStr") - - read[SimpleTypeWithAny](obj( - "i" -> 1, - "s" -> "str", - "d" -> 2.0, - "any" -> 2 - )) shouldBe SimpleTypeWithAny(1, "str", 2.0, 2) + read[SimpleTypeWithAny]( + obj( + "i" -> 1, + "s" -> "str", + "d" -> 1.0, + "any" -> "anyStr" + ) + ) shouldBe SimpleTypeWithAny(1, "str", 1.0, "anyStr") + + read[SimpleTypeWithAny]( + obj( + "i" -> 1, + "s" -> "str", + "d" -> 2.0, + "any" -> 2 + ) + ) shouldBe SimpleTypeWithAny(1, "str", 2.0, 2) } it should "derive reader for complex extraction case" in { - implicit val reader: JsonReader[SimpleTypeWithAny] = jsonReader[SimpleTypeWithAny] { - ReaderBuilder[SimpleTypeWithAny] - .extractReader(_.any).from(_.i) { - case 1 => JsonReader[String] - case 2 => JsonReader[Int] - case _ => JsonReader[Option[Boolean]] + implicit val reader: JsonReader[SimpleTypeWithAny] = + jsonReader[SimpleTypeWithAny] { + ReaderBuilder[SimpleTypeWithAny] + .extractReader(_.any) + .from(_.i) { + case 1 => JsonReader[String] + case 2 => JsonReader[Int] + case _ => JsonReader[Option[Boolean]] + } + .extract(_.i) + .from(_.d) + .and[Int]("e")((d, e) => d.toInt + e) + .extract(_.d) + .as[Option[Double]](_.getOrElse(1.0)) } - .extract(_.i).from(_.d).and[Int]("e")((d, e) => d.toInt + e) - .extract(_.d).as[Option[Double]](_.getOrElse(1.0)) - } - read[SimpleTypeWithAny](obj( - "s" -> "str", - "d" -> 1.0, - "e" -> 0, - "any" -> "anyStr" - )) shouldBe SimpleTypeWithAny(1, "str", 1.0, "anyStr") - - read[SimpleTypeWithAny](obj( - "s" -> "str", - "e" -> 0, - "any" -> "anyStr" - )) shouldBe SimpleTypeWithAny(1, "str", 1.0, "anyStr") - - read[SimpleTypeWithAny](obj( - "s" -> "str", - "d" -> 1.0, - "e" -> 1, - "any" -> 3 - )) shouldBe SimpleTypeWithAny(2, "str", 1.0, 3) - - read[SimpleTypeWithAny](obj( - "s" -> "str", - "d" -> 1.0, - "e" -> 2, - "any" -> true - )) shouldBe SimpleTypeWithAny(3, "str", 1.0, Some(true)) - - read[SimpleTypeWithAny](obj( - "s" -> "str", - "d" -> 1.0, - "e" -> 2 - )) shouldBe SimpleTypeWithAny(3, "str", 1.0, None) + read[SimpleTypeWithAny]( + obj( + "s" -> "str", + "d" -> 1.0, + "e" -> 0, + "any" -> "anyStr" + ) + ) shouldBe SimpleTypeWithAny(1, "str", 1.0, "anyStr") + + read[SimpleTypeWithAny]( + obj( + "s" -> "str", + "e" -> 0, + "any" -> "anyStr" + ) + ) shouldBe SimpleTypeWithAny(1, "str", 1.0, "anyStr") + + read[SimpleTypeWithAny]( + obj( + "s" -> "str", + "d" -> 1.0, + "e" -> 1, + "any" -> 3 + ) + ) shouldBe SimpleTypeWithAny(2, "str", 1.0, 3) + + read[SimpleTypeWithAny]( + obj( + "s" -> "str", + "d" -> 1.0, + "e" -> 2, + "any" -> true + ) + ) shouldBe SimpleTypeWithAny(3, "str", 1.0, Some(true)) + + read[SimpleTypeWithAny]( + obj( + "s" -> "str", + "d" -> 1.0, + "e" -> 2 + ) + ) shouldBe SimpleTypeWithAny(3, "str", 1.0, None) } it should "derive reader for fieldStyle from description" in { - implicit val reader: JsonReader[CamelCaseNames] = jsonReader[CamelCaseNames] { - ReaderBuilder[CamelCaseNames].fieldStyle(FieldStyle.LowerSnakeCase) - } + implicit val reader: JsonReader[CamelCaseNames] = + jsonReader[CamelCaseNames] { + ReaderBuilder[CamelCaseNames].fieldStyle(FieldStyle.LowerSnakeCase) + } - read[CamelCaseNames](obj( - "some_param" -> 1, - "id_param" -> 2, - "simple" -> 3 - )) shouldBe CamelCaseNames( + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "id_param" -> 2, + "simple" -> 3 + ) + ) shouldBe CamelCaseNames( someParam = 1, IDParam = 2, simple = 3 @@ -228,15 +278,18 @@ class SemiautoReaderDerivationTest extends AnyFlatSpec with Matchers { } it should "derive reader for fieldStyle from function in description" in { - implicit val reader: JsonReader[CamelCaseNames] = jsonReader[CamelCaseNames] { - ReaderBuilder[CamelCaseNames].fieldStyle(FieldStyle.Capitalize) - } + implicit val reader: JsonReader[CamelCaseNames] = + jsonReader[CamelCaseNames] { + ReaderBuilder[CamelCaseNames].fieldStyle(FieldStyle.Capitalize) + } - read[CamelCaseNames](obj( - "SomeParam" -> 1, - "IDParam" -> 2, - "Simple" -> 3 - )) shouldBe CamelCaseNames( + read[CamelCaseNames]( + obj( + "SomeParam" -> 1, + "IDParam" -> 2, + "Simple" -> 3 + ) + ) shouldBe CamelCaseNames( someParam = 1, IDParam = 2, simple = 3 @@ -247,74 +300,86 @@ class SemiautoReaderDerivationTest extends AnyFlatSpec with Matchers { implicit val reader: JsonReader[SimpleType] = jsonReader[SimpleType] { describe { ReaderBuilder[SimpleType] - .extract(_.i).as[String](_.toInt) + .extract(_.i) + .as[String](_.toInt) } } - read[SimpleType](obj( - "i" -> "1", - "s" -> "str", - "d" -> 1.0 - )) shouldBe SimpleType(1, "str", 1.0) + read[SimpleType]( + obj( + "i" -> "1", + "s" -> "str", + "d" -> 1.0 + ) + ) shouldBe SimpleType(1, "str", 1.0) } it should "derive reader for reader config" in { - implicit val reader: JsonReader[CamelCaseNames] = jsonReader[CamelCaseNames]( + implicit val reader + : JsonReader[CamelCaseNames] = jsonReader[CamelCaseNames]( ReaderBuilder[CamelCaseNames].fieldStyle(FieldStyle.LowerSnakeCase).strict ) - read[CamelCaseNames](obj( - "some_param" -> 1, - "id_param" -> 2, - "simple" -> 3 - )) shouldBe CamelCaseNames( + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "id_param" -> 2, + "simple" -> 3 + ) + ) shouldBe CamelCaseNames( someParam = 1, IDParam = 2, simple = 3 ) (the[ReaderError] thrownBy { - read[CamelCaseNames](obj( - "some_param" -> 1, - "not_id_param" -> 2, - "simple" -> 3 - )) + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "not_id_param" -> 2, + "simple" -> 3 + ) + ) }).getMessage shouldBe "Illegal json at '[ROOT]': unexpected field 'not_id_param', expected one of 'some_param', 'id_param', 'simple'" } it should "derive reader for reader config from builder" in { - implicit val reader: JsonReader[CamelCaseNames] = jsonReader[CamelCaseNames]( - ReaderBuilder[CamelCaseNames] - .strict - .fieldStyle(FieldStyle.LowerSnakeCase) - ) + implicit val reader: JsonReader[CamelCaseNames] = + jsonReader[CamelCaseNames]( + ReaderBuilder[CamelCaseNames].strict + .fieldStyle(FieldStyle.LowerSnakeCase) + ) - read[CamelCaseNames](obj( - "some_param" -> 1, - "id_param" -> 2, - "simple" -> 3 - )) shouldBe CamelCaseNames( + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "id_param" -> 2, + "simple" -> 3 + ) + ) shouldBe CamelCaseNames( someParam = 1, IDParam = 2, simple = 3 ) (the[ReaderError] thrownBy { - read[CamelCaseNames](obj( - "some_param" -> 1, - "not_id_param" -> 2, - "simple" -> 3 - )) + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "not_id_param" -> 2, + "simple" -> 3 + ) + ) }).getMessage shouldBe "Illegal json at '[ROOT]': unexpected field 'not_id_param', expected one of 'some_param', 'id_param', 'simple'" } - it should "derive reader for simple enum" in { - implicit val simpleEnumReader: JsonReader[SimpleEnum] = StringEnumJsonReader.derived + implicit val simpleEnumReader: JsonReader[SimpleEnum] = + StringEnumJsonReader.derived read[SimpleEnum]( token(SimpleEnum.ONE.toString) - )shouldBe SimpleEnum.ONE + ) shouldBe SimpleEnum.ONE read[SimpleEnum]( token(SimpleEnum.TWO.toString) @@ -322,7 +387,8 @@ class SemiautoReaderDerivationTest extends AnyFlatSpec with Matchers { } it should "derive reader for parametrized enum" in { - implicit val parametrizedEnumReader: JsonReader[ParametrizedEnum] = StringEnumJsonReader.derived + implicit val parametrizedEnumReader: JsonReader[ParametrizedEnum] = + StringEnumJsonReader.derived read[ParametrizedEnum]( token(ParametrizedEnum.ONE.toString) @@ -338,11 +404,13 @@ class SemiautoReaderDerivationTest extends AnyFlatSpec with Matchers { ReaderDerivationConfig.withFieldStyle(FieldStyle.LowerSnakeCase) } - read[CamelCaseNames](obj( - "some_param" -> 1, - "id_param" -> 2, - "simple" -> 3 - )) shouldBe CamelCaseNames( + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "id_param" -> 2, + "simple" -> 3 + ) + ) shouldBe CamelCaseNames( someParam = 1, IDParam = 2, simple = 3 @@ -354,11 +422,13 @@ class SemiautoReaderDerivationTest extends AnyFlatSpec with Matchers { ReaderDerivationConfig.empty.withFieldStyle(FieldStyle.LowerSnakeCase) } - read[CamelCaseNames](obj( - "some_param" -> 1, - "id_param" -> 2, - "simple" -> 3 - )) shouldBe CamelCaseNames( + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "id_param" -> 2, + "simple" -> 3 + ) + ) shouldBe CamelCaseNames( someParam = 1, IDParam = 2, simple = 3 @@ -366,51 +436,61 @@ class SemiautoReaderDerivationTest extends AnyFlatSpec with Matchers { } it should "derive strict reader" in { - implicit val reader: JsonReader[CamelCaseNames] = jsonReader[CamelCaseNames]( - ReaderDerivationConfig.withFieldStyle(FieldStyle.LowerSnakeCase).strict - ) + implicit val reader: JsonReader[CamelCaseNames] = + jsonReader[CamelCaseNames]( + ReaderDerivationConfig.withFieldStyle(FieldStyle.LowerSnakeCase).strict + ) - read[CamelCaseNames](obj( - "some_param" -> 1, - "id_param" -> 2, - "simple" -> 3 - )) shouldBe CamelCaseNames( + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "id_param" -> 2, + "simple" -> 3 + ) + ) shouldBe CamelCaseNames( someParam = 1, IDParam = 2, simple = 3 ) (the[ReaderError] thrownBy { - read[CamelCaseNames](obj( - "some_param" -> 1, - "not_id_param" -> 2, - "simple" -> 3 - )) + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "not_id_param" -> 2, + "simple" -> 3 + ) + ) }).getMessage shouldBe "Illegal json at '[ROOT]': unexpected field 'not_id_param', expected one of 'some_param', 'id_param', 'simple'" } it should "derive strict reader with legacy field style" in { import tethys.derivation.builder.FieldStyle - implicit val reader: JsonReader[CamelCaseNames] = jsonReader[CamelCaseNames]( - ReaderDerivationConfig.withFieldStyle(FieldStyle.lowerSnakeCase).strict - ) + implicit val reader: JsonReader[CamelCaseNames] = + jsonReader[CamelCaseNames]( + ReaderDerivationConfig.withFieldStyle(FieldStyle.lowerSnakeCase).strict + ) - read[CamelCaseNames](obj( - "some_param" -> 1, - "id_param" -> 2, - "simple" -> 3 - )) shouldBe CamelCaseNames( + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "id_param" -> 2, + "simple" -> 3 + ) + ) shouldBe CamelCaseNames( someParam = 1, IDParam = 2, simple = 3 ) (the[ReaderError] thrownBy { - read[CamelCaseNames](obj( - "some_param" -> 1, - "not_id_param" -> 2, - "simple" -> 3 - )) + read[CamelCaseNames]( + obj( + "some_param" -> 1, + "not_id_param" -> 2, + "simple" -> 3 + ) + ) }).getMessage shouldBe "Illegal json at '[ROOT]': unexpected field 'not_id_param', expected one of 'some_param', 'id_param', 'simple'" } diff --git a/modules/macro-derivation/src/test/scala-3/tethys/derivation/SemiautoWriterDerivationTest.scala b/modules/macro-derivation/src/test/scala-3/tethys/derivation/SemiautoWriterDerivationTest.scala index bbe39f57..49123d26 100644 --- a/modules/macro-derivation/src/test/scala-3/tethys/derivation/SemiautoWriterDerivationTest.scala +++ b/modules/macro-derivation/src/test/scala-3/tethys/derivation/SemiautoWriterDerivationTest.scala @@ -17,12 +17,14 @@ class SemiautoWriterDerivationTest extends AnyFlatSpec with Matchers { behavior of "semiauto derivation" it should "generate proper writer from WriterBuilder" in { def freeVariable: String = "e" - implicit val dWriter: JsonWriter[D] = jsonWriter[D](WriterBuilder[D].fieldStyle(FieldStyle.UpperCase)) + implicit val dWriter: JsonWriter[D] = + jsonWriter[D](WriterBuilder[D].fieldStyle(FieldStyle.UpperCase)) implicit val testWriter: JsonWriter[JsonTreeTestData] = jsonWriter { WriterBuilder[JsonTreeTestData] .remove(_.b) - .update(_.a).fromRoot(d => d.a.toDouble + d.c.d.a) + .update(_.a) + .fromRoot(d => d.a.toDouble + d.c.d.a) .update(_.c)(_.d) .add("d")(_.a * 2) .add(freeVariable)(_.b) @@ -41,7 +43,9 @@ class SemiautoWriterDerivationTest extends AnyFlatSpec with Matchers { def freeVariable: String = "e" implicit val dWriter: JsonWriter[D] = jsonWriter[D]( - WriterDerivationConfig.withFieldStyle(tethys.derivation.builder.FieldStyle.uppercase) + WriterDerivationConfig.withFieldStyle( + tethys.derivation.builder.FieldStyle.uppercase + ) ) implicit val testWriter: JsonWriter[JsonTreeTestData] = jsonWriter { @@ -62,10 +66,10 @@ class SemiautoWriterDerivationTest extends AnyFlatSpec with Matchers { implicit val partialWriter: JsonWriter[D] = jsonWriter { WriterBuilder[D] .updatePartial(_.a) { - case 1 => "uno!" - case 2 => 1 + case 1 => "uno!" + case 2 => 1 case v if v > 0 => v * 2 - case _ => throw new IllegalArgumentException("Wrong value!") + case _ => throw new IllegalArgumentException("Wrong value!") } } @@ -81,10 +85,11 @@ class SemiautoWriterDerivationTest extends AnyFlatSpec with Matchers { it should "derive writer for update partial from root" in { implicit val partialWriter: JsonWriter[D] = jsonWriter { WriterBuilder[D] - .updatePartial(_.a).fromRoot { + .updatePartial(_.a) + .fromRoot { case d if d.a == 1 => "uno!" case d if d.a == 2 => 1 - case d if d.a > 0 => d.a * 2 + case d if d.a > 0 => d.a * 2 case _ => throw new IllegalArgumentException("Wrong value!") } } @@ -103,7 +108,8 @@ class SemiautoWriterDerivationTest extends AnyFlatSpec with Matchers { } it should "derive writer for recursive type" in { - implicit lazy val testWriter: JsonWriter[RecursiveType] = jsonWriter[RecursiveType] + implicit lazy val testWriter: JsonWriter[RecursiveType] = + jsonWriter[RecursiveType] RecursiveType(1, Seq(RecursiveType(2))).asTokenList shouldBe obj( "a" -> 1, @@ -117,10 +123,15 @@ class SemiautoWriterDerivationTest extends AnyFlatSpec with Matchers { } it should "derive writer for A => B => A cycle" in { - implicit lazy val testWriter1: JsonWriter[ComplexRecursionA] = jsonWriter[ComplexRecursionA] - implicit lazy val testWriter2: JsonWriter[ComplexRecursionB] = jsonWriter[ComplexRecursionB] - - ComplexRecursionA(1, Some(ComplexRecursionB(2, ComplexRecursionA(3, None)))).asTokenList shouldBe obj( + implicit lazy val testWriter1: JsonWriter[ComplexRecursionA] = + jsonWriter[ComplexRecursionA] + implicit lazy val testWriter2: JsonWriter[ComplexRecursionB] = + jsonWriter[ComplexRecursionB] + + ComplexRecursionA( + 1, + Some(ComplexRecursionB(2, ComplexRecursionA(3, None))) + ).asTokenList shouldBe obj( "a" -> 1, "b" -> obj( "b" -> 2, @@ -132,11 +143,16 @@ class SemiautoWriterDerivationTest extends AnyFlatSpec with Matchers { } it should "derive writer for sealed cyclic trait with type parameter" in { - implicit def recursionTraitWithTypeWriter[B: JsonWriter]: JsonObjectWriter[ADTWithType[B]] = jsonWriter[ADTWithType[B]] - implicit def recursionTraitWithTypeAWriter[B: JsonWriter]: JsonObjectWriter[ADTWithTypeA[B]] = jsonWriter[ADTWithTypeA[B]] - implicit def recursionTraitWithTypeBWriter[B: JsonWriter]: JsonObjectWriter[ADTWithTypeB[B]] = jsonWriter[ADTWithTypeB[B]] - - (ADTWithTypeB[Int](1, ADTWithTypeA[Int](2)): ADTWithType[Int]).asTokenList shouldBe obj( + implicit def recursionTraitWithTypeWriter[B: JsonWriter] + : JsonObjectWriter[ADTWithType[B]] = jsonWriter[ADTWithType[B]] + implicit def recursionTraitWithTypeAWriter[B: JsonWriter] + : JsonObjectWriter[ADTWithTypeA[B]] = jsonWriter[ADTWithTypeA[B]] + implicit def recursionTraitWithTypeBWriter[B: JsonWriter] + : JsonObjectWriter[ADTWithTypeB[B]] = jsonWriter[ADTWithTypeB[B]] + + (ADTWithTypeB[Int](1, ADTWithTypeA[Int](2)): ADTWithType[ + Int + ]).asTokenList shouldBe obj( "a" -> 1, "b" -> obj( "a" -> 2 @@ -145,19 +161,25 @@ class SemiautoWriterDerivationTest extends AnyFlatSpec with Matchers { } it should "derive writer that normally concatenates with other JsonWriter's" in { - implicit def recursionTraitWithTypeWriter[B: JsonWriter]: JsonWriter[ADTWithType[B]] = { - val simpleJsonWriter = SimpleJsonObjectWriter[ADTWithType[B]].addField("clazz") { - case _: ADTWithTypeA[B] => "ADTWithTypeA" - case _: ADTWithTypeB[B] => "ADTWithTypeB" - } + implicit def recursionTraitWithTypeWriter[B: JsonWriter] + : JsonWriter[ADTWithType[B]] = { + val simpleJsonWriter = + SimpleJsonObjectWriter[ADTWithType[B]].addField("clazz") { + case _: ADTWithTypeA[B] => "ADTWithTypeA" + case _: ADTWithTypeB[B] => "ADTWithTypeB" + } simpleJsonWriter ++ jsonWriter[ADTWithType[B]] } - implicit def recursionTraitWithTypeAWriter[B: JsonWriter]: JsonObjectWriter[ADTWithTypeA[B]] = jsonWriter[ADTWithTypeA[B]] + implicit def recursionTraitWithTypeAWriter[B: JsonWriter] + : JsonObjectWriter[ADTWithTypeA[B]] = jsonWriter[ADTWithTypeA[B]] - implicit def recursionTraitWithTypeBWriter[B: JsonWriter]: JsonObjectWriter[ADTWithTypeB[B]] = jsonWriter[ADTWithTypeB[B]] + implicit def recursionTraitWithTypeBWriter[B: JsonWriter] + : JsonObjectWriter[ADTWithTypeB[B]] = jsonWriter[ADTWithTypeB[B]] - (ADTWithTypeB[Int](1, ADTWithTypeA[Int](2)): ADTWithType[Int]).asTokenList shouldBe obj( + (ADTWithTypeB[Int](1, ADTWithTypeA[Int](2)): ADTWithType[ + Int + ]).asTokenList shouldBe obj( "clazz" -> "ADTWithTypeB", "a" -> 1, "b" -> obj( @@ -176,33 +198,46 @@ class SemiautoWriterDerivationTest extends AnyFlatSpec with Matchers { } it should "derive writer for simple sealed trait with hierarchy" in { - implicit val caseClassWriter: JsonObjectWriter[CaseClass] = jsonWriter[CaseClass] - implicit val simpleClassWriter: JsonObjectWriter[SimpleClass] = JsonWriter.obj[SimpleClass].addField("b")(_.b) - implicit val justObjectWriter: JsonObjectWriter[JustObject.type] = JsonWriter.obj.addField("type")(_ => "JustObject") - implicit val subChildWriter: JsonObjectWriter[SubChild] = jsonWriter[SubChild] - - implicit val sealedSubWriter: JsonObjectWriter[SimpleSealedTypeSub] = jsonWriter[SimpleSealedTypeSub] - implicit val sealedWriter: JsonWriter[SimpleSealedType] = jsonWriter[SimpleSealedType] - - def write(simpleSealedType: SimpleSealedType): List[TokenNode] = simpleSealedType.asTokenList + implicit val caseClassWriter: JsonObjectWriter[CaseClass] = + jsonWriter[CaseClass] + implicit val simpleClassWriter: JsonObjectWriter[SimpleClass] = + JsonWriter.obj[SimpleClass].addField("b")(_.b) + implicit val justObjectWriter: JsonObjectWriter[JustObject.type] = + JsonWriter.obj.addField("type")(_ => "JustObject") + implicit val subChildWriter: JsonObjectWriter[SubChild] = + jsonWriter[SubChild] + + implicit val sealedSubWriter: JsonObjectWriter[SimpleSealedTypeSub] = + jsonWriter[SimpleSealedTypeSub] + implicit val sealedWriter: JsonWriter[SimpleSealedType] = + jsonWriter[SimpleSealedType] + + def write(simpleSealedType: SimpleSealedType): List[TokenNode] = + simpleSealedType.asTokenList write(CaseClass(1)) shouldBe obj("a" -> 1) - write(SimpleClass(2)) shouldBe obj( "b" -> 2) + write(SimpleClass(2)) shouldBe obj("b" -> 2) write(JustObject) shouldBe obj("type" -> "JustObject") write(SubChild(3)) shouldBe obj("c" -> 3) } it should "derive writer for simple sealed trait with hierarchy with discriminator" in { - implicit val caseClassWriter: JsonObjectWriter[CaseClass] = jsonWriter[CaseClass] - implicit val simpleClassWriter: JsonObjectWriter[SimpleClass] = JsonWriter.obj[SimpleClass].addField("b")(_.b) - implicit val justObjectWriter: JsonObjectWriter[JustObject.type] = JsonWriter.obj - implicit val subChildWriter: JsonObjectWriter[SubChild] = jsonWriter[SubChild] - - implicit val sealedWriter: JsonWriter[SimpleSealedType] = jsonWriter[SimpleSealedType] { - WriterDerivationConfig.withDiscriminator("__type") - } + implicit val caseClassWriter: JsonObjectWriter[CaseClass] = + jsonWriter[CaseClass] + implicit val simpleClassWriter: JsonObjectWriter[SimpleClass] = + JsonWriter.obj[SimpleClass].addField("b")(_.b) + implicit val justObjectWriter: JsonObjectWriter[JustObject.type] = + JsonWriter.obj + implicit val subChildWriter: JsonObjectWriter[SubChild] = + jsonWriter[SubChild] + + implicit val sealedWriter: JsonWriter[SimpleSealedType] = + jsonWriter[SimpleSealedType] { + WriterDerivationConfig.withDiscriminator("__type") + } - def write(simpleSealedType: SimpleSealedType): List[TokenNode] = simpleSealedType.asTokenList + def write(simpleSealedType: SimpleSealedType): List[TokenNode] = + simpleSealedType.asTokenList write(CaseClass(1)) shouldBe obj("__type" -> "CaseClass", "a" -> 1) write(new SimpleClass(2)) shouldBe obj("__type" -> "SimpleClass", "b" -> 2) @@ -211,30 +246,34 @@ class SemiautoWriterDerivationTest extends AnyFlatSpec with Matchers { } it should "derive writer for simple enum" in { - implicit val simpleEnumWriter: JsonWriter[SimpleEnum] = StringEnumJsonWriter.derived - + implicit val simpleEnumWriter: JsonWriter[SimpleEnum] = + StringEnumJsonWriter.derived + SimpleEnum.ONE.asTokenList shouldBe token("ONE") SimpleEnum.TWO.asTokenList shouldBe token("TWO") } it should "derive writer for parametrized enum" in { - implicit val parametrizedEnumWriter: JsonWriter[ParametrizedEnum] = StringEnumJsonWriter.derived + implicit val parametrizedEnumWriter: JsonWriter[ParametrizedEnum] = + StringEnumJsonWriter.derived ParametrizedEnum.ONE.asTokenList shouldBe token("ONE") ParametrizedEnum.TWO.asTokenList shouldBe token("TWO") } it should "derive writer with discriminator for simple enum" in { - implicit val simpleEnumWriter: JsonWriter[SimpleEnum] = StringEnumJsonWriter.withLabel("__type") + implicit val simpleEnumWriter: JsonWriter[SimpleEnum] = + StringEnumJsonWriter.withLabel("__type") SimpleEnum.ONE.asTokenList shouldBe obj("__type" -> "ONE") SimpleEnum.TWO.asTokenList shouldBe obj("__type" -> "TWO") } it should "derive writer with discriminator for parametrized enum" in { - implicit val simpleEnumWriter: JsonWriter[ParametrizedEnum] = StringEnumJsonWriter.withLabel("__type") + implicit val simpleEnumWriter: JsonWriter[ParametrizedEnum] = + StringEnumJsonWriter.withLabel("__type") - ParametrizedEnum.ONE.asTokenList shouldBe obj ("__type" -> "ONE") - ParametrizedEnum.TWO.asTokenList shouldBe obj ("__type" -> "TWO") + ParametrizedEnum.ONE.asTokenList shouldBe obj("__type" -> "ONE") + ParametrizedEnum.TWO.asTokenList shouldBe obj("__type" -> "TWO") } } diff --git a/modules/macro-derivation/src/test/scala-3/tethys/derivation/WriterRenamingSyntaxTest.scala b/modules/macro-derivation/src/test/scala-3/tethys/derivation/WriterRenamingSyntaxTest.scala index b9d17ef0..59836ed0 100644 --- a/modules/macro-derivation/src/test/scala-3/tethys/derivation/WriterRenamingSyntaxTest.scala +++ b/modules/macro-derivation/src/test/scala-3/tethys/derivation/WriterRenamingSyntaxTest.scala @@ -46,7 +46,7 @@ class WriterRenamingSyntaxTest extends AnyFlatSpec with Matchers { it should "rename field on update from root" in { implicit val writer: JsonWriter[D] = jsonWriter[D] { WriterBuilder[D].update(_.a).withRename("b").fromRoot(_.a * 2) - + } D(1).asTokenList shouldBe obj( diff --git a/modules/macro-derivation/src/test/scala-3/tethys/derivation/package.scala b/modules/macro-derivation/src/test/scala-3/tethys/derivation/package.scala index a528b93e..99e81ca6 100644 --- a/modules/macro-derivation/src/test/scala-3/tethys/derivation/package.scala +++ b/modules/macro-derivation/src/test/scala-3/tethys/derivation/package.scala @@ -8,7 +8,6 @@ package object derivation { case class C(d: D) case class D(a: Int) - case class RecursiveType(a: Int, children: Seq[RecursiveType] = Seq.empty) case class ComplexRecursionA(a: Int, b: Option[ComplexRecursionB]) diff --git a/modules/refined/src/main/scala/tethys/refined/TethysRefinedInstances.scala b/modules/refined/src/main/scala/tethys/refined/TethysRefinedInstances.scala index 103a23f6..d9564674 100644 --- a/modules/refined/src/main/scala/tethys/refined/TethysRefinedInstances.scala +++ b/modules/refined/src/main/scala/tethys/refined/TethysRefinedInstances.scala @@ -6,26 +6,31 @@ import tethys.readers.tokens.TokenIterator import tethys.{JsonReader, JsonWriter} trait TethysRefinedInstances { - implicit final def RefinedJsonWriter[T: JsonWriter, P, F[_, _]: RefType]: JsonWriter[F[T, P]] = + implicit final def RefinedJsonWriter[T: JsonWriter, P, F[_, _]: RefType] + : JsonWriter[F[T, P]] = JsonWriter[T].contramap(RefType[F].unwrap) implicit final def RefinedJsonReader[T: JsonReader, P, F[_, _]: RefType]( - implicit validate: Validate[T, P] + implicit validate: Validate[T, P] ): JsonReader[F[T, P]] = new JsonReader[F[T, P]] { - override def read(it: TokenIterator)(implicit fieldName: FieldName): F[T, P] = + override def read(it: TokenIterator)(implicit + fieldName: FieldName + ): F[T, P] = fromEither(RefType[F].refine(JsonReader[T].read(it))) } - implicit final def RefinedKeyReader[T, P, F[_, _]: RefType]( - implicit reader: KeyReader[T], - validate: Validate[T, P] + implicit final def RefinedKeyReader[T, P, F[_, _]: RefType](implicit + reader: KeyReader[T], + validate: Validate[T, P] ): KeyReader[F[T, P]] = new KeyReader[F[T, P]] { override def read(s: String)(implicit fieldName: FieldName): F[T, P] = fromEither(RefType[F].refine(reader.read(s))) } - private def fromEither[A](either: Either[String, A])(implicit fieldName: FieldName): A = + private def fromEither[A]( + either: Either[String, A] + )(implicit fieldName: FieldName): A = either match { case Right(value) => value case Left(err) => ReaderError.wrongJson(s"Refined error: $err") diff --git a/modules/refined/src/test/scala/tethys/refined/RefinedSupportTest.scala b/modules/refined/src/test/scala/tethys/refined/RefinedSupportTest.scala index cfacba6f..64777a24 100644 --- a/modules/refined/src/test/scala/tethys/refined/RefinedSupportTest.scala +++ b/modules/refined/src/test/scala/tethys/refined/RefinedSupportTest.scala @@ -133,10 +133,15 @@ class RefinedSupportTest extends AnyFlatSpec with Matchers { it should "work with refined strings" in { type Limits = Map[String Refined IPv4, Int] - val limits: Limits = Map(refineV[IPv4].unsafeFrom("192.168.0.1") -> 1, refineV[IPv4].unsafeFrom("192.168.1.1") -> 2) + val limits: Limits = Map( + refineV[IPv4].unsafeFrom("192.168.0.1") -> 1, + refineV[IPv4].unsafeFrom("192.168.1.1") -> 2 + ) obj("192.168.0.1" -> 1, "192.168.1.1" -> 2).tokensAs[Limits] shouldBe limits - assertThrows[ReaderError](obj("192.168.0.1" -> 1, "192.168.256.1" -> 2).tokensAs[Limits]) + assertThrows[ReaderError]( + obj("192.168.0.1" -> 1, "192.168.256.1" -> 2).tokensAs[Limits] + ) } } diff --git a/project/JsonReaderBuilderGenerator.scala b/project/JsonReaderBuilderGenerator.scala index 1eff962b..e9a52801 100644 --- a/project/JsonReaderBuilderGenerator.scala +++ b/project/JsonReaderBuilderGenerator.scala @@ -2,12 +2,10 @@ import sbt._ object JsonReaderBuilderGenerator { private val packageName = "readers" - + def gen(dir: File): Unit = { val targetFile = dir / "tethys" / packageName / "JsonReaderBuilder.scala" - + } - - - + } diff --git a/project/plugins.sbt b/project/plugins.sbt index a6b04437..e251e471 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,2 +1,3 @@ -addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.4") -addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.12") +addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.4") +addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.12") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6")