From e3ede68c15312101d851a397ce5457d6a5287e5a Mon Sep 17 00:00:00 2001 From: Stanislav Chetvertkov Date: Wed, 26 Jun 2024 18:05:14 +0300 Subject: [PATCH 01/15] =?UTF-8?q?Fixes=20#691=20-=20when=20decoding=20json?= =?UTF-8?q?=20payload=20using=20decoder=20derived=20from=20a=20=E2=80=A6?= =?UTF-8?q?=20(#693)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixes #691 - when decoding json payload using decoder derived from a schema, the missing fields in are populated using their default values (for case classes with more than 22 fields) * Fixes #691 - when decoding json payload using decoder derived from a schema, the missing fields in are populated using their default values (for case classes with more than 22 fields) * #691 - formatting * #691 - formatting * #691 - fix tests in JsonCodecSpec --- .../zio/schema/codec/JsonCodecJVMSpec.scala | 75 +++++++++++++++++++ .../scala/zio/schema/codec/JsonCodec.scala | 13 +++- .../zio/schema/codec/JsonCodecSpec.scala | 46 ++++++++++++ 3 files changed, 133 insertions(+), 1 deletion(-) diff --git a/zio-schema-json/jvm/src/test/scala-2/zio/schema/codec/JsonCodecJVMSpec.scala b/zio-schema-json/jvm/src/test/scala-2/zio/schema/codec/JsonCodecJVMSpec.scala index 01f1da1c2..a1d3ac230 100644 --- a/zio-schema-json/jvm/src/test/scala-2/zio/schema/codec/JsonCodecJVMSpec.scala +++ b/zio-schema-json/jvm/src/test/scala-2/zio/schema/codec/JsonCodecJVMSpec.scala @@ -20,6 +20,18 @@ object JsonCodecJVMSpec extends ZIOSpecDefault { ) @@ TestAspect.jvmOnly @@ timeout(180.seconds) private val decoderSuite = suite("decoding")( + suite("decode record with more than 22 fields")( + test("missing fields in the json payload are populated with their default values") { + val exampleSchema = zio.schema.DeriveSchema.gen[RecordExample] + val string = """{"f1": "test"}""" + assertDecodesJson(exampleSchema, RecordExample(Some("test")), string) + }, + test("fail if a field with no default value is missing in the json payload") { + val exampleSchema = zio.schema.DeriveSchema.gen[RecordExample2] + val string = """{"f1": "test"}""" + assertDecodesJsonFailure(exampleSchema, string) + } + ), suite("case class")( test("case class with empty option field is decoded by stream") { val names = Gen.option(Gen.elements("John", "Jane", "Jermaine", "Jasmine")) @@ -50,6 +62,16 @@ object JsonCodecJVMSpec extends ZIOSpecDefault { ) ) + private def assertDecodesJson[A](schema: Schema[A], value: A, jsonString: String) = { + val either = JsonCodec.jsonDecoder(schema).decodeJson(jsonString) + zio.test.assert(either)(isRight(equalTo(value))) + } + + private def assertDecodesJsonFailure[A](schema: Schema[A], jsonString: String) = { + val either = JsonCodec.jsonDecoder(schema).decodeJson(jsonString) + zio.test.assertTrue(either.isLeft) + } + private def assertDecodesJsonStream[A]( schema: Schema[A], value: Chunk[A], @@ -64,4 +86,57 @@ object JsonCodecJVMSpec extends ZIOSpecDefault { .either assertZIO(result)(isRight(equalTo(value))) } + + case class RecordExample( + f1: Option[String], + f2: Option[String] = None, + f3: Option[String] = None, + f4: Option[String] = None, + f5: Option[String] = None, + f6: Option[String] = None, + f7: Option[String] = None, + f8: Option[String] = None, + f9: Option[String] = None, + f10: Option[String] = None, + f11: Option[String] = None, + f12: Option[String] = None, + f13: Option[String] = None, + f14: Option[String] = None, + f15: Option[String] = None, + f16: Option[String] = None, + f17: Option[String] = None, + f18: Option[String] = None, + f19: Option[String] = None, + f20: Option[String] = None, + f21: Option[String] = None, + f22: Option[String] = None, + f23: Option[String] = None + ) + + case class RecordExample2( + f1: Option[String], + f2: Option[String], + f3: Option[String] = None, + f4: Option[String] = None, + f5: Option[String] = None, + f6: Option[String] = None, + f7: Option[String] = None, + f8: Option[String] = None, + f9: Option[String] = None, + f10: Option[String] = None, + f11: Option[String] = None, + f12: Option[String] = None, + f13: Option[String] = None, + f14: Option[String] = None, + f15: Option[String] = None, + f16: Option[String] = None, + f17: Option[String] = None, + f18: Option[String] = None, + f19: Option[String] = None, + f20: Option[String] = None, + f21: Option[String] = None, + f22: Option[String] = None, + f23: Option[String] = None + ) + } diff --git a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala index 8aacace25..c11bea9f6 100644 --- a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala +++ b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala @@ -830,7 +830,18 @@ object JsonCodec { () } } - (ListMap.newBuilder[String, Any] ++= builder.result()).result() + val tuples = builder.result() + val collectedFields: Set[String] = tuples.map { case (fieldName, _) => fieldName }.toSet + val resultBuilder = ListMap.newBuilder[String, Any] + + // add fields with default values if they are not present in the JSON + structure.foreach { field => + if (!collectedFields.contains(field.name) && field.optional && field.defaultValue.isDefined) { + val value = field.name -> field.defaultValue.get + resultBuilder += value + } + } + (resultBuilder ++= tuples).result() } } diff --git a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala index 0393c8a7a..aeb062fb9 100644 --- a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala +++ b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala @@ -219,6 +219,13 @@ object JsonCodecSpec extends ZIOSpecDefault { } ), suite("record")( + test("missing fields should be replaced by default values") { + assertDecodes( + recordSchema, + ListMap[String, Any]("foo" -> "s", "bar" -> 1), + charSequenceToByteChunk("""{"foo":"s"}""") + ) + }, test("of primitives") { assertEncodes( recordSchema, @@ -435,6 +442,13 @@ object JsonCodecSpec extends ZIOSpecDefault { ListMap[String, Any]("foo" -> "s", "bar" -> 1), charSequenceToByteChunk("""{"foo":"s","bar":1,"baz":2}""") ) + }, + test("with missing fields") { + assertDecodes( + RecordExample.schema, + RecordExample(f1 = Some("test"), f2 = None), + charSequenceToByteChunk("""{"f1":"test"}""") + ) } ), suite("transform")( @@ -1636,6 +1650,7 @@ object JsonCodecSpec extends ZIOSpecDefault { .Field( "bar", Schema.Primitive(StandardType.IntType), + annotations0 = Chunk(fieldDefaultValue(1)), get0 = (p: ListMap[String, _]) => p("bar").asInstanceOf[Int], set0 = (p: ListMap[String, _], v: Int) => p.updated("bar", v) ) @@ -1867,4 +1882,35 @@ object JsonCodecSpec extends ZIOSpecDefault { object AllOptionalFields { implicit lazy val schema: Schema[AllOptionalFields] = DeriveSchema.gen[AllOptionalFields] } + + case class RecordExample( + f1: Option[String], // the only field that does not have a default value + f2: Option[String] = None, + f3: Option[String] = None, + f4: Option[String] = None, + f5: Option[String] = None, + f6: Option[String] = None, + f7: Option[String] = None, + f8: Option[String] = None, + f9: Option[String] = None, + f10: Option[String] = None, + f11: Option[String] = None, + f12: Option[String] = None, + f13: Option[String] = None, + f14: Option[String] = None, + f15: Option[String] = None, + f16: Option[String] = None, + f17: Option[String] = None, + f18: Option[String] = None, + f19: Option[String] = None, + f20: Option[String] = None, + f21: Option[String] = None, + f22: Option[String] = None, + f23: Option[String] = None + ) + + object RecordExample { + implicit lazy val schema: Schema[RecordExample] = DeriveSchema.gen[RecordExample] + } + } From 37d59546dc4bb467e181bd2c5db6a0e0f5fa9e2a Mon Sep 17 00:00:00 2001 From: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com> Date: Fri, 28 Jun 2024 10:02:52 +0200 Subject: [PATCH 02/15] Fix generic record construction for fields with fieldName annotation (#698) --- .../shared/src/main/scala-2/zio/schema/DeriveSchema.scala | 8 +++++--- .../src/main/scala/zio/schema/codec/JsonCodec.scala | 4 +++- .../src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala index f5772dd7d..018079141 100644 --- a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala @@ -330,9 +330,11 @@ object DeriveSchema { } } val fromMap = { - val casts = fieldTypes.map { termSymbol => - q""" - try m.apply(${termSymbol.name.toString.trim}).asInstanceOf[${termSymbol.typeSignature}] + val casts = fieldTypes.zip(fieldAnnotations).map { + case (termSymbol, annotations) => + val newName = getFieldName(annotations).getOrElse(termSymbol.name.toString.trim) + q""" + try m.apply(${newName}).asInstanceOf[${termSymbol.typeSignature}] catch { case _: ClassCastException => throw new RuntimeException("Field " + ${termSymbol.name.toString.trim} + " has invalid type") case _: Throwable => throw new RuntimeException("Field " + ${termSymbol.name.toString.trim} + " is missing") diff --git a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala index c11bea9f6..b72d8af6d 100644 --- a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala +++ b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala @@ -814,7 +814,9 @@ object JsonCodec { if (Lexer.firstField(trace, in)) { while ({ val field = Lexer.string(trace, in).toString - structure.find(_.name == field) match { + structure.find( + f => f.name == field || f.annotations.collectFirst { case fieldName(name) => name }.contains(field) + ) match { case Some(Schema.Field(label, schema, _, _, _, _)) => val trace_ = JsonError.ObjectAccess(label) :: trace Lexer.char(trace_, in, ':') diff --git a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala index aeb062fb9..115bee8e5 100644 --- a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala +++ b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala @@ -1906,7 +1906,7 @@ object JsonCodecSpec extends ZIOSpecDefault { f20: Option[String] = None, f21: Option[String] = None, f22: Option[String] = None, - f23: Option[String] = None + @fieldName("$f23") f23: Option[String] = None ) object RecordExample { From 91899ff0415009ca7f3f31d13083244e69e66d0f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 10:06:36 +0200 Subject: [PATCH 03/15] Update README.md (#690) Co-authored-by: github-actions[bot] --- README.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8d29f4a3a..acb2a97f1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [ZIO Schema](https://github.com/zio/zio-schema) is a [ZIO](https://zio.dev)-based library for modeling the schema of data structures as first-class values. -[![Development](https://img.shields.io/badge/Project%20Stage-Development-green.svg)](https://github.com/zio/zio/wiki/Project-Stages) ![CI Badge](https://github.com/zio/zio-schema/workflows/CI/badge.svg) [![Sonatype Snapshots](https://img.shields.io/nexus/s/https/oss.sonatype.org/dev.zio/zio-schema_2.13.svg?label=Sonatype%20Snapshot)](https://oss.sonatype.org/content/repositories/snapshots/dev/zio/zio-schema_2.13/) [![ZIO Schema](https://img.shields.io/github/stars/zio/zio-schema?style=social)](https://github.com/zio/zio-schema) +[![Development](https://img.shields.io/badge/Project%20Stage-Development-green.svg)](https://github.com/zio/zio/wiki/Project-Stages) ![CI Badge](https://github.com/zio/zio-schema/workflows/CI/badge.svg) [![Sonatype Releases](https://img.shields.io/nexus/r/https/oss.sonatype.org/dev.zio/zio-schema_2.13.svg?label=Sonatype%20Release)](https://oss.sonatype.org/content/repositories/releases/dev/zio/zio-schema_2.13/) [![Sonatype Snapshots](https://img.shields.io/nexus/s/https/oss.sonatype.org/dev.zio/zio-schema_2.13.svg?label=Sonatype%20Snapshot)](https://oss.sonatype.org/content/repositories/snapshots/dev/zio/zio-schema_2.13/) [![javadoc](https://javadoc.io/badge2/dev.zio/zio-schema-docs_2.13/javadoc.svg)](https://javadoc.io/doc/dev.zio/zio-schema-docs_2.13) [![ZIO Schema](https://img.shields.io/github/stars/zio/zio-schema?style=social)](https://github.com/zio/zio-schema) ## Introduction @@ -39,18 +39,17 @@ _ZIO Schema_ is used by a growing number of ZIO libraries, including [ZIO Flow]( In order to use this library, we need to add the following lines in our `build.sbt` file: ```scala - -libraryDependencies += "dev.zio" %% "zio-schema" % "1.1.1" -libraryDependencies += "dev.zio" %% "zio-schema-avro" % "1.1.1" -libraryDependencies += "dev.zio" %% "zio-schema-bson" % "1.1.1" -libraryDependencies += "dev.zio" %% "zio-schema-json" % "1.1.1" -libraryDependencies += "dev.zio" %% "zio-schema-msg-pack" % "1.1.1" -libraryDependencies += "dev.zio" %% "zio-schema-protobuf" % "1.1.1" -libraryDependencies += "dev.zio" %% "zio-schema-thrift" % "1.1.1" -libraryDependencies += "dev.zio" %% "zio-schema-zio-test" % "1.1.1" +libraryDependencies += "dev.zio" %% "zio-schema" % "1.2.1" +libraryDependencies += "dev.zio" %% "zio-schema-avro" % "1.2.1" +libraryDependencies += "dev.zio" %% "zio-schema-bson" % "1.2.1" +libraryDependencies += "dev.zio" %% "zio-schema-json" % "1.2.1" +libraryDependencies += "dev.zio" %% "zio-schema-msg-pack" % "1.2.1" +libraryDependencies += "dev.zio" %% "zio-schema-protobuf" % "1.2.1" +libraryDependencies += "dev.zio" %% "zio-schema-thrift" % "1.2.1" +libraryDependencies += "dev.zio" %% "zio-schema-zio-test" % "1.2.1" // Required for the automatic generic derivation of schemas -libraryDependencies += "dev.zio" %% "zio-schema-derivation" % "1.1.1" +libraryDependencies += "dev.zio" %% "zio-schema-derivation" % "1.2.1" libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided" ``` From 975539a1c4830544604465937ee98a5a2cfc46c8 Mon Sep 17 00:00:00 2001 From: Jisoo Park Date: Tue, 9 Jul 2024 23:22:14 +0900 Subject: [PATCH 04/15] Fix JSON decoding of empty objects (#710) * Fix JSON decoding of empty objects - discriminated case object - case object with @rejectExtraField * fmt test sources * Simplify test --- .../scala/zio/schema/codec/JsonCodec.scala | 24 ++++++++++++++++++- .../zio/schema/codec/JsonCodecSpec.scala | 15 +++++++++++- .../zio/schema/codec/DefaultValueSpec.scala | 4 ++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala index b72d8af6d..586860b04 100644 --- a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala +++ b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala @@ -991,7 +991,29 @@ object JsonCodec { import JsonCodec.JsonDecoder.schemaDecoder private[codec] def caseClass0Decoder[Z](discriminator: Int, schema: Schema.CaseClass0[Z]): ZJsonDecoder[Z] = { (trace: List[JsonError], in: RetractReader) => - if (discriminator == -1) Codecs.unitDecoder.unsafeDecode(trace, in) + def skipField(): Unit = { + val rejectExtraFields = schema.annotations.collectFirst({ case _: rejectExtraFields => () }).isDefined + if (rejectExtraFields) { + throw UnsafeJson(JsonError.Message("extra field") :: trace) + } + Lexer.char(trace, in, '"') + Lexer.skipString(trace, in) + Lexer.char(trace, in, ':') + Lexer.skipValue(trace, in) + } + + if (discriminator == -2) { + while (Lexer.nextField(trace, in)) { skipField() } + } else { + if (discriminator == -1) { + Lexer.char(trace, in, '{') + } + if (Lexer.firstField(trace, in)) { + skipField() + while (Lexer.nextField(trace, in)) { skipField() } + } + } + schema.defaultConstruct() } diff --git a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala index 115bee8e5..e4957af48 100644 --- a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala +++ b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala @@ -524,7 +524,12 @@ object JsonCodecSpec extends ZIOSpecDefault { PersonWithRejectExtraFields.schema, """{"name":"test","age":10,"extraField":10}""", JsonError.Message("extra field") :: Nil - ) + ) &> + assertDecodesToError( + schemaObject.annotate(rejectExtraFields()), + """{"extraField":10}""", + JsonError.Message("extra field") :: Nil + ) }, test("transient field annotation") { assertDecodes( @@ -1242,6 +1247,13 @@ object JsonCodecSpec extends ZIOSpecDefault { assertEncodesThenDecodes(Schema[Command], Command.Cash) &> assertEncodesThenDecodes(Schema[Command], Command.Buy(100)) }, + test("decode discriminated case objects in array")( + assertDecodes(Schema[List[Command]], Command.Cash :: Nil, charSequenceToByteChunk("""[{"type":"Cash"}]""")) + ), + test("decode discriminated case objects with extra fields")( + assertDecodes(Schema[Command], Command.Cash, charSequenceToByteChunk("""{"type":"Cash","extraField":1}""")) &> + assertDecodes(Schema[Command], Command.Cash, charSequenceToByteChunk("""{"extraField":1,"type":"Cash"}"""")) + ), suite("of case objects")( test("without annotation")( assertEncodesThenDecodes(Schema[Color], Color.Red) @@ -1593,6 +1605,7 @@ object JsonCodecSpec extends ZIOSpecDefault { val schema: Schema[PersonWithRejectExtraFields] = DeriveSchema.gen[PersonWithRejectExtraFields] } + case class FieldDefaultValueSearchRequest( query: String, pageNumber: Int, diff --git a/zio-schema-json/shared/src/test/scala-3/zio/schema/codec/DefaultValueSpec.scala b/zio-schema-json/shared/src/test/scala-3/zio/schema/codec/DefaultValueSpec.scala index cd65b6a00..4b2dd94bc 100644 --- a/zio-schema-json/shared/src/test/scala-3/zio/schema/codec/DefaultValueSpec.scala +++ b/zio-schema-json/shared/src/test/scala-3/zio/schema/codec/DefaultValueSpec.scala @@ -12,7 +12,7 @@ object DefaultValueSpec extends ZIOSpecDefault { def spec: Spec[TestEnvironment, Any] = suite("Custom Spec")( - customSuite, + customSuite ) @@ timeout(90.seconds) private val customSuite = suite("custom")( @@ -24,7 +24,7 @@ object DefaultValueSpec extends ZIOSpecDefault { ) ) - case class WithDefaultValue(orderId:Int, description: String = "desc") + case class WithDefaultValue(orderId: Int, description: String = "desc") object WithDefaultValue { implicit lazy val schema: Schema[WithDefaultValue] = DeriveSchema.gen[WithDefaultValue] From 3f59113ca35ece7e29302b84340a93f108378f90 Mon Sep 17 00:00:00 2001 From: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com> Date: Tue, 9 Jul 2024 16:23:29 +0200 Subject: [PATCH 05/15] Failing deriving Schemas with transient fields without defaults (#654) (#708) --- .../src/main/scala-2/zio/schema/DeriveSchema.scala | 14 +++++++++++--- .../src/main/scala-3/zio/schema/DeriveSchema.scala | 4 ++++ .../scala-2/zio/schema/codec/JsonCodecSpec.scala | 2 +- .../scala-2/zio/schema/codec/ThriftCodecSpec.scala | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala index 018079141..9d5d070e4 100644 --- a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala @@ -271,10 +271,18 @@ object DeriveSchema { } val hasDefaultAnnotation = annotations.exists { - case q"new _root_.zio.schema.annotation.fieldDefaultValue(..$_)" => true - case _ => false + case ann if ann.toString.contains("new fieldDefaultValue") => true + case _ => false } - if (hasDefaultAnnotation || defaultConstructorValues.get(i).isEmpty) { + val transientField = + annotations.exists { + case ann if ann.toString().endsWith("new transientField()") => true + case _ => false + } + if (transientField && !(hasDefaultAnnotation || defaultConstructorValues.contains(i))) { + throw new IllegalStateException(s"Field ${symbol.name} is transient and must have a default value.") + } + if (hasDefaultAnnotation || !defaultConstructorValues.contains(i)) { annotations } else { annotations :+ diff --git a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala index 57df11ebc..e012fbac0 100644 --- a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala @@ -339,6 +339,10 @@ private case class DeriveSchema()(using val ctx: Quotes) { .map(_.asExpr.asInstanceOf[Expr[Any]]) val hasDefaultAnnotation = field.annotations.exists(_.tpe <:< TypeRepr.of[zio.schema.annotation.fieldDefaultValue[_]]) + val transientField = field.annotations.exists(_.tpe <:< TypeRepr.of[zio.schema.annotation.transientField]) + if (transientField && !hasDefaultAnnotation && defaults.get(field.name).isEmpty) { + report.errorAndAbort(s"Field ${field.name} is transient and must have a default value.") + } if (hasDefaultAnnotation || defaults.get(field.name).isEmpty) { annos } else { diff --git a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala index e4957af48..19704fd5a 100644 --- a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala +++ b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala @@ -1642,7 +1642,7 @@ object JsonCodecSpec extends ZIOSpecDefault { query: String, pageNumber: Int, resultPerPage: Int, - @transientField nextPage: String + @transientField nextPage: String = "" ) val searchRequestWithTransientFieldSchema: Schema[SearchRequestWithTransientField] = diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala b/zio-schema-thrift/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala index 5f21af2ca..5067e24f4 100644 --- a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala +++ b/zio-schema-thrift/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala @@ -1169,7 +1169,7 @@ object ThriftCodecSpec extends ZIOSpecDefault { implicit val schema: Schema[PersonWithOptionalField] = DeriveSchema.gen[PersonWithOptionalField] } - case class PersonWithTransientField(name: String, @transientField age: Int) + case class PersonWithTransientField(name: String, @transientField age: Int = 0) object PersonWithTransientField { implicit val schema: Schema[PersonWithTransientField] = DeriveSchema.gen[PersonWithTransientField] From f5152fbb3e364f462ab76833d57c594a4d8735f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Femen=C3=ADa?= <131800808+pablf@users.noreply.github.com> Date: Tue, 9 Jul 2024 16:24:26 +0200 Subject: [PATCH 06/15] not assign simpleEnum annotation (#707) --- .../scala-3/zio/schema/DeriveSchema.scala | 4 ++- .../VersionSpecificDeriveSchemaSpec.scala | 29 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala index e012fbac0..53566a978 100644 --- a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala @@ -364,7 +364,9 @@ private case class DeriveSchema()(using val ctx: Quotes) { val cases = typesAndLabels.map { case (tpe, label) => deriveCase[T](tpe, label, newStack) } val numParentFields: Int = TypeRepr.of[T].typeSymbol.declaredFields.length - val isSimpleEnum: Boolean = !TypeRepr.of[T].typeSymbol.children.map(_.declaredFields.length).exists( _ > numParentFields ) + val childrenFields = TypeRepr.of[T].typeSymbol.children.map(_.declaredFields.length) + val childrenFieldsConstructor = TypeRepr.of[T].typeSymbol.children.map(_.caseFields.length) + val isSimpleEnum: Boolean = childrenFieldsConstructor.forall( _ == 0) && childrenFields.forall( _ <= numParentFields) val hasSimpleEnumAnn: Boolean = TypeRepr.of[T].typeSymbol.hasAnnotation(TypeRepr.of[_root_.zio.schema.annotation.simpleEnum].typeSymbol) val docAnnotationExpr = TypeRepr.of[T].typeSymbol.docstring.map { docstring => diff --git a/zio-schema-derivation/shared/src/test/scala-3/zio/schema/VersionSpecificDeriveSchemaSpec.scala b/zio-schema-derivation/shared/src/test/scala-3/zio/schema/VersionSpecificDeriveSchemaSpec.scala index 881c7bb08..68c7d195d 100644 --- a/zio-schema-derivation/shared/src/test/scala-3/zio/schema/VersionSpecificDeriveSchemaSpec.scala +++ b/zio-schema-derivation/shared/src/test/scala-3/zio/schema/VersionSpecificDeriveSchemaSpec.scala @@ -48,6 +48,23 @@ trait VersionSpecificDeriveSchemaSpec extends ZIOSpecDefault { @description("Red") case Red + enum NonSimpleEnum1: + case A(a: Int) + + enum NonSimpleEnum2(a: Int): + case A(b: Int) extends NonSimpleEnum2(0) + + + enum NonSimpleEnum3(a: Int): + case A(b: Int) extends NonSimpleEnum3(b) + + enum NonSimpleEnum4(val a: Int): + case A(override val a: Int) extends NonSimpleEnum4(a) + + enum NonSimpleEnum5(a: Int, b: String): + case A extends NonSimpleEnum5(0, "") + case B(n: Int) extends NonSimpleEnum5(n, "") + def versionSpecificSuite = Spec.labeled( "Scala 3 specific tests", suite("Derivation")( @@ -68,6 +85,18 @@ trait VersionSpecificDeriveSchemaSpec extends ZIOSpecDefault { val derived: Schema[Colour] = DeriveSchema.gen[Colour] assertTrue(derived.annotations == Chunk(simpleEnum(true))) }, + test("doesn't assigns simpleEnum to non-simple enum") { + val derived1: Schema[NonSimpleEnum1] = DeriveSchema.gen[NonSimpleEnum1] + val derived2: Schema[NonSimpleEnum2] = DeriveSchema.gen[NonSimpleEnum2] + val derived3: Schema[NonSimpleEnum3] = DeriveSchema.gen[NonSimpleEnum3] + val derived4: Schema[NonSimpleEnum4] = DeriveSchema.gen[NonSimpleEnum4] + val derived5: Schema[NonSimpleEnum5] = DeriveSchema.gen[NonSimpleEnum5] + assertTrue(derived1.annotations.isEmpty) && + assertTrue(derived2.annotations.isEmpty) && + assertTrue(derived3.annotations.isEmpty) && + assertTrue(derived4.annotations.isEmpty) && + assertTrue(derived5.annotations.isEmpty) + }, test("derive different annotations for parent and child in enum") { val parent = DeriveSchema.gen[ColourAnnotations] val child = parent match { From 31a0180656388ea0002c6c9703569e2a54486050 Mon Sep 17 00:00:00 2001 From: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com> Date: Tue, 9 Jul 2024 17:37:16 +0200 Subject: [PATCH 07/15] Save info about generically applied types in new annotation (#695) (#703) --- .../scala-2/zio/schema/DeriveSchema.scala | 47 +++++++++++++++++-- .../scala-3/zio/schema/DeriveSchema.scala | 14 +++++- .../test/scala/zio/schema/DeriveSpec.scala | 7 ++- .../schema/annotation/genericTypeInfo.scala | 8 ++++ 4 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 zio-schema/shared/src/main/scala/zio/schema/annotation/genericTypeInfo.scala diff --git a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala index 9d5d070e4..dc92f4866 100644 --- a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala @@ -232,7 +232,20 @@ object DeriveSchema { val typeId = q"_root_.zio.schema.TypeId.parse(${tpe.typeSymbol.fullName})" - val typeAnnotations: List[Tree] = collectTypeAnnotations(tpe) + val genericAnnotations: List[Tree] = + if (tpe.typeArgs.isEmpty) Nil + else { + val typeMembers = tpe.typeSymbol.asClass.typeParams.map(_.name.toString) + val typeArgs = tpe.typeArgs + .map(_.typeSymbol.fullName) + .map(t => q"_root_.zio.schema.TypeId.parse(${t}).asInstanceOf[_root_.zio.schema.TypeId.Nominal]") + val typeMembersWithArgs = typeMembers.zip(typeArgs).map { case (m, a) => q"($m, $a)" } + List( + q"new _root_.zio.schema.annotation.genericTypeInfo(_root_.scala.collection.immutable.ListMap(..$typeMembersWithArgs))" + ) + } + + val typeAnnotations: List[Tree] = collectTypeAnnotations(tpe) ++ genericAnnotations val defaultConstructorValues = tpe.typeSymbol.asClass.primaryConstructor.asMethod.paramLists.head @@ -565,7 +578,20 @@ object DeriveSchema { val hasSimpleEnum: Boolean = tpe.typeSymbol.annotations.exists(_.tree.tpe =:= typeOf[_root_.zio.schema.annotation.simpleEnum]) - val typeAnnotations: List[Tree] = (isSimpleEnum, hasSimpleEnum) match { + val genericAnnotations: List[Tree] = + if (tpe.typeArgs.isEmpty) Nil + else { + val typeMembers = tpe.typeSymbol.asClass.typeParams.map(_.name.toString) + val typeArgs = tpe.typeArgs + .map(_.typeSymbol.fullName) + .map(t => q"_root_.zio.schema.TypeId.parse(${t}).asInstanceOf[_root_.zio.schema.TypeId.Nominal]") + val typeMembersWithArgs = typeMembers.zip(typeArgs).map { case (m, a) => q"($m, $a)" } + List( + q"new _root_.zio.schema.annotation.genericTypeInfo(_root_.scala.collection.immutable.ListMap(..$typeMembersWithArgs))" + ) + } + + val typeAnnotations: List[Tree] = ((isSimpleEnum, hasSimpleEnum) match { case (true, false) => tpe.typeSymbol.annotations.collect { case annotation if !(annotation.tree.tpe <:< JavaAnnotationTpe) => @@ -600,7 +626,7 @@ object DeriveSchema { c.warning(c.enclosingPosition, s"Unhandled annotation ${annotation.tree}") EmptyTree }.filter(_ != EmptyTree) - } + }) ++ genericAnnotations val selfRefName = c.freshName("ref") val selfRefIdent = Ident(TermName(selfRefName)) @@ -610,6 +636,19 @@ object DeriveSchema { val typeArgs = subtypes ++ Iterable(tpe) val cases = subtypes.map { (subtype: Type) => + val genericAnnotations: List[Tree] = + if (subtype.typeArgs.isEmpty) Nil + else { + val typeMembers = subtype.typeSymbol.asClass.typeParams.map(_.name.toString) + val typeArgs = subtype.typeArgs + .map(_.typeSymbol.fullName) + .map(t => q"_root_.zio.schema.TypeId.parse(${t}).asInstanceOf[_root_.zio.schema.TypeId.Nominal]") + val typeMembersWithArgs = typeMembers.zip(typeArgs).map { case (m, a) => q"($m, $a)" } + List( + q"new _root_.zio.schema.annotation.genericTypeInfo(_root_.scala.collection.immutable.ListMap(..$typeMembersWithArgs))" + ) + } + val typeAnnotations: List[Tree] = subtype.typeSymbol.annotations.collect { case annotation if !(annotation.tree.tpe <:< JavaAnnotationTpe) => @@ -625,7 +664,7 @@ object DeriveSchema { case annotation => c.warning(c.enclosingPosition, s"Unhandled annotation ${annotation.tree}") EmptyTree - }.filter(_ != EmptyTree) + }.filter(_ != EmptyTree) ++ genericAnnotations val caseLabel = subtype.typeSymbol.name.toString.trim val caseSchema = directInferSchema(tpe, concreteType(tpe, subtype), currentFrame +: stack) diff --git a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala index 53566a978..7e4e3fb77 100644 --- a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala @@ -195,7 +195,12 @@ private case class DeriveSchema()(using val ctx: Quotes) { then TypeRepr.of[T].typeSymbol.children.map(_.annotations).flatten.filter (filterAnnotation).map (_.asExpr) else TypeRepr.of[T].typeSymbol.annotations.filter (filterAnnotation).map (_.asExpr) - val annotations = '{ zio.Chunk.fromIterable(${Expr.ofSeq(annotationExprs)}) ++ zio.Chunk.fromIterable(${Expr.ofSeq(docAnnotationExpr)}) } + val genericAnnotations = if (TypeRepr.of[T].classSymbol.exists(_.typeMembers.nonEmpty)){ + val typeMembersExpr = Expr.ofSeq(TypeRepr.of[T].classSymbol.get.typeMembers.map { t => Expr(t.name) }) + val typeArgsExpr = Expr.ofSeq(TypeRepr.of[T].typeArgs.map { t => Expr(t.typeSymbol.fullName) }) + List('{zio.schema.annotation.genericTypeInfo(ListMap.from(${typeMembersExpr}.zip(${typeArgsExpr}.map(name => TypeId.parse(name).asInstanceOf[TypeId.Nominal]))))}) + } else List.empty + val annotations = '{ zio.Chunk.fromIterable(${Expr.ofSeq(annotationExprs)}) ++ zio.Chunk.fromIterable(${Expr.ofSeq(docAnnotationExpr)}) ++ zio.Chunk.fromIterable(${Expr.ofSeq(genericAnnotations)}) } val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].show)})} val applied = if (labels.length <= 22) { @@ -378,7 +383,12 @@ private case class DeriveSchema()(using val ctx: Quotes) { case (false, true) => throw new Exception(s"${TypeRepr.of[T].typeSymbol.name} must be a simple Enum") case _ => TypeRepr.of[T].typeSymbol.annotations.filter(filterAnnotation).map(_.asExpr) } - val annotations = '{ zio.Chunk.fromIterable(${Expr.ofSeq(annotationExprs)}) ++ zio.Chunk.fromIterable(${Expr.ofSeq(docAnnotationExpr.toList)}) } + val genericAnnotations = if (TypeRepr.of[T].classSymbol.exists(_.typeMembers.nonEmpty)){ + val typeMembersExpr = Expr.ofSeq(TypeRepr.of[T].classSymbol.get.typeMembers.map { t => Expr(t.name) }) + val typeArgsExpr = Expr.ofSeq(TypeRepr.of[T].typeArgs.map { t => Expr(t.typeSymbol.fullName) }) + List('{zio.schema.annotation.genericTypeInfo(ListMap.from(${typeMembersExpr}.zip(${typeArgsExpr}.map(name => TypeId.parse(name).asInstanceOf[TypeId.Nominal]))))}) + } else List.empty + val annotations = '{ zio.Chunk.fromIterable(${Expr.ofSeq(annotationExprs)}) ++ zio.Chunk.fromIterable(${Expr.ofSeq(docAnnotationExpr.toList)}) ++ zio.Chunk.fromIterable(${Expr.ofSeq(genericAnnotations)}) } val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].show)})} diff --git a/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala b/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala index e82bac1f3..51a222e08 100644 --- a/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala +++ b/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala @@ -1,11 +1,12 @@ package zio.schema import scala.annotation.nowarn +import scala.collection.immutable.ListMap import scala.reflect.ClassTag import zio.schema.Deriver.WrappedF import zio.schema.Schema.Field -import zio.schema.annotation.fieldDefaultValue +import zio.schema.annotation.{ fieldDefaultValue, genericTypeInfo } import zio.test.{ Spec, TestEnvironment, ZIOSpecDefault, assertTrue } import zio.{ Chunk, Scope } @@ -183,7 +184,11 @@ import zio.{ Chunk, Scope } .asInstanceOf[Schema.Record[GenericRecordWithDefaultValue[Int]]] .fields(0) .annotations + val maybeTypeInfo = capturedSchema.schema.annotations.collectFirst { case gt @ genericTypeInfo(_) => gt } assertTrue( + maybeTypeInfo.contains( + genericTypeInfo(ListMap("T" -> TypeId.parse("scala.Int").asInstanceOf[TypeId.Nominal])) + ), annotations.exists { a => a.isInstanceOf[fieldDefaultValue[_]] && a.asInstanceOf[fieldDefaultValue[Option[Int]]].value == None diff --git a/zio-schema/shared/src/main/scala/zio/schema/annotation/genericTypeInfo.scala b/zio-schema/shared/src/main/scala/zio/schema/annotation/genericTypeInfo.scala new file mode 100644 index 000000000..0c4a32505 --- /dev/null +++ b/zio-schema/shared/src/main/scala/zio/schema/annotation/genericTypeInfo.scala @@ -0,0 +1,8 @@ +package zio.schema.annotation + +import scala.collection.immutable.ListMap + +import zio.schema.TypeId + +final case class genericTypeInfo(appliedTypes: ListMap[String, TypeId.Nominal]) + extends scala.annotation.StaticAnnotation From 3dc17485b13cd634dfd3a4fd8c5a2bb005882e0a Mon Sep 17 00:00:00 2001 From: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com> Date: Tue, 9 Jul 2024 17:37:53 +0200 Subject: [PATCH 08/15] JsonCodec respects annotations for GenericRecord (#700) (#704) * JsonCodec respects annotations for GenericRecord (#700) * Tests for JsonCodec for Schema.EnumN (#700) --- .../scala-2/zio/schema/DeriveSchema.scala | 6 +- .../zio/schema/codec/JsonCodecJVMSpec.scala | 2 +- .../scala/zio/schema/codec/JsonCodec.scala | 80 ++++----- .../zio/schema/codec/JsonCodecSpec.scala | 157 ++++++++++++++++-- .../src/main/scala/zio/schema/Schema.scala | 10 ++ 5 files changed, 204 insertions(+), 51 deletions(-) diff --git a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala index dc92f4866..2f2420cde 100644 --- a/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-2/zio/schema/DeriveSchema.scala @@ -365,8 +365,10 @@ object DeriveSchema { q"""(m: scala.collection.immutable.ListMap[String, _]) => try { Right($tpeCompanion.apply(..$casts)) } catch { case e: Throwable => Left(e.getMessage) }""" } val toMap = { - val tuples = fieldAccessors.map { fieldName => - q"(${fieldName.toString},b.$fieldName)" + val tuples = fieldAccessors.zip(fieldAnnotations).map { + case (fieldName, annotations) => + val newName = getFieldName(annotations).getOrElse(fieldName.toString) + q"(${newName},b.$fieldName)" } q"""(b: $tpe) => Right(scala.collection.immutable.ListMap.apply(..$tuples))""" } diff --git a/zio-schema-json/jvm/src/test/scala-2/zio/schema/codec/JsonCodecJVMSpec.scala b/zio-schema-json/jvm/src/test/scala-2/zio/schema/codec/JsonCodecJVMSpec.scala index a1d3ac230..78ce4400b 100644 --- a/zio-schema-json/jvm/src/test/scala-2/zio/schema/codec/JsonCodecJVMSpec.scala +++ b/zio-schema-json/jvm/src/test/scala-2/zio/schema/codec/JsonCodecJVMSpec.scala @@ -115,7 +115,7 @@ object JsonCodecJVMSpec extends ZIOSpecDefault { case class RecordExample2( f1: Option[String], - f2: Option[String], + f2: String, f3: Option[String] = None, f4: Option[String] = None, f5: Option[String] = None, diff --git a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala index 586860b04..23a5f5635 100644 --- a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala +++ b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala @@ -462,7 +462,8 @@ object JsonCodec { pad(indent_, out) var first = true structure.foreach { - case Schema.Field(k, a, _, _, _, _) => + case field if field.transient || isEmptyOptionalValue(field, value(field.fieldName), cfg) => () + case f @ Schema.Field(_, a, _, _, _, _) => val enc = schemaEncoder(a.asInstanceOf[Schema[Any]], cfg) if (first) first = false @@ -471,10 +472,10 @@ object JsonCodec { if (indent.isDefined) ZJsonEncoder.pad(indent_, out) } - string.encoder.unsafeEncode(JsonFieldEncoder.string.unsafeEncodeField(k), indent_, out) + string.encoder.unsafeEncode(JsonFieldEncoder.string.unsafeEncodeField(f.fieldName), indent_, out) if (indent.isEmpty) out.write(':') else out.write(" : ") - enc.unsafeEncode(value(k), indent_, out) + enc.unsafeEncode(value(f.fieldName), indent_, out) } pad(indent, out) out.write('}') @@ -551,7 +552,7 @@ object JsonCodec { case Schema.Map(ks, vs, _) => mapDecoder(ks, vs) case Schema.Set(s, _) => ZJsonDecoder.chunk(schemaDecoder(s, -1)).map(entries => entries.toSet) case Schema.Fail(message, _) => failDecoder(message) - case Schema.GenericRecord(_, structure, _) => recordDecoder(structure.toChunk) + case Schema.GenericRecord(_, structure, _) => recordDecoder(structure.toChunk, schema.annotations.contains(rejectExtraFields())) case Schema.Either(left, right, _) => ZJsonDecoder.either(schemaDecoder(left, -1), schemaDecoder(right, -1)) case s @ Schema.Fallback(_, _, _, _) => fallbackDecoder(s) case l @ Schema.Lazy(_) => schemaDecoder(l.schema, discriminator) @@ -806,45 +807,48 @@ object JsonCodec { private def deAliasCaseName(alias: String, caseNameAliases: Map[String, String]): String = caseNameAliases.getOrElse(alias, alias) - private def recordDecoder[Z](structure: Seq[Schema.Field[Z, _]]): ZJsonDecoder[ListMap[String, Any]] = { - (trace: List[JsonError], in: RetractReader) => - { - val builder: ChunkBuilder[(String, Any)] = zio.ChunkBuilder.make[(String, Any)](structure.size) - Lexer.char(trace, in, '{') - if (Lexer.firstField(trace, in)) { - while ({ - val field = Lexer.string(trace, in).toString - structure.find( - f => f.name == field || f.annotations.collectFirst { case fieldName(name) => name }.contains(field) - ) match { - case Some(Schema.Field(label, schema, _, _, _, _)) => - val trace_ = JsonError.ObjectAccess(label) :: trace - Lexer.char(trace_, in, ':') - val value = schemaDecoder(schema).unsafeDecode(trace_, in) - builder += ((JsonFieldDecoder.string.unsafeDecodeField(trace_, label), value)) - case None => - Lexer.char(trace, in, ':') - Lexer.skipValue(trace, in) + private def recordDecoder[Z]( + structure: Seq[Schema.Field[Z, _]], + rejectAdditionalFields: Boolean + ): ZJsonDecoder[ListMap[String, Any]] = { (trace: List[JsonError], in: RetractReader) => + { + val builder: ChunkBuilder[(String, Any)] = zio.ChunkBuilder.make[(String, Any)](structure.size) + Lexer.char(trace, in, '{') + if (Lexer.firstField(trace, in)) { + while ({ + val field = Lexer.string(trace, in).toString + structure.find(f => f.nameAndAliases.contains(field)) match { + case Some(s @ Schema.Field(_, schema, _, _, _, _)) => + val fieldName = s.fieldName + val trace_ = JsonError.ObjectAccess(fieldName) :: trace + Lexer.char(trace_, in, ':') + val value = schemaDecoder(schema).unsafeDecode(trace_, in) + builder += ((JsonFieldDecoder.string.unsafeDecodeField(trace_, fieldName), value)) + case None if rejectAdditionalFields => + throw UnsafeJson(JsonError.Message(s"unexpected field: $field") :: trace) + case None => + Lexer.char(trace, in, ':') + Lexer.skipValue(trace, in) - } - (Lexer.nextField(trace, in)) - }) { - () } + Lexer.nextField(trace, in) + }) { + () } - val tuples = builder.result() - val collectedFields: Set[String] = tuples.map { case (fieldName, _) => fieldName }.toSet - val resultBuilder = ListMap.newBuilder[String, Any] - - // add fields with default values if they are not present in the JSON - structure.foreach { field => - if (!collectedFields.contains(field.name) && field.optional && field.defaultValue.isDefined) { - val value = field.name -> field.defaultValue.get - resultBuilder += value - } + } + val tuples = builder.result() + val collectedFields: Set[String] = tuples.map { case (fieldName, _) => fieldName }.toSet + val resultBuilder = ListMap.newBuilder[String, Any] + + // add fields with default values if they are not present in the JSON + structure.foreach { field => + if (!collectedFields.contains(field.fieldName) && field.optional && field.defaultValue.isDefined) { + val value = field.fieldName -> field.defaultValue.get + resultBuilder += value } - (resultBuilder ++= tuples).result() } + (resultBuilder ++= tuples).result() + } } private def fallbackDecoder[A, B](schema: Schema.Fallback[A, B]): ZJsonDecoder[Fallback[A, B]] = diff --git a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala index 19704fd5a..c5222c89a 100644 --- a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala +++ b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala @@ -416,6 +416,26 @@ object JsonCodecSpec extends ZIOSpecDefault { charSequenceToByteChunk("""null""") ) } + ), + suite("Generic Record")( + test("Do not encode transient field") { + assertEncodes( + RecordExample.schema.annotate(rejectExtraFields()), + RecordExample(f1 = Some("test"), f3 = Some("transient")), + charSequenceToByteChunk( + """{"$f1":"test","f2":null,"f4":null,"f5":null,"f6":null,"f7":null,"f8":null,"f9":null,"f10":null,"f11":null,"f12":null,"f13":null,"f14":null,"f15":null,"f16":null,"f17":null,"f18":null,"f19":null,"f20":null,"f21":null,"f22":null,"$f23":null}""".stripMargin + ) + ) + } + ), + suite("EnumN")( + test("Respects the case name annotation") { + assertEncodesJson( + Enum23Cases.schema, + Enum23Cases.Case1("foo"), + """{"NumberOne":{"value":"foo"}}""" + ) + } ) ) @@ -435,7 +455,7 @@ object JsonCodecSpec extends ZIOSpecDefault { ) } @@ TestAspect.jvmOnly ), - suite("generic record")( + suite("Generic record")( test("with extra fields") { assertDecodes( recordSchema, @@ -447,7 +467,44 @@ object JsonCodecSpec extends ZIOSpecDefault { assertDecodes( RecordExample.schema, RecordExample(f1 = Some("test"), f2 = None), - charSequenceToByteChunk("""{"f1":"test"}""") + charSequenceToByteChunk("""{"$f1":"test"}""") + ) + }, + test("aliased field") { + assertDecodes( + RecordExample.schema, + RecordExample(f1 = Some("test"), f2 = Some("alias")), + charSequenceToByteChunk("""{"$f1":"test", "field2":"alias"}""") + ) + }, + test("reject extra fields") { + assertDecodes( + RecordExample.schema.annotate(rejectExtraFields()), + RecordExample(f1 = Some("test")), + charSequenceToByteChunk("""{"$f1":"test", "extraField":"extra"}""") + ).flip.map(err => assertTrue(err.getMessage() == "(unexpected field: extraField)")) + }, + test("optional field with schema or annotated default value") { + assertDecodes( + RecordExampleWithOptField.schema, + RecordExampleWithOptField(f1 = Some("test"), f2 = None, f4 = "", f5 = "hello"), + charSequenceToByteChunk("""{"$f1":"test"}""") + ) + } + ), + suite("EnumN")( + test("Respects the case name annotation") { + assertDecodes( + Enum23Cases.schema, + Enum23Cases.Case1("foo"), + charSequenceToByteChunk("""{"NumberOne":{"value":"foo"}}""") + ) + }, + test("Respects case aliases") { + assertDecodes( + Enum23Cases.schema, + Enum23Cases.Case1("foo"), + charSequenceToByteChunk("""{"One":{"value":"foo"}}""") ) } ), @@ -1237,11 +1294,9 @@ object JsonCodecSpec extends ZIOSpecDefault { Enumeration3(StringValue3("foo")) ) &> assertEncodesThenDecodes( Schema[Enumeration3], - Enumeration3(StringValue3Multi("foo", "bar")) - ) &> assertEncodesThenDecodes(Schema[Enumeration3], Enumeration3(IntValue3(-1))) &> assertEncodesThenDecodes( - Schema[Enumeration3], - Enumeration3(BooleanValue3(false)) - ) &> assertEncodesThenDecodes(Schema[Enumeration3], Enumeration3(Nested(StringValue3("foo")))) + Enumeration3(StringValue3Multi("foo", "bar")), + print = true + ) }, test("of case classes with discriminator") { assertEncodesThenDecodes(Schema[Command], Command.Cash) &> @@ -1897,9 +1952,9 @@ object JsonCodecSpec extends ZIOSpecDefault { } case class RecordExample( - f1: Option[String], // the only field that does not have a default value - f2: Option[String] = None, - f3: Option[String] = None, + @fieldName("$f1") f1: Option[String], // the only field that does not have a default value + @fieldNameAliases("field2") f2: Option[String] = None, + @transientField f3: Option[String] = None, f4: Option[String] = None, f5: Option[String] = None, f6: Option[String] = None, @@ -1922,8 +1977,90 @@ object JsonCodecSpec extends ZIOSpecDefault { @fieldName("$f23") f23: Option[String] = None ) + case class RecordExampleWithOptField( + @fieldName("$f1") f1: Option[String], // the only field that does not have a default value + @optionalField @fieldNameAliases("field2") f2: Option[String] = None, + @transientField f3: Option[String] = None, + @optionalField f4: String, + @optionalField @fieldDefaultValue("hello") f5: String, + f6: Option[String] = None, + f7: Option[String] = None, + f8: Option[String] = None, + f9: Option[String] = None, + f10: Option[String] = None, + f11: Option[String] = None, + f12: Option[String] = None, + f13: Option[String] = None, + f14: Option[String] = None, + f15: Option[String] = None, + f16: Option[String] = None, + f17: Option[String] = None, + f18: Option[String] = None, + f19: Option[String] = None, + f20: Option[String] = None, + f21: Option[String] = None, + f22: Option[String] = None, + @fieldName("$f23") f23: Option[String] = None + ) + object RecordExample { implicit lazy val schema: Schema[RecordExample] = DeriveSchema.gen[RecordExample] } + object RecordExampleWithOptField { + implicit lazy val schema: Schema[RecordExampleWithOptField] = + DeriveSchema.gen[RecordExampleWithOptField] + } + + sealed trait Enum23Cases + + object Enum23Cases { + implicit lazy val schema: Schema[Enum23Cases] = DeriveSchema.gen[Enum23Cases] + + @caseName("NumberOne") @caseNameAliases("One") case class Case1(value: String) extends Enum23Cases + + case class Case2(value: Int) extends Enum23Cases + + case class Case3(value: String) extends Enum23Cases + + case class Case4(value: String) extends Enum23Cases + + case class Case5(value: String) extends Enum23Cases + + case class Case6(value: String) extends Enum23Cases + + case class Case7(value: String) extends Enum23Cases + + case class Case8(value: String) extends Enum23Cases + + case class Case9(value: String) extends Enum23Cases + + case class Case10(value: String) extends Enum23Cases + + case class Case11(value: String) extends Enum23Cases + + case class Case12(value: String) extends Enum23Cases + + case class Case13(value: String) extends Enum23Cases + + case class Case14(value: String) extends Enum23Cases + + case class Case15(value: String) extends Enum23Cases + + case class Case16(value: String) extends Enum23Cases + + case class Case17(value: String) extends Enum23Cases + + case class Case18(value: String) extends Enum23Cases + + case class Case19(value: String) extends Enum23Cases + + case class Case20(value: String) extends Enum23Cases + + case class Case21(value: String) extends Enum23Cases + + case class Case22(value: String) extends Enum23Cases + + case class Case23(value: String) extends Enum23Cases + } } diff --git a/zio-schema/shared/src/main/scala/zio/schema/Schema.scala b/zio-schema/shared/src/main/scala/zio/schema/Schema.scala index 9c58c9333..ec792b7ff 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Schema.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Schema.scala @@ -394,6 +394,16 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality { val transient: Boolean = annotations.exists(_.isInstanceOf[transientField]) + val nameAndAliases: scala.collection.immutable.Set[String] = + annotations.collect { + case aliases: fieldNameAliases => aliases.aliases + case f: fieldName => Seq(f.name) + }.flatten.toSet + name + + val fieldName: String = annotations.collectFirst { + case f: fieldName => f.name + }.getOrElse(name) + override def toString: String = s"Field($name,$schema)" } From 5c8e7ebebebee950223e0d4e4c3e0057cb0a20b9 Mon Sep 17 00:00:00 2001 From: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com> Date: Sun, 14 Jul 2024 10:08:28 +0300 Subject: [PATCH 09/15] Generate in Scala 3 macro typeId without type parameters (#694) (#702) --- .../shared/src/main/scala-3/zio/schema/DeriveSchema.scala | 6 +++--- .../shared/src/test/scala/zio/schema/DeriveSpec.scala | 3 +++ .../src/main/scala/zio/schema/SchemaPlatformSpecific.scala | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala index 7e4e3fb77..b41711c30 100644 --- a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala @@ -121,7 +121,7 @@ private case class DeriveSchema()(using val ctx: Quotes) { val selfRefSymbol = Symbol.newVal(Symbol.spliceOwner, s"derivedSchema${stack.size}", TypeRepr.of[Schema[T]], Flags.Lazy, Symbol.noSymbol) val selfRef = Ref(selfRefSymbol) - val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].show)})} + val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].classSymbol.get.fullName.replaceAll("\\$", ""))})} val isEnumCase = Type.of[T] match { case '[reflect.Enum] => true case _ => false @@ -201,7 +201,7 @@ private case class DeriveSchema()(using val ctx: Quotes) { List('{zio.schema.annotation.genericTypeInfo(ListMap.from(${typeMembersExpr}.zip(${typeArgsExpr}.map(name => TypeId.parse(name).asInstanceOf[TypeId.Nominal]))))}) } else List.empty val annotations = '{ zio.Chunk.fromIterable(${Expr.ofSeq(annotationExprs)}) ++ zio.Chunk.fromIterable(${Expr.ofSeq(docAnnotationExpr)}) ++ zio.Chunk.fromIterable(${Expr.ofSeq(genericAnnotations)}) } - val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].show)})} + val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].classSymbol.get.fullName.replaceAll("\\$", ""))})} val applied = if (labels.length <= 22) { @@ -390,7 +390,7 @@ private case class DeriveSchema()(using val ctx: Quotes) { } else List.empty val annotations = '{ zio.Chunk.fromIterable(${Expr.ofSeq(annotationExprs)}) ++ zio.Chunk.fromIterable(${Expr.ofSeq(docAnnotationExpr.toList)}) ++ zio.Chunk.fromIterable(${Expr.ofSeq(genericAnnotations)}) } - val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].show)})} + val typeInfo = '{TypeId.parse(${Expr(TypeRepr.of[T].classSymbol.get.fullName.replaceAll("\\$", ""))})} val applied = if (cases.length <= 22) { val args = List(typeInfo) ++ cases :+ annotations diff --git a/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala b/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala index 51a222e08..a4467831a 100644 --- a/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala +++ b/zio-schema-derivation/shared/src/test/scala/zio/schema/DeriveSpec.scala @@ -189,6 +189,9 @@ import zio.{ Chunk, Scope } maybeTypeInfo.contains( genericTypeInfo(ListMap("T" -> TypeId.parse("scala.Int").asInstanceOf[TypeId.Nominal])) ), + capturedSchema.schema.asInstanceOf[Schema.Record[GenericRecordWithDefaultValue[Int]]].id == TypeId.parse( + "zio.schema.DeriveSpec.GenericRecordWithDefaultValue" + ), annotations.exists { a => a.isInstanceOf[fieldDefaultValue[_]] && a.asInstanceOf[fieldDefaultValue[Option[Int]]].value == None diff --git a/zio-schema/jvm/src/main/scala/zio/schema/SchemaPlatformSpecific.scala b/zio-schema/jvm/src/main/scala/zio/schema/SchemaPlatformSpecific.scala index f256da2da..faef5f72d 100644 --- a/zio-schema/jvm/src/main/scala/zio/schema/SchemaPlatformSpecific.scala +++ b/zio-schema/jvm/src/main/scala/zio/schema/SchemaPlatformSpecific.scala @@ -6,7 +6,7 @@ trait SchemaPlatformSpecific { Schema[String].transformOrFail( string => try { - Right(new java.net.URL(string)) + Right(new java.net.URI(string).toURL) } catch { case _: Exception => Left(s"Invalid URL: $string") }, url => Right(url.toString) ) From d0d87173961a71180c5a317b1e6a1557488486f7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 14 Jul 2024 09:56:45 +0200 Subject: [PATCH 10/15] Update README.md (#699) Co-authored-by: github-actions[bot] --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index acb2a97f1..2ff5a2ad4 100644 --- a/README.md +++ b/README.md @@ -39,17 +39,17 @@ _ZIO Schema_ is used by a growing number of ZIO libraries, including [ZIO Flow]( In order to use this library, we need to add the following lines in our `build.sbt` file: ```scala -libraryDependencies += "dev.zio" %% "zio-schema" % "1.2.1" -libraryDependencies += "dev.zio" %% "zio-schema-avro" % "1.2.1" -libraryDependencies += "dev.zio" %% "zio-schema-bson" % "1.2.1" -libraryDependencies += "dev.zio" %% "zio-schema-json" % "1.2.1" -libraryDependencies += "dev.zio" %% "zio-schema-msg-pack" % "1.2.1" -libraryDependencies += "dev.zio" %% "zio-schema-protobuf" % "1.2.1" -libraryDependencies += "dev.zio" %% "zio-schema-thrift" % "1.2.1" -libraryDependencies += "dev.zio" %% "zio-schema-zio-test" % "1.2.1" +libraryDependencies += "dev.zio" %% "zio-schema" % "1.2.2" +libraryDependencies += "dev.zio" %% "zio-schema-avro" % "1.2.2" +libraryDependencies += "dev.zio" %% "zio-schema-bson" % "1.2.2" +libraryDependencies += "dev.zio" %% "zio-schema-json" % "1.2.2" +libraryDependencies += "dev.zio" %% "zio-schema-msg-pack" % "1.2.2" +libraryDependencies += "dev.zio" %% "zio-schema-protobuf" % "1.2.2" +libraryDependencies += "dev.zio" %% "zio-schema-thrift" % "1.2.2" +libraryDependencies += "dev.zio" %% "zio-schema-zio-test" % "1.2.2" // Required for the automatic generic derivation of schemas -libraryDependencies += "dev.zio" %% "zio-schema-derivation" % "1.2.1" +libraryDependencies += "dev.zio" %% "zio-schema-derivation" % "1.2.2" libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided" ``` From 5a276f7417b3039f46da7c85ca41e00c4f993be0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 14 Jul 2024 10:04:35 +0200 Subject: [PATCH 11/15] Update README.md (#713) Co-authored-by: github-actions[bot] --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2ff5a2ad4..adf1dc5b0 100644 --- a/README.md +++ b/README.md @@ -39,17 +39,17 @@ _ZIO Schema_ is used by a growing number of ZIO libraries, including [ZIO Flow]( In order to use this library, we need to add the following lines in our `build.sbt` file: ```scala -libraryDependencies += "dev.zio" %% "zio-schema" % "1.2.2" -libraryDependencies += "dev.zio" %% "zio-schema-avro" % "1.2.2" -libraryDependencies += "dev.zio" %% "zio-schema-bson" % "1.2.2" -libraryDependencies += "dev.zio" %% "zio-schema-json" % "1.2.2" -libraryDependencies += "dev.zio" %% "zio-schema-msg-pack" % "1.2.2" -libraryDependencies += "dev.zio" %% "zio-schema-protobuf" % "1.2.2" -libraryDependencies += "dev.zio" %% "zio-schema-thrift" % "1.2.2" -libraryDependencies += "dev.zio" %% "zio-schema-zio-test" % "1.2.2" +libraryDependencies += "dev.zio" %% "zio-schema" % "1.3.0" +libraryDependencies += "dev.zio" %% "zio-schema-avro" % "1.3.0" +libraryDependencies += "dev.zio" %% "zio-schema-bson" % "1.3.0" +libraryDependencies += "dev.zio" %% "zio-schema-json" % "1.3.0" +libraryDependencies += "dev.zio" %% "zio-schema-msg-pack" % "1.3.0" +libraryDependencies += "dev.zio" %% "zio-schema-protobuf" % "1.3.0" +libraryDependencies += "dev.zio" %% "zio-schema-thrift" % "1.3.0" +libraryDependencies += "dev.zio" %% "zio-schema-zio-test" % "1.3.0" // Required for the automatic generic derivation of schemas -libraryDependencies += "dev.zio" %% "zio-schema-derivation" % "1.2.2" +libraryDependencies += "dev.zio" %% "zio-schema-derivation" % "1.3.0" libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided" ``` From eb71680e001c1776e4094ab29bbeb2338b152d77 Mon Sep 17 00:00:00 2001 From: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com> Date: Fri, 9 Aug 2024 20:20:29 +0200 Subject: [PATCH 12/15] Run all possible test for all Scala 3 (#709) (#721) --- .../zio/schema/PlatformSpecificGen.scala | 8 +- .../zio/schema/PlatformSpecificGen.scala | 24 --- .../zio/schema/PlatformSpecificGen.scala | 24 +++ .../zio/schema/PlatformSpecificGen.scala | 8 +- .../scala-2/zio/schema/StandardTypeGen.scala | 87 --------- .../zio/schema/AccessorBuilderSpec.scala | 19 +- .../zio/schema/DynamicValueGen.scala | 6 +- .../zio/schema/DynamicValueSpec.scala | 0 .../zio/schema/MetaSchemaSpec.scala | 0 .../zio/schema/OrderingSpec.scala | 60 +++--- .../zio/schema/PatchSpec.scala | 2 +- .../zio/schema/SchemaGen.scala | 180 +++++++++--------- .../zio/schema/SchemaMigrationSpec.scala | 0 .../scala/zio/schema/StandardTypeGen.scala | 89 +++++++++ .../{scala-2 => scala}/zio/schema/types.scala | 6 +- .../zio/schema/codec/AvroCodecSpec.scala | 0 .../schema/codec/AvroSchemaCodecSpec.scala | 9 +- .../scala-3/zio/schema/DeriveSchema.scala | 20 +- .../zio/schema/codec/JsonCodecJVMSpec.scala | 0 .../zio/schema/codec/JsonCodecSpec.scala | 0 .../schema/codec/MessagePackCodecSpec.scala | 0 .../zio/schema/codec/ProtobufCodecSpec.scala | 0 .../zio/schema/codec/ThriftCodecSpec.scala | 0 .../schema/codec/generated/BasicDouble.java | 0 .../zio/schema/codec/generated/BasicInt.java | 0 .../schema/codec/generated/BasicString.java | 0 .../zio/schema/codec/generated/BoolValue.java | 0 .../zio/schema/codec/generated/Color.java | 0 .../zio/schema/codec/generated/Embedded.java | 0 .../zio/schema/codec/generated/EnumValue.java | 0 .../schema/codec/generated/Enumeration.java | 0 .../zio/schema/codec/generated/HighArity.java | 0 .../zio/schema/codec/generated/IntList.java | 0 .../zio/schema/codec/generated/IntValue.java | 0 .../zio/schema/codec/generated/MapValue.java | 0 .../zio/schema/codec/generated/OneOf.java | 0 .../zio/schema/codec/generated/Record.java | 0 .../zio/schema/codec/generated/SetValue.java | 0 .../schema/codec/generated/StringList.java | 0 .../schema/codec/generated/StringValue.java | 0 40 files changed, 282 insertions(+), 260 deletions(-) rename tests/js/src/test/{scala-2 => scala}/zio/schema/PlatformSpecificGen.scala (50%) delete mode 100644 tests/jvm/src/test/scala-2/zio/schema/PlatformSpecificGen.scala create mode 100644 tests/jvm/src/test/scala/zio/schema/PlatformSpecificGen.scala rename tests/native/src/test/{scala-2 => scala}/zio/schema/PlatformSpecificGen.scala (50%) delete mode 100644 tests/shared/src/test/scala-2/zio/schema/StandardTypeGen.scala rename tests/shared/src/test/{scala-2 => scala}/zio/schema/AccessorBuilderSpec.scala (92%) rename tests/shared/src/test/{scala-2 => scala}/zio/schema/DynamicValueGen.scala (98%) rename tests/shared/src/test/{scala-2 => scala}/zio/schema/DynamicValueSpec.scala (100%) rename tests/shared/src/test/{scala-2 => scala}/zio/schema/MetaSchemaSpec.scala (100%) rename tests/shared/src/test/{scala-2 => scala}/zio/schema/OrderingSpec.scala (90%) rename tests/shared/src/test/{scala-2 => scala}/zio/schema/PatchSpec.scala (99%) rename tests/shared/src/test/{scala-2 => scala}/zio/schema/SchemaGen.scala (82%) rename tests/shared/src/test/{scala-2 => scala}/zio/schema/SchemaMigrationSpec.scala (100%) create mode 100644 tests/shared/src/test/scala/zio/schema/StandardTypeGen.scala rename tests/shared/src/test/{scala-2 => scala}/zio/schema/types.scala (98%) rename zio-schema-avro/src/test/{scala-2 => scala}/zio/schema/codec/AvroCodecSpec.scala (100%) rename zio-schema-avro/src/test/{scala-2 => scala}/zio/schema/codec/AvroSchemaCodecSpec.scala (99%) rename zio-schema-json/jvm/src/test/{scala-2 => scala}/zio/schema/codec/JsonCodecJVMSpec.scala (100%) rename zio-schema-json/shared/src/test/{scala-2 => scala}/zio/schema/codec/JsonCodecSpec.scala (100%) rename zio-schema-msg-pack/src/test/{scala-2 => scala}/zio/schema/codec/MessagePackCodecSpec.scala (100%) rename zio-schema-protobuf/shared/src/test/{scala-2 => scala}/zio/schema/codec/ProtobufCodecSpec.scala (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/ThriftCodecSpec.scala (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/BasicDouble.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/BasicInt.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/BasicString.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/BoolValue.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/Color.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/Embedded.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/EnumValue.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/Enumeration.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/HighArity.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/IntList.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/IntValue.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/MapValue.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/OneOf.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/Record.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/SetValue.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/StringList.java (100%) rename zio-schema-thrift/src/test/{scala-2 => scala}/zio/schema/codec/generated/StringValue.java (100%) diff --git a/tests/js/src/test/scala-2/zio/schema/PlatformSpecificGen.scala b/tests/js/src/test/scala/zio/schema/PlatformSpecificGen.scala similarity index 50% rename from tests/js/src/test/scala-2/zio/schema/PlatformSpecificGen.scala rename to tests/js/src/test/scala/zio/schema/PlatformSpecificGen.scala index 941b41d24..490027d60 100644 --- a/tests/js/src/test/scala-2/zio/schema/PlatformSpecificGen.scala +++ b/tests/js/src/test/scala/zio/schema/PlatformSpecificGen.scala @@ -6,14 +6,14 @@ import zio.test.Gen object PlatformSpecificGen { - val platformSpecificStandardTypes: Gen[Any, StandardType[_]] = Gen.fromIterable( + val platformSpecificStandardTypes: Gen[Any, StandardType[Any]] = Gen.fromIterable( List.empty ) - def platformSpecificStandardTypeAndGen(standardTypeGen: StandardType[_]): StandardTypeAndGen[_] = + def platformSpecificStandardTypeAndGen(standardTypeGen: StandardType[Any]): StandardTypeAndGen[Any] = standardTypeGen match { - case _ => StandardType.UnitType -> Gen.unit: StandardTypeAndGen[_] + case _ => StandardType.UnitType.asInstanceOf[StandardType[Any]] -> Gen.unit } - val platformSpecificSchemasAndGens: List[SchemaTest[_]] = List.empty + val platformSpecificSchemasAndGens: List[SchemaTest[Any]] = List.empty } diff --git a/tests/jvm/src/test/scala-2/zio/schema/PlatformSpecificGen.scala b/tests/jvm/src/test/scala-2/zio/schema/PlatformSpecificGen.scala deleted file mode 100644 index ceeb2381c..000000000 --- a/tests/jvm/src/test/scala-2/zio/schema/PlatformSpecificGen.scala +++ /dev/null @@ -1,24 +0,0 @@ -package zio.schema - -import zio.schema.SchemaGen.SchemaTest -import zio.schema.StandardTypeGen.StandardTypeAndGen -import zio.test.Gen - -object PlatformSpecificGen { - - val platformSpecificStandardTypes: Gen[Any, StandardType[_]] = Gen.fromIterable( - List( - StandardType.CurrencyType - ) - ) - - def platformSpecificStandardTypeAndGen(standardTypeGen: StandardType[_]): StandardTypeAndGen[_] = - standardTypeGen match { - case typ: StandardType.CurrencyType.type => typ -> Gen.currency - case _ => StandardType.UnitType -> Gen.unit: StandardTypeAndGen[_] - } - - val platformSpecificSchemasAndGens: List[SchemaTest[_]] = List( - SchemaTest("Currency", StandardType.CurrencyType, Gen.currency) - ) -} diff --git a/tests/jvm/src/test/scala/zio/schema/PlatformSpecificGen.scala b/tests/jvm/src/test/scala/zio/schema/PlatformSpecificGen.scala new file mode 100644 index 000000000..97da5edb9 --- /dev/null +++ b/tests/jvm/src/test/scala/zio/schema/PlatformSpecificGen.scala @@ -0,0 +1,24 @@ +package zio.schema + +import zio.schema.SchemaGen.SchemaTest +import zio.schema.StandardTypeGen.StandardTypeAndGen +import zio.test.Gen + +object PlatformSpecificGen { + + val platformSpecificStandardTypes: Gen[Any, StandardType[Any]] = Gen.fromIterable( + List( + StandardType.CurrencyType + ).map(_.asInstanceOf[StandardType[Any]]) + ) + + def platformSpecificStandardTypeAndGen(standardTypeGen: StandardType[Any]): StandardTypeAndGen[Any] = + standardTypeGen match { + case typ if typ.isInstanceOf[StandardType.CurrencyType.type] => typ -> Gen.currency + case _ => StandardType.UnitType.asInstanceOf[StandardType[Any]] -> Gen.unit + } + + val platformSpecificSchemasAndGens: List[SchemaTest[Any]] = List( + SchemaTest("Currency", StandardType.CurrencyType.asInstanceOf[StandardType[Any]], Gen.currency) + ) +} diff --git a/tests/native/src/test/scala-2/zio/schema/PlatformSpecificGen.scala b/tests/native/src/test/scala/zio/schema/PlatformSpecificGen.scala similarity index 50% rename from tests/native/src/test/scala-2/zio/schema/PlatformSpecificGen.scala rename to tests/native/src/test/scala/zio/schema/PlatformSpecificGen.scala index 941b41d24..490027d60 100644 --- a/tests/native/src/test/scala-2/zio/schema/PlatformSpecificGen.scala +++ b/tests/native/src/test/scala/zio/schema/PlatformSpecificGen.scala @@ -6,14 +6,14 @@ import zio.test.Gen object PlatformSpecificGen { - val platformSpecificStandardTypes: Gen[Any, StandardType[_]] = Gen.fromIterable( + val platformSpecificStandardTypes: Gen[Any, StandardType[Any]] = Gen.fromIterable( List.empty ) - def platformSpecificStandardTypeAndGen(standardTypeGen: StandardType[_]): StandardTypeAndGen[_] = + def platformSpecificStandardTypeAndGen(standardTypeGen: StandardType[Any]): StandardTypeAndGen[Any] = standardTypeGen match { - case _ => StandardType.UnitType -> Gen.unit: StandardTypeAndGen[_] + case _ => StandardType.UnitType.asInstanceOf[StandardType[Any]] -> Gen.unit } - val platformSpecificSchemasAndGens: List[SchemaTest[_]] = List.empty + val platformSpecificSchemasAndGens: List[SchemaTest[Any]] = List.empty } diff --git a/tests/shared/src/test/scala-2/zio/schema/StandardTypeGen.scala b/tests/shared/src/test/scala-2/zio/schema/StandardTypeGen.scala deleted file mode 100644 index 98a5570be..000000000 --- a/tests/shared/src/test/scala-2/zio/schema/StandardTypeGen.scala +++ /dev/null @@ -1,87 +0,0 @@ -package zio.schema - -import java.math.{ BigDecimal => JBigDecimal, BigInteger => JBigInt } - -import zio.schema.PlatformSpecificGen.{ platformSpecificStandardTypeAndGen, platformSpecificStandardTypes } -import zio.test.{ Gen, Sized } - -object StandardTypeGen { - - //IMPORTANT! - Updating the following list without updating the schema primitive case set in zio.schema.DynamicValue.schema will trigger a set of very obscure test failures - val anyStandardType: Gen[Any, StandardType[_]] = Gen.fromIterable( - List( - StandardType.StringType, - StandardType.BoolType, - StandardType.ShortType, - StandardType.IntType, - StandardType.LongType, - StandardType.FloatType, - StandardType.DoubleType, - StandardType.BinaryType, - StandardType.BigDecimalType, - StandardType.BigIntegerType, - StandardType.CharType, - StandardType.UUIDType, - StandardType.DayOfWeekType, - StandardType.DurationType, - StandardType.InstantType, - StandardType.LocalDateType, - StandardType.LocalDateTimeType, - StandardType.LocalTimeType, - StandardType.MonthType, - StandardType.MonthDayType, - StandardType.OffsetDateTimeType, - StandardType.OffsetTimeType, - StandardType.PeriodType, - StandardType.YearType, - StandardType.YearMonthType, - StandardType.ZonedDateTimeType, - StandardType.ZoneIdType, - StandardType.ZoneOffsetType - ) - ) ++ platformSpecificStandardTypes - - val javaBigInt: Gen[Any, JBigInt] = - Gen.bigInt(JBigInt.valueOf(Long.MinValue), JBigInt.valueOf(Long.MaxValue)).map { sBigInt => - new JBigInt(sBigInt.toByteArray) - } - - val javaBigDecimal: Gen[Any, JBigDecimal] = - Gen.bigDecimal(JBigDecimal.valueOf(Long.MinValue), JBigDecimal.valueOf(Long.MaxValue)).map(_.bigDecimal) - - type StandardTypeAndGen[A] = (StandardType[A], Gen[Sized, A]) - - val anyStandardTypeAndGen: Gen[Any, StandardTypeAndGen[_]] = { - anyStandardType.map { - case typ: StandardType.StringType.type => typ -> Gen.string - case typ: StandardType.BoolType.type => typ -> Gen.boolean - case typ: StandardType.ShortType.type => typ -> Gen.short - case typ: StandardType.IntType.type => typ -> Gen.int - case typ: StandardType.LongType.type => typ -> Gen.long - case typ: StandardType.FloatType.type => typ -> Gen.float - case typ: StandardType.DoubleType.type => typ -> Gen.double - case typ: StandardType.BinaryType.type => typ -> Gen.chunkOf(Gen.byte) - case typ: StandardType.CharType.type => typ -> Gen.asciiChar - case typ: StandardType.UUIDType.type => typ -> Gen.uuid - case typ: StandardType.BigDecimalType.type => typ -> javaBigDecimal - case typ: StandardType.BigIntegerType.type => typ -> javaBigInt - case typ: StandardType.DayOfWeekType.type => typ -> JavaTimeGen.anyDayOfWeek - case typ: StandardType.DurationType.type => typ -> JavaTimeGen.anyDuration - case typ: StandardType.InstantType.type => typ -> JavaTimeGen.anyInstant - case typ: StandardType.LocalDateType.type => typ -> JavaTimeGen.anyLocalDate - case typ: StandardType.LocalDateTimeType.type => typ -> JavaTimeGen.anyLocalDateTime - case typ: StandardType.LocalTimeType.type => typ -> JavaTimeGen.anyLocalTime - case typ: StandardType.MonthType.type => typ -> JavaTimeGen.anyMonth - case typ: StandardType.MonthDayType.type => typ -> JavaTimeGen.anyMonthDay - case typ: StandardType.OffsetDateTimeType.type => typ -> JavaTimeGen.anyOffsetDateTime - case typ: StandardType.OffsetTimeType.type => typ -> JavaTimeGen.anyOffsetTime - case typ: StandardType.PeriodType.type => typ -> JavaTimeGen.anyPeriod - case typ: StandardType.YearType.type => typ -> JavaTimeGen.anyYear - case typ: StandardType.YearMonthType.type => typ -> JavaTimeGen.anyYearMonth - case typ: StandardType.ZonedDateTimeType.type => typ -> JavaTimeGen.anyZonedDateTime - case typ: StandardType.ZoneIdType.type => typ -> JavaTimeGen.anyZoneId - case typ: StandardType.ZoneOffsetType.type => typ -> JavaTimeGen.anyZoneOffset - case typ => platformSpecificStandardTypeAndGen(typ) - } - } -} diff --git a/tests/shared/src/test/scala-2/zio/schema/AccessorBuilderSpec.scala b/tests/shared/src/test/scala/zio/schema/AccessorBuilderSpec.scala similarity index 92% rename from tests/shared/src/test/scala-2/zio/schema/AccessorBuilderSpec.scala rename to tests/shared/src/test/scala/zio/schema/AccessorBuilderSpec.scala index 867d7ff29..771e609db 100644 --- a/tests/shared/src/test/scala-2/zio/schema/AccessorBuilderSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/AccessorBuilderSpec.scala @@ -5,8 +5,8 @@ import zio.schema.SchemaGen.Json.schema import zio.test._ object AccessorBuilderSpec extends ZIOSpecDefault { - import TestAccessorBuilder._ import Assertion._ + import TestAccessorBuilder._ private val builder: TestAccessorBuilder = new TestAccessorBuilder @@ -70,15 +70,12 @@ object AccessorBuilderSpec extends ZIOSpecDefault { val accessor = tupleSchema.makeAccessors(builder) - assert( - accessor match { - case (Lens(r1, f1), Lens(r2, f2)) => - r1 == r2 && r2 == tupleSchema.toRecord && - f1.name == "_1" && f1.schema == leftSchema && - f2.name == "_2" && f2.schema == rightSchema - case _ => false - } - )(isTrue) + assertTrue(accessor match { + case (Lens(r1, f1), Lens(r2, f2)) => + r1 == r2 && r2 == tupleSchema.toRecord && + f1.name == "_1" && f1.schema == leftSchema && + f2.name == "_2" && f2.schema == rightSchema + }) } }, test("either") { @@ -122,8 +119,6 @@ object AccessorBuilderSpec extends ZIOSpecDefault { accessor match { case (Lens(r1, f1), Lens(r2, f2), Lens(r3, f3)) => r1 == schema && r2 == schema && r3 == schema && f1 == schema.field1 && f2 == schema.field2 && f3 == schema.field3 - case _ => false - } ) }, diff --git a/tests/shared/src/test/scala-2/zio/schema/DynamicValueGen.scala b/tests/shared/src/test/scala/zio/schema/DynamicValueGen.scala similarity index 98% rename from tests/shared/src/test/scala-2/zio/schema/DynamicValueGen.scala rename to tests/shared/src/test/scala/zio/schema/DynamicValueGen.scala index d5a5e73d4..d17941483 100644 --- a/tests/shared/src/test/scala-2/zio/schema/DynamicValueGen.scala +++ b/tests/shared/src/test/scala/zio/schema/DynamicValueGen.scala @@ -81,7 +81,11 @@ object DynamicValueGen { case Schema.Either(left, right, _) => Gen.oneOf(anyDynamicLeftValueOfSchema(left), anyDynamicRightValueOfSchema(right)) case Schema.Fallback(left, right, _, _) => - Gen.oneOf(anyDynamicLeftValueOfSchema(left), anyDynamicRightValueOfSchema(right), anyDynamicBothValueOfSchema(left, right)) + Gen.oneOf[Sized, DynamicValue]( + anyDynamicLeftValueOfSchema(left.asInstanceOf[Schema[Any]]), + anyDynamicRightValueOfSchema(right.asInstanceOf[Schema[Any]]), + anyDynamicBothValueOfSchema(left.asInstanceOf[Schema[Any]], right.asInstanceOf[Schema[Any]]) + ) case Schema.Transform(schema, _, _, _, _) => anyDynamicValueOfSchema(schema) case Schema.Fail(message, _) => Gen.const(DynamicValue.Error(message)) case l @ Schema.Lazy(_) => anyDynamicValueOfSchema(l.schema) diff --git a/tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala b/tests/shared/src/test/scala/zio/schema/DynamicValueSpec.scala similarity index 100% rename from tests/shared/src/test/scala-2/zio/schema/DynamicValueSpec.scala rename to tests/shared/src/test/scala/zio/schema/DynamicValueSpec.scala diff --git a/tests/shared/src/test/scala-2/zio/schema/MetaSchemaSpec.scala b/tests/shared/src/test/scala/zio/schema/MetaSchemaSpec.scala similarity index 100% rename from tests/shared/src/test/scala-2/zio/schema/MetaSchemaSpec.scala rename to tests/shared/src/test/scala/zio/schema/MetaSchemaSpec.scala diff --git a/tests/shared/src/test/scala-2/zio/schema/OrderingSpec.scala b/tests/shared/src/test/scala/zio/schema/OrderingSpec.scala similarity index 90% rename from tests/shared/src/test/scala-2/zio/schema/OrderingSpec.scala rename to tests/shared/src/test/scala/zio/schema/OrderingSpec.scala index 2e33499d3..8e2edbbbe 100644 --- a/tests/shared/src/test/scala-2/zio/schema/OrderingSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/OrderingSpec.scala @@ -53,7 +53,7 @@ object OrderingSpec extends ZIOSpecDefault { assert(schemaOrdering.compare(l, r))(equalTo(standardType.compare(l, r))) } - case class StructureTestCase(name: String, increasingPairGen: Gen[Sized, SchemaAndPair[_]]) + case class StructureTestCase(name: String, increasingPairGen: Gen[Sized, SchemaAndPair[Any]]) private val structureTestCases = Seq( @@ -72,11 +72,11 @@ object OrderingSpec extends ZIOSpecDefault { assert(schema.ordering.compare(l, r))(isLessThan(0)) })) - def genAnyOrderedPairOption: Gen[Sized, SchemaAndPair[Option[_]]] = + def genAnyOrderedPairOption: Gen[Sized, SchemaAndPair[Any]] = for { schema <- anySchema (l, r) <- genOrderedPairOption(schema) - } yield (Schema.Optional(schema), l, r).asInstanceOf[SchemaAndPair[Option[_]]] + } yield (Schema.Optional(schema), l, r).asInstanceOf[SchemaAndPair[Any]] def genOrderedPairOption[A](schema: Schema[A]): Gen[Sized, (Option[A], Option[A])] = Gen.oneOf( @@ -88,12 +88,12 @@ object OrderingSpec extends ZIOSpecDefault { } yield (None, Some(a)) ) - def genAnyOrderedPairEither: Gen[Sized, SchemaAndPair[Either[_, _]]] = + def genAnyOrderedPairEither: Gen[Sized, SchemaAndPair[Any]] = for { leftSchema <- anySchema rightSchema <- anySchema (l, r) <- genOrderedPairEither(leftSchema, rightSchema) - } yield (Schema.Either(leftSchema, rightSchema), l, r).asInstanceOf[SchemaAndPair[Either[_, _]]] + } yield (Schema.Either(leftSchema, rightSchema), l, r).asInstanceOf[SchemaAndPair[Any]] def genOrderedPairEither[A, B]( lSchema: Schema[A], @@ -111,12 +111,12 @@ object OrderingSpec extends ZIOSpecDefault { } yield (Left(l), Right(r)) ) - def genAnyOrderedPairTuple: Gen[Sized, SchemaAndPair[_]] = + def genAnyOrderedPairTuple: Gen[Sized, SchemaAndPair[Any]] = for { xSchema <- anySchema ySchema <- anySchema (l, r) <- genOrderedPairTuple(xSchema, ySchema) - } yield (Schema.Tuple2(xSchema, ySchema), l, r).asInstanceOf[SchemaAndPair[Either[_, _]]] + } yield (Schema.Tuple2(xSchema, ySchema), l, r).asInstanceOf[SchemaAndPair[Any]] def genOrderedPairTuple[A, B]( xSchema: Schema[A], @@ -134,17 +134,17 @@ object OrderingSpec extends ZIOSpecDefault { } yield ((x, smallY), (x, largeY)) ) - def genAnyOrderedPairChunks: Gen[Sized, SchemaAndPair[_]] = + def genAnyOrderedPairChunks: Gen[Sized, SchemaAndPair[Any]] = anySchema.flatMap(genOrderedPairChunk(_)) - def genOrderedPairChunk[A](schema: Schema[A]): Gen[Sized, SchemaAndPair[_]] = + def genOrderedPairChunk[A](schema: Schema[A]): Gen[Sized, SchemaAndPair[Any]] = for { init <- Gen.chunkOf(genFromSchema(schema)) rems <- Gen.oneOf( genChunkPairWithOrderedFirstElement(schema), genChunkPairWithOnlyFirstEmpty(schema) ) - } yield (Schema.chunk(schema), init ++ rems._1, init ++ rems._2) + } yield (Schema.chunk(schema), init ++ rems._1, init ++ rems._2).asInstanceOf[SchemaAndPair[Any]] def genChunkPairWithOrderedFirstElement[A]( schema: Schema[A] @@ -161,20 +161,22 @@ object OrderingSpec extends ZIOSpecDefault { rem <- Gen.chunkOf(genFromSchema(schema)) } yield (Chunk(), init +: rem) - def genAnyOrderedPairTransform: Gen[Sized, SchemaAndPair[_]] = - Gen.oneOf( - anySchema.flatMap(genOrderedPairIdentityTransform(_)), - anySchema.flatMap(genOrderedPairDecodeTransform(_)) - ) + def genAnyOrderedPairTransform: Gen[Sized, SchemaAndPair[Any]] = + Gen + .oneOf( + anySchema.flatMap(genOrderedPairIdentityTransform(_)), + anySchema.flatMap(genOrderedPairDecodeTransform(_)) + ) + .asInstanceOf[Gen[Sized, SchemaAndPair[Any]]] - def genOrderedPairIdentityTransform[A](schema: Schema[A]): Gen[Sized, SchemaAndPair[_]] = + def genOrderedPairIdentityTransform[A](schema: Schema[A]): Gen[Sized, SchemaAndPair[Any]] = for { (small, large) <- genOrderedPair(schema) } yield (schema.transformOrFail({ (a: A) => Right(a) }, { (a: A) => Right(a) - }), small, large) + }), small, large).asInstanceOf[SchemaAndPair[Any]] def genOrderedPairDecodeTransform[A]( schema: Schema[A] @@ -189,14 +191,14 @@ object OrderingSpec extends ZIOSpecDefault { largeEncoded = encode(large).toOption.get } yield (schema.transformOrFail(encode, decode), smallEncodedOrError, largeEncoded) - def genAnyOrderedPairRecord: Gen[Sized, SchemaAndPair[_]] = + def genAnyOrderedPairRecord: Gen[Sized, SchemaAndPair[Any]] = for { name <- Gen.string(Gen.alphaChar).map(TypeId.parse) schema <- anyStructure(anyTree(1)).map(fieldSet => { Schema.GenericRecord(name, fieldSet) }) pair <- genOrderedPairRecord(schema) - } yield pair + } yield pair.asInstanceOf[SchemaAndPair[Any]] def genOrderedPairRecord[A](schema: Schema.Record[A]): Gen[Sized, SchemaAndPair[A]] = { val fields: Chunk[Schema.Field[A, _]] = schema.fields @@ -257,13 +259,15 @@ object OrderingSpec extends ZIOSpecDefault { } yield (field.name, dx, dy) +: rem } - def genAnyOrderedPairEnum: Gen[Sized, SchemaAndPair[_]] = - anyEnumSchema.flatMap(schema => { - Gen.oneOf( - genOrderedPairEnumSameCase(schema), - genOrderedPairEnumDiffCase(schema) - ) - }) + def genAnyOrderedPairEnum: Gen[Sized, SchemaAndPair[Any]] = + anyEnumSchema + .flatMap(schema => { + Gen.oneOf( + genOrderedPairEnumSameCase(schema), + genOrderedPairEnumDiffCase(schema) + ) + }) + .asInstanceOf[Gen[Sized, SchemaAndPair[Any]]] def genOrderedPairEnumSameCase[A](schema: Schema.Enum[A]): Gen[Sized, SchemaAndPair[A]] = for { @@ -305,7 +309,7 @@ object OrderingSpec extends ZIOSpecDefault { .anyDynamicValueOfSchema(schema) .map(d => schema.fromDynamic(d).toOption.get) - def genAnyOrderedPair: Gen[Sized, SchemaAndPair[_]] = + def genAnyOrderedPair: Gen[Sized, SchemaAndPair[Any]] = for { schema <- anySchema (x, y) <- genOrderedPair(schema) @@ -326,7 +330,7 @@ object OrderingSpec extends ZIOSpecDefault { DynamicValue.fromSchemaAndValue(schema, large.asInstanceOf[A]) ) - def genAnyOrderedTriplet: Gen[Sized, SchemaAndTriplet[_]] = + def genAnyOrderedTriplet: Gen[Sized, SchemaAndTriplet[Any]] = for { schema <- anySchema (x, y, z) <- genOrderedTriplet(schema) diff --git a/tests/shared/src/test/scala-2/zio/schema/PatchSpec.scala b/tests/shared/src/test/scala/zio/schema/PatchSpec.scala similarity index 99% rename from tests/shared/src/test/scala-2/zio/schema/PatchSpec.scala rename to tests/shared/src/test/scala/zio/schema/PatchSpec.scala index 07701496e..c04e4272d 100644 --- a/tests/shared/src/test/scala-2/zio/schema/PatchSpec.scala +++ b/tests/shared/src/test/scala/zio/schema/PatchSpec.scala @@ -148,7 +148,7 @@ object PatchSpec extends ZIOSpecDefault { } val finalTestName = renamingFuncOption.fold(name)(renamingFunc => renamingFunc(name)) standardType match { - case _ @StandardType.MonthDayType => + case s if s.isInstanceOf[StandardType.MonthDayType.type] => test(finalTestName) { patchingFunc(finalSchema) } @@ TestAspect.ignore // TODO Leap years! diff --git a/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala b/tests/shared/src/test/scala/zio/schema/SchemaGen.scala similarity index 82% rename from tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala rename to tests/shared/src/test/scala/zio/schema/SchemaGen.scala index 46405ce2c..41f5c6116 100644 --- a/tests/shared/src/test/scala-2/zio/schema/SchemaGen.scala +++ b/tests/shared/src/test/scala/zio/schema/SchemaGen.scala @@ -50,8 +50,8 @@ object SchemaGen { .map(_.toSeq) def anyEnumeration( - schemaGen: Gen[Sized, Schema[_]] - ): Gen[Sized, ListMap[String, Schema[_]]] = + schemaGen: Gen[Sized, Schema[Any]] + ): Gen[Sized, ListMap[String, Schema[Any]]] = Gen .setOfBounded(1, 3)( anyLabel.zip(schemaGen) @@ -61,19 +61,19 @@ object SchemaGen { def anyEnumeration[A](schema: Schema[A]): Gen[Sized, ListMap[String, Schema[A]]] = Gen.setOfBounded(1, 3)(anyLabel.map(_ -> schema)).map(ListMap.empty ++ _) - val anyPrimitive: Gen[Any, Schema.Primitive[_]] = + val anyPrimitive: Gen[Any, Schema.Primitive[Any]] = StandardTypeGen.anyStandardType.map(Schema.Primitive(_, Chunk.empty)) type PrimitiveAndGen[A] = (Schema.Primitive[A], Gen[Sized, A]) - val anyPrimitiveAndGen: Gen[Any, PrimitiveAndGen[_]] = + val anyPrimitiveAndGen: Gen[Any, PrimitiveAndGen[Any]] = StandardTypeGen.anyStandardTypeAndGen.map { case (standardType, gen) => Schema.Primitive(standardType, Chunk.empty) -> gen } type PrimitiveAndValue[A] = (Schema.Primitive[A], A) - val anyPrimitiveAndValue: Gen[Sized, PrimitiveAndValue[_]] = + val anyPrimitiveAndValue: Gen[Sized, PrimitiveAndValue[Any]] = for { (schema, gen) <- anyPrimitiveAndGen value <- gen @@ -86,20 +86,20 @@ object SchemaGen { type OptionalAndGen[A] = (Schema.Optional[A], Gen[Sized, Option[A]]) - val anyOptionalAndGen: Gen[Sized, OptionalAndGen[_]] = + val anyOptionalAndGen: Gen[Sized, OptionalAndGen[Any]] = anyPrimitiveAndGen.map { case (schema, gen) => Schema.Optional(schema) -> Gen.option(gen) } type OptionalAndValue[A] = (Schema.Optional[A], Option[A]) - val anyOptionalAndValue: Gen[Sized, OptionalAndValue[_]] = + val anyOptionalAndValue: Gen[Sized, OptionalAndValue[Any]] = for { (schema, gen) <- anyOptionalAndGen value <- gen } yield schema -> value - val anyEither: Gen[Sized, Schema.Either[_, _]] = + val anyEither: Gen[Sized, Schema.Either[Any, Any]] = for { left <- anyPrimitive right <- anyPrimitive @@ -107,7 +107,7 @@ object SchemaGen { type EitherAndGen[A, B] = (Schema.Either[A, B], Gen[Sized, scala.util.Either[A, B]]) - val anyEitherAndGen: Gen[Sized, EitherAndGen[_, _]] = + val anyEitherAndGen: Gen[Sized, EitherAndGen[Any, Any]] = for { (leftSchema, leftGen) <- anyPrimitiveAndGen (rightSchema, rightGen) <- anyPrimitiveAndGen @@ -115,13 +115,13 @@ object SchemaGen { type EitherAndValue[A, B] = (Schema.Either[A, B], scala.util.Either[A, B]) - val anyEitherAndValue: Gen[Sized, EitherAndValue[_, _]] = + val anyEitherAndValue: Gen[Sized, EitherAndValue[Any, Any]] = for { (schema, gen) <- anyEitherAndGen value <- gen } yield (schema, value) - def anyFallback(fullDecode: Boolean): Gen[Sized, Schema.Fallback[_, _]] = + def anyFallback(fullDecode: Boolean): Gen[Sized, Schema.Fallback[Any, Any]] = for { left <- anyPrimitive right <- anyPrimitive @@ -129,7 +129,7 @@ object SchemaGen { type FallbackAndGen[A, B] = (Schema.Fallback[A, B], Gen[Sized, Fallback[A, B]]) - def anyFallbackAndGen(fullDecode: Boolean): Gen[Sized, FallbackAndGen[_, _]] = + def anyFallbackAndGen(fullDecode: Boolean): Gen[Sized, FallbackAndGen[Any, Any]] = for { (leftSchema, leftGen) <- anyPrimitiveAndGen (rightSchema, rightGen) <- anyPrimitiveAndGen @@ -142,20 +142,20 @@ object SchemaGen { type FallbackAndValue[A, B] = (Schema.Fallback[A, B], Fallback[A, B]) - def anyFallbackAndValue(fullDecode: Boolean): Gen[Sized, FallbackAndValue[_, _]] = + def anyFallbackAndValue(fullDecode: Boolean): Gen[Sized, FallbackAndValue[Any, Any]] = for { (schema, gen) <- anyFallbackAndGen(fullDecode) value <- gen } yield (schema, value) - lazy val anyTuple: Gen[Sized, Schema.Tuple2[_, _]] = + lazy val anyTuple: Gen[Sized, Schema.Tuple2[Any, Any]] = anySchema.zipWith(anySchema) { (a, b) => Schema.Tuple2(a, b) } type TupleAndGen[A, B] = (Schema.Tuple2[A, B], Gen[Sized, (A, B)]) - val anyTupleAndGen: Gen[Sized, TupleAndGen[_, _]] = + val anyTupleAndGen: Gen[Sized, TupleAndGen[Any, Any]] = for { (schemaA, genA) <- anyPrimitiveAndGen (schemaB, genB) <- anyPrimitiveAndGen @@ -163,7 +163,7 @@ object SchemaGen { type TupleAndValue[A, B] = (Schema.Tuple2[A, B], (A, B)) - val anyTupleAndValue: Gen[Sized, TupleAndValue[_, _]] = + val anyTupleAndValue: Gen[Sized, TupleAndValue[Any, Any]] = for { (schema, gen) <- anyTupleAndGen (valueA, valueB) <- gen @@ -174,7 +174,7 @@ object SchemaGen { type SequenceAndGen[A] = (Schema[Chunk[A]], Gen[Sized, Chunk[A]]) - val anySequenceAndGen: Gen[Sized, SequenceAndGen[_]] = + val anySequenceAndGen: Gen[Sized, SequenceAndGen[Any]] = anyPrimitiveAndGen.map { case (schema, gen) => Schema.chunk(schema) -> Gen.chunkOf(gen) @@ -182,13 +182,13 @@ object SchemaGen { type SequenceAndValue[A] = (Schema[Chunk[A]], Chunk[A]) - val anySequenceAndValue: Gen[Sized, SequenceAndValue[_]] = + val anySequenceAndValue: Gen[Sized, SequenceAndValue[Any]] = for { (schema, gen) <- anySequenceAndGen value <- gen } yield schema -> value - def toCaseSet(cases: ListMap[String, Schema[_]]): CaseSet.Aux[Any] = + def toCaseSet(cases: ListMap[String, Schema[Any]]): CaseSet.Aux[Any] = cases.foldRight[CaseSet.Aux[Any]](CaseSet.Empty[Any]()) { case ((id, codec), acc) => val _case = Schema.Case[Any, Any]( @@ -202,13 +202,13 @@ object SchemaGen { CaseSet.Cons(_case, acc) } - lazy val anyMap: Gen[Sized, Schema.Map[_, _]] = + lazy val anyMap: Gen[Sized, Schema.Map[Any, Any]] = anySchema.zipWith(anySchema) { (a, b) => Schema.Map(a, b, Chunk.empty) } type MapAndGen[K, V] = (Schema.Map[K, V], Gen[Sized, Map[K, V]]) - val anyMapAndGen: Gen[Sized, MapAndGen[_, _]] = + val anyMapAndGen: Gen[Sized, MapAndGen[Any, Any]] = for { (schemaK, genK) <- anyPrimitiveAndGen (schemaV, genV) <- anyPrimitiveAndGen @@ -218,7 +218,7 @@ object SchemaGen { type MapAndValue[K, V] = (Schema.Map[K, V], Map[K, V]) - val anyMapAndValue: Gen[Sized, MapAndValue[_, _]] = + val anyMapAndValue: Gen[Sized, MapAndValue[Any, Any]] = for { (schema, gen) <- anyMapAndGen map <- gen @@ -226,7 +226,7 @@ object SchemaGen { type SetAndGen[A] = (Schema.Set[A], Gen[Sized, scala.collection.immutable.Set[A]]) - val anySetAndGen: Gen[Sized, SetAndGen[_]] = + val anySetAndGen: Gen[Sized, SetAndGen[Any]] = anyPrimitiveAndGen.map { case (schema, gen) => Schema.Set(schema, Chunk.empty) -> Gen.setOf(gen) @@ -234,7 +234,7 @@ object SchemaGen { type SetAndValue[A] = (Schema.Set[A], scala.collection.immutable.Set[A]) - val anySetAndValue: Gen[Sized, SetAndValue[_]] = + val anySetAndValue: Gen[Sized, SetAndValue[Any]] = for { (schema, gen) <- anySetAndGen value <- gen @@ -327,16 +327,16 @@ object SchemaGen { type SequenceTransform[A] = Schema.Transform[Chunk[A], List[A], String] - val anySequenceTransform: Gen[Sized, SequenceTransform[_]] = { + val anySequenceTransform: Gen[Sized, SequenceTransform[Any]] = { anySequence.map(schema => transformSequence(schema)) } type SequenceTransformAndGen[A] = (SequenceTransform[A], Gen[Sized, List[A]]) - val anySequenceTransformAndGen: Gen[Sized, SequenceTransformAndGen[_]] = + val anySequenceTransformAndGen: Gen[Sized, SequenceTransformAndGen[Any]] = anyPrimitiveAndGen.map { case (schema, gen) => - transformSequence(Schema.chunk(schema)) -> Gen.listOf(gen) + transformSequence[Any](Schema.chunk(schema)) -> Gen.listOf(gen) } // TODO: Add some random Left values. @@ -351,7 +351,7 @@ object SchemaGen { type SequenceTransformAndValue[A] = (SequenceTransform[A], List[A]) - val anySequenceTransformAndValue: Gen[Sized, SequenceTransformAndValue[_]] = + val anySequenceTransformAndValue: Gen[Sized, SequenceTransformAndValue[Any]] = for { (schema, gen) <- anySequenceTransformAndGen value <- gen @@ -359,14 +359,14 @@ object SchemaGen { type RecordTransform[A] = Schema.Transform[ListMap[String, _], A, String] - val anyRecordTransform: Gen[Sized, RecordTransform[_]] = { + val anyRecordTransform: Gen[Sized, RecordTransform[Any]] = { anyRecord.map(schema => transformRecord(schema)) } type RecordTransformAndGen[A] = (RecordTransform[A], Gen[Sized, A]) // TODO: How do we generate a value of a type that we know nothing about? - val anyRecordTransformAndGen: Gen[Sized, RecordTransformAndGen[_]] = + val anyRecordTransformAndGen: Gen[Sized, RecordTransformAndGen[Any]] = Gen.empty // anyRecordAndGen.map { // case (schema, gen) => transformRecord(schema) -> gen @@ -384,7 +384,7 @@ object SchemaGen { type RecordTransformAndValue[A] = (RecordTransform[A], A) - val anyRecordTransformAndValue: Gen[Sized, RecordTransformAndValue[_]] = + val anyRecordTransformAndValue: Gen[Sized, RecordTransformAndValue[Any]] = for { (schema, gen) <- anyRecordTransformAndGen value <- gen @@ -392,21 +392,21 @@ object SchemaGen { type EnumerationTransform[A] = Schema.Transform[Any, A, String] - val anyEnumerationTransform: Gen[Sized, EnumerationTransform[_]] = { + val anyEnumerationTransform: Gen[Sized, EnumerationTransform[Any]] = { anyEnumeration.map(schema => transformEnumeration(schema)) } type EnumerationTransformAndGen[A] = (EnumerationTransform[A], Gen[Sized, A]) // TODO: How do we generate a value of a type that we know nothing about? - val anyEnumerationTransformAndGen: Gen[Sized, EnumerationTransformAndGen[_]] = + val anyEnumerationTransformAndGen: Gen[Sized, EnumerationTransformAndGen[Any]] = Gen.empty // anyEnumerationAndGen.map { // case (schema, gen) => transformEnumeration(schema) -> gen // } // TODO: Dynamically generate a sealed trait and case/value classes. - def transformEnumeration[A](schema: Schema[Any]): EnumerationTransform[_] = + def transformEnumeration[A](schema: Schema[Any]): EnumerationTransform[A] = Schema.Transform[Any, A, String]( schema, _ => Left("Not implemented."), @@ -417,7 +417,7 @@ object SchemaGen { type EnumerationTransformAndValue[A] = (EnumerationTransform[A], A) - val anyEnumerationTransformAndValue: Gen[Sized, EnumerationTransformAndValue[_]] = + val anyEnumerationTransformAndValue: Gen[Sized, EnumerationTransformAndValue[Any]] = for { (schema, gen) <- anyEnumerationTransformAndGen value <- gen @@ -429,25 +429,25 @@ object SchemaGen { anyEnumerationTransform ) - type TransformAndValue[A] = (Schema.Transform[_, A, String], A) + type TransformAndValue[A] = (Schema.Transform[Any, A, String], A) - val anyTransformAndValue: Gen[Sized, TransformAndValue[_]] = - Gen.oneOf[Sized, TransformAndValue[_]]( - anySequenceTransformAndValue + val anyTransformAndValue: Gen[Sized, TransformAndValue[Any]] = + Gen.oneOf[Sized, TransformAndValue[Any]]( + anySequenceTransformAndValue.asInstanceOf[Gen[Sized, TransformAndValue[Any]]] // anyRecordTransformAndValue, // anyEnumerationTransformAndValue ) - type TransformAndGen[A] = (Schema.Transform[_, A, String], Gen[Sized, A]) + type TransformAndGen[A] = (Schema.Transform[Any, A, String], Gen[Sized, A]) - val anyTransformAndGen: Gen[Sized, TransformAndGen[_]] = - Gen.oneOf[Sized, TransformAndGen[_]]( - anySequenceTransformAndGen, - anyRecordTransformAndGen, + val anyTransformAndGen: Gen[Sized, TransformAndGen[Any]] = + Gen.oneOf[Sized, TransformAndGen[Any]]( + anySequenceTransformAndGen.asInstanceOf[Gen[Sized, TransformAndGen[Any]]], + anyRecordTransformAndGen.asInstanceOf[Gen[Sized, TransformAndGen[Any]]], anyEnumerationTransformAndGen ) - lazy val anySchema: Gen[Sized, Schema[_]] = + lazy val anySchema: Gen[Sized, Schema[Any]] = for { treeDepth <- Gen.bounded(0, 2)(Gen.const(_)) tree <- anyTree(treeDepth) @@ -462,7 +462,7 @@ object SchemaGen { type SchemaAndValue[A] = (Schema[A], A) - lazy val anySchemaAndValue: Gen[Sized, SchemaAndValue[_]] = + lazy val anySchemaAndValue: Gen[Sized, SchemaAndValue[Any]] = for { schema <- anySchema dynamic <- DynamicValueGen.anyDynamicValueOfSchema(schema) @@ -556,7 +556,7 @@ object SchemaGen { Gen.const(Schema[Arity24]) ) - val anyCaseClassAndGen: Gen[Sized, CaseClassAndGen[_]] = + val anyCaseClassAndGen: Gen[Sized, CaseClassAndGen[Any]] = anyCaseClassSchema.map { case s @ Schema.CaseClass1(_, _, _, _) => (s -> anyArity1).asInstanceOf[CaseClassAndGen[Any]] case s @ Schema.CaseClass2(_, _, _, _, _) => (s -> anyArity2).asInstanceOf[CaseClassAndGen[Any]] @@ -564,7 +564,7 @@ object SchemaGen { case s => (s -> anyArity24).asInstanceOf[CaseClassAndGen[Any]] } - val anyCaseClassAndValue: Gen[Sized, CaseClassAndValue[_]] = + val anyCaseClassAndValue: Gen[Sized, CaseClassAndValue[Any]] = for { (schema, gen) <- anyCaseClassAndGen value <- gen @@ -576,61 +576,65 @@ object SchemaGen { lazy val anyEnumSchema: Gen[Any, Schema.Enum[Arity]] = Gen.const(Arity.arityEnumSchema) - val anyEnumAndGen: Gen[Sized, EnumAndGen[_]] = - anyEnumSchema.map(_ -> anyArity) + val anyEnumAndGen: Gen[Sized, EnumAndGen[Any]] = + anyEnumSchema.map(_ -> anyArity).asInstanceOf[Gen[Sized, EnumAndGen[Any]]] - val anyEnumAndValue: Gen[Sized, EnumAndValue[_]] = + val anyEnumAndValue: Gen[Sized, EnumAndValue[Any]] = for { (schema, gen) <- anyEnumAndGen value <- gen } yield schema -> value - lazy val anyLeaf: Gen[Sized, Schema[_]] = - Gen.oneOf( - anyPrimitive, - anyPrimitive.map(Schema.list(_)), - anyPrimitive.map(_.optional), - anyPrimitive.zip(anyPrimitive).map { case (l, r) => Schema.either(l, r) }, - anyPrimitive.zip(anyPrimitive).map { case (l, r) => Schema.tuple2(l, r) }, - anyStructure(anyPrimitive) - .zip(Gen.string(Gen.alphaChar).map(TypeId.parse)) - .map(z => Schema.record(z._2, z._1)), - Gen.const(Schema[Json]), + lazy val anyLeaf: Gen[Sized, Schema[Any]] = + Gen + .oneOf( + anyPrimitive, + anyPrimitive.map(Schema.list(_)), + anyPrimitive.map(_.optional), + anyPrimitive.zip(anyPrimitive).map { case (l, r) => Schema.either(l, r) }, + anyPrimitive.zip(anyPrimitive).map { case (l, r) => Schema.tuple2(l, r) }, + anyStructure(anyPrimitive) + .zip(Gen.string(Gen.alphaChar).map(TypeId.parse)) + .map(z => Schema.record(z._2, z._1)), + Gen.const(Schema[Json]), // anyEnumeration(anyPrimitive).map(toCaseSet).map(Schema.enumeration[Any, CaseSet.Aux[Any]](_)), - anyCaseClassSchema, - anyEnumSchema - ) + anyCaseClassSchema, + anyEnumSchema + ) + .asInstanceOf[Gen[Sized, Schema[Any]]] - def anyTree(depth: Int): Gen[Sized, Schema[_]] = + def anyTree(depth: Int): Gen[Sized, Schema[Any]] = if (depth == 0) anyLeaf else - Gen.oneOf( - anyTree(depth - 1).map(Schema.list(_)), - // Nested optional cause some issues. Ignore them for now: See https://github.com/zio/zio-schema/issues/68 - anyTree(depth - 1).map { - case s @ Schema.Optional(_, _) => s - case s => Schema.option(s) - }, - anyTree(depth - 1).zip(anyTree(depth - 1)).map { case (l, r) => Schema.either(l, r) }, - anyTree(depth - 1).zip(anyTree(depth - 1)).map { case (l, r) => Schema.tuple2(l, r) }, - anyStructure(anyTree(depth - 1)) - .zip(Gen.string(Gen.alphaChar).map(TypeId.parse)) - .map(z => Schema.record(z._2, z._1)), - Gen.const(Schema[Json]), - anyDynamic + Gen + .oneOf( + anyTree(depth - 1).map(Schema.list(_)), + // Nested optional cause some issues. Ignore them for now: See https://github.com/zio/zio-schema/issues/68 + anyTree(depth - 1).map { + case s if s.isInstanceOf[Schema.Optional[_]] => s + case s => Schema.option(s).asInstanceOf[Schema[Any]] + }, + anyTree(depth - 1).zip(anyTree(depth - 1)).map { case (l, r) => Schema.either(l, r) }, + anyTree(depth - 1).zip(anyTree(depth - 1)).map { case (l, r) => Schema.tuple2(l, r) }, + anyStructure(anyTree(depth - 1)) + .zip(Gen.string(Gen.alphaChar).map(TypeId.parse)) + .map(z => Schema.record(z._2, z._1)), + Gen.const(Schema[Json]), + anyDynamic // anyEnumeration(anyTree(depth - 1)).map(toCaseSet).map(Schema.enumeration[Any, CaseSet.Aux[Any]](_)) - ) + ) + .asInstanceOf[Gen[Sized, Schema[Any]]] type SchemaAndDerivedValue[A, B] = (Schema[A], Schema[B], Chunk[scala.util.Either[A, B]]) - lazy val anyLeafAndValue: Gen[Sized, SchemaAndValue[_]] = + lazy val anyLeafAndValue: Gen[Sized, SchemaAndValue[Any]] = for { schema <- anyLeaf value <- DynamicValueGen.anyDynamicValueOfSchema(schema) } yield (schema -> schema.fromDynamic(value).toOption.get).asInstanceOf[SchemaAndValue[Any]] - lazy val anyTreeAndValue: Gen[Sized, SchemaAndValue[_]] = + lazy val anyTreeAndValue: Gen[Sized, SchemaAndValue[Any]] = for { schema <- anyTree(1) value <- DynamicValueGen.anyDynamicValueOfSchema(schema) @@ -674,16 +678,16 @@ object SchemaGen { } } - lazy val anyRecursiveType: Gen[Sized, Schema[_]] = + lazy val anyRecursiveType: Gen[Sized, Schema[Json]] = Gen.const(Schema[Json]) - lazy val anyRecursiveTypeAndValue: Gen[Sized, SchemaAndValue[_]] = + lazy val anyRecursiveTypeAndValue: Gen[Sized, SchemaAndValue[Json]] = for { schema <- Gen.const(Schema[Json]) value <- Json.gen } yield (schema, value) - lazy val anyDeepRecursiveTypeAndValue: Gen[Sized, SchemaAndValue[_]] = + lazy val anyDeepRecursiveTypeAndValue: Gen[Sized, SchemaAndValue[Json]] = for { schema <- Gen.const(Schema[Json]) value <- Json.genDeep @@ -693,7 +697,7 @@ object SchemaGen { case class SchemaTest[A](name: String, schema: StandardType[A], gen: Gen[Sized, A]) - def schemasAndGens: List[SchemaTest[_]] = + def schemasAndGens: List[SchemaTest[Any]] = List( SchemaTest("String", StandardType.StringType, Gen.string), SchemaTest("Bool", StandardType.BoolType, Gen.boolean), @@ -752,5 +756,5 @@ object SchemaGen { SchemaTest("ZoneId", StandardType.ZoneIdType, JavaTimeGen.anyZoneId), SchemaTest("ZoneOffset", StandardType.ZoneOffsetType, JavaTimeGen.anyZoneOffset), SchemaTest("UnitType", StandardType.UnitType, Gen.unit) - ) ++ platformSpecificSchemasAndGens + ).asInstanceOf[List[SchemaTest[Any]]] ++ platformSpecificSchemasAndGens } diff --git a/tests/shared/src/test/scala-2/zio/schema/SchemaMigrationSpec.scala b/tests/shared/src/test/scala/zio/schema/SchemaMigrationSpec.scala similarity index 100% rename from tests/shared/src/test/scala-2/zio/schema/SchemaMigrationSpec.scala rename to tests/shared/src/test/scala/zio/schema/SchemaMigrationSpec.scala diff --git a/tests/shared/src/test/scala/zio/schema/StandardTypeGen.scala b/tests/shared/src/test/scala/zio/schema/StandardTypeGen.scala new file mode 100644 index 000000000..09cc588d8 --- /dev/null +++ b/tests/shared/src/test/scala/zio/schema/StandardTypeGen.scala @@ -0,0 +1,89 @@ +package zio.schema + +import java.math.{ BigDecimal => JBigDecimal, BigInteger => JBigInt } + +import zio.schema.PlatformSpecificGen.{ platformSpecificStandardTypeAndGen, platformSpecificStandardTypes } +import zio.test.{ Gen, Sized } + +object StandardTypeGen { + + //IMPORTANT! - Updating the following list without updating the schema primitive case set in zio.schema.DynamicValue.schema will trigger a set of very obscure test failures + val anyStandardType: Gen[Any, StandardType[Any]] = Gen.fromIterable( + List( + StandardType.StringType, + StandardType.BoolType, + StandardType.ShortType, + StandardType.IntType, + StandardType.LongType, + StandardType.FloatType, + StandardType.DoubleType, + StandardType.BinaryType, + StandardType.BigDecimalType, + StandardType.BigIntegerType, + StandardType.CharType, + StandardType.UUIDType, + StandardType.DayOfWeekType, + StandardType.DurationType, + StandardType.InstantType, + StandardType.LocalDateType, + StandardType.LocalDateTimeType, + StandardType.LocalTimeType, + StandardType.MonthType, + StandardType.MonthDayType, + StandardType.OffsetDateTimeType, + StandardType.OffsetTimeType, + StandardType.PeriodType, + StandardType.YearType, + StandardType.YearMonthType, + StandardType.ZonedDateTimeType, + StandardType.ZoneIdType, + StandardType.ZoneOffsetType + ).asInstanceOf[List[StandardType[Any]]] + ) ++ platformSpecificStandardTypes + + val javaBigInt: Gen[Any, JBigInt] = + Gen.bigInt(JBigInt.valueOf(Long.MinValue), JBigInt.valueOf(Long.MaxValue)).map { sBigInt => + new JBigInt(sBigInt.toByteArray) + } + + val javaBigDecimal: Gen[Any, JBigDecimal] = + Gen.bigDecimal(JBigDecimal.valueOf(Long.MinValue), JBigDecimal.valueOf(Long.MaxValue)).map(_.bigDecimal) + + type StandardTypeAndGen[A] = (StandardType[A], Gen[Sized, A]) + + val anyStandardTypeAndGen: Gen[Any, StandardTypeAndGen[Any]] = { + anyStandardType.map { t => + t.asInstanceOf[StandardType[_]] match { + case typ: StandardType.StringType.type => typ -> Gen.string + case typ: StandardType.BoolType.type => typ -> Gen.boolean + case typ: StandardType.ShortType.type => typ -> Gen.short + case typ: StandardType.IntType.type => typ -> Gen.int + case typ: StandardType.LongType.type => typ -> Gen.long + case typ: StandardType.FloatType.type => typ -> Gen.float + case typ: StandardType.DoubleType.type => typ -> Gen.double + case typ: StandardType.BinaryType.type => typ -> Gen.chunkOf(Gen.byte) + case typ: StandardType.CharType.type => typ -> Gen.asciiChar + case typ: StandardType.UUIDType.type => typ -> Gen.uuid + case typ: StandardType.BigDecimalType.type => typ -> javaBigDecimal + case typ: StandardType.BigIntegerType.type => typ -> javaBigInt + case typ: StandardType.DayOfWeekType.type => typ -> JavaTimeGen.anyDayOfWeek + case typ: StandardType.DurationType.type => typ -> JavaTimeGen.anyDuration + case typ: StandardType.InstantType.type => typ -> JavaTimeGen.anyInstant + case typ: StandardType.LocalDateType.type => typ -> JavaTimeGen.anyLocalDate + case typ: StandardType.LocalDateTimeType.type => typ -> JavaTimeGen.anyLocalDateTime + case typ: StandardType.LocalTimeType.type => typ -> JavaTimeGen.anyLocalTime + case typ: StandardType.MonthType.type => typ -> JavaTimeGen.anyMonth + case typ: StandardType.MonthDayType.type => typ -> JavaTimeGen.anyMonthDay + case typ: StandardType.OffsetDateTimeType.type => typ -> JavaTimeGen.anyOffsetDateTime + case typ: StandardType.OffsetTimeType.type => typ -> JavaTimeGen.anyOffsetTime + case typ: StandardType.PeriodType.type => typ -> JavaTimeGen.anyPeriod + case typ: StandardType.YearType.type => typ -> JavaTimeGen.anyYear + case typ: StandardType.YearMonthType.type => typ -> JavaTimeGen.anyYearMonth + case typ: StandardType.ZonedDateTimeType.type => typ -> JavaTimeGen.anyZonedDateTime + case typ: StandardType.ZoneIdType.type => typ -> JavaTimeGen.anyZoneId + case typ: StandardType.ZoneOffsetType.type => typ -> JavaTimeGen.anyZoneOffset + case typ => platformSpecificStandardTypeAndGen(typ.asInstanceOf[StandardType[Any]]) + } + }.asInstanceOf[Gen[Any, StandardTypeAndGen[Any]]] + } +} diff --git a/tests/shared/src/test/scala-2/zio/schema/types.scala b/tests/shared/src/test/scala/zio/schema/types.scala similarity index 98% rename from tests/shared/src/test/scala-2/zio/schema/types.scala rename to tests/shared/src/test/scala/zio/schema/types.scala index 520410002..384976095 100644 --- a/tests/shared/src/test/scala-2/zio/schema/types.scala +++ b/tests/shared/src/test/scala/zio/schema/types.scala @@ -229,13 +229,13 @@ object types { Gen.const(Schema[Arities]) ) - def anySchemaAndValue: Gen[Sized, SchemaAndValue[_]] = + def anySchemaAndValue: Gen[Sized, SchemaAndValue[Any]] = for { schema <- anySchema dynamicValue <- DynamicValueGen.anyDynamicValueOfSchema(schema) } yield schema.asInstanceOf[Schema[Any]] -> dynamicValue.toTypedValue(schema).toOption.get - def anySchemaAndValuePair: Gen[Sized, SchemaAndValuePair[_]] = + def anySchemaAndValuePair: Gen[Sized, SchemaAndValuePair[Any]] = for { schema <- anySchema dynamicValue1 <- DynamicValueGen.anyDynamicValueOfSchema(schema) @@ -245,7 +245,7 @@ object types { .toOption .get) - def anySchemaAndValues(n: Int): Gen[Sized, SchemaAndValues[_]] = + def anySchemaAndValues(n: Int): Gen[Sized, SchemaAndValues[Any]] = for { schema <- anySchema dynamicValues <- Gen.listOfN(n)(DynamicValueGen.anyDynamicValueOfSchema(schema)) diff --git a/zio-schema-avro/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala b/zio-schema-avro/src/test/scala/zio/schema/codec/AvroCodecSpec.scala similarity index 100% rename from zio-schema-avro/src/test/scala-2/zio/schema/codec/AvroCodecSpec.scala rename to zio-schema-avro/src/test/scala/zio/schema/codec/AvroCodecSpec.scala diff --git a/zio-schema-avro/src/test/scala-2/zio/schema/codec/AvroSchemaCodecSpec.scala b/zio-schema-avro/src/test/scala/zio/schema/codec/AvroSchemaCodecSpec.scala similarity index 99% rename from zio-schema-avro/src/test/scala-2/zio/schema/codec/AvroSchemaCodecSpec.scala rename to zio-schema-avro/src/test/scala/zio/schema/codec/AvroSchemaCodecSpec.scala index 25895f44d..bc19b6b82 100644 --- a/zio-schema-avro/src/test/scala-2/zio/schema/codec/AvroSchemaCodecSpec.scala +++ b/zio-schema-avro/src/test/scala/zio/schema/codec/AvroSchemaCodecSpec.scala @@ -81,7 +81,7 @@ object AvroSchemaCodecSpec extends ZIOSpecDefault { val expected = """[{"type":"record","name":"A","fields":[]},{"type":"record","name":"B","fields":[]},{"type":"record","name":"MyC","fields":[]},{"type":"record","name":"D","fields":[{"name":"s","type":"string"}]}]""" assert(result)(isRight(equalTo(expected))) - }, + } @@ TestAspect.scala2Only, test("wraps nested unions") { val schemaA = DeriveSchema.gen[UnionWithNesting.Nested.A.type] val schemaB = DeriveSchema.gen[UnionWithNesting.Nested.B.type] @@ -1178,7 +1178,8 @@ object AvroSchemaCodecSpec extends ZIOSpecDefault { val s = """{"type":"enum","name":"TestEnum","symbols":["a","b","c"]}""" val schema = AvroSchemaCodec.decode(Chunk.fromArray(s.getBytes())) - val symbolKeysAssetion = Assertion.hasKeys(hasSameElements(Seq("a", "b", "c"))) + val symbolKeysAssetion: Assertion[Predef.Map[String, Any]] = + Assertion.hasKeys(hasSameElements(Seq("a", "b", "c"))) val enumStringTypeAssertion: Assertion[ListMap[String, (Schema[_], Chunk[Any])]] = Assertion.hasValues(forall(tuple2First(isStandardType(StandardType.StringType)))) assert(schema)(isRight(isEnum(enumStructure(symbolKeysAssetion && enumStringTypeAssertion)))) @@ -1858,8 +1859,8 @@ object AssertionHelper { def enumStructure(assertion: Assertion[ListMap[String, (Schema[_], Chunk[Any])]]): Assertion[Schema.Enum[_]] = Assertion.assertionRec("enumStructure")(assertion)( - enum => - Some(`enum`.cases.foldRight(ListMap.empty[String, (Schema[_], Chunk[Any])]) { (caseValue, acc) => + enum0 => + Some(enum0.cases.foldRight(ListMap.empty[String, (Schema[_], Chunk[Any])]) { (caseValue, acc) => (acc + (caseValue.id -> scala.Tuple2(caseValue.schema, caseValue.annotations))) }) ) diff --git a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala index b41711c30..47b4ac5a6 100644 --- a/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala +++ b/zio-schema-derivation/shared/src/main/scala-3/zio/schema/DeriveSchema.scala @@ -255,11 +255,17 @@ private case class DeriveSchema()(using val ctx: Quotes) { case None => tpe.asType } + val annotations = paramAnns.getOrElse(label, List.empty) + val nameExpr = annotations.collectFirst { + case ann if ann.isExprOf[fieldName] => + val fieldNameAnn = ann.asExprOf[fieldName] + '{${fieldNameAnn}.name} + }.getOrElse(Expr(label)) fieldType match { case '[t] => - '{ try ${m}.apply(${Expr(label)}).asInstanceOf[t] + '{ try ${m}.apply(${nameExpr}).asInstanceOf[t] catch { - case _: ClassCastException => throw new RuntimeException("Field " + ${Expr(label)} + " has invalid type") - case _: Throwable => throw new RuntimeException("Field " + ${Expr(label)} + " is missing") + case _: ClassCastException => throw new RuntimeException("Field " + ${nameExpr} + " has invalid type") + case _: Throwable => throw new RuntimeException("Field " + ${nameExpr} + " is missing") } }.asTerm } @@ -284,8 +290,14 @@ private case class DeriveSchema()(using val ctx: Quotes) { case None => tpe.asType } + val annotations = paramAnns.getOrElse(label, List.empty) + val nameExpr = annotations.collectFirst { + case ann if ann.isExprOf[fieldName] => + val fieldNameAnn = ann.asExprOf[fieldName] + '{${fieldNameAnn}.name} + }.getOrElse(Expr(label)) fieldType match { case '[t] => - '{(${Expr(label)}, ${Select.unique(b.asTerm, label).asExprOf[t]})} + '{(${nameExpr}, ${Select.unique(b.asTerm, label).asExprOf[t]})} } } val toMap = '{(b: T) => Right(ListMap.apply(${Varargs(tuples('b))} :_*)) } diff --git a/zio-schema-json/jvm/src/test/scala-2/zio/schema/codec/JsonCodecJVMSpec.scala b/zio-schema-json/jvm/src/test/scala/zio/schema/codec/JsonCodecJVMSpec.scala similarity index 100% rename from zio-schema-json/jvm/src/test/scala-2/zio/schema/codec/JsonCodecJVMSpec.scala rename to zio-schema-json/jvm/src/test/scala/zio/schema/codec/JsonCodecJVMSpec.scala diff --git a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala/zio/schema/codec/JsonCodecSpec.scala similarity index 100% rename from zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala rename to zio-schema-json/shared/src/test/scala/zio/schema/codec/JsonCodecSpec.scala diff --git a/zio-schema-msg-pack/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala b/zio-schema-msg-pack/src/test/scala/zio/schema/codec/MessagePackCodecSpec.scala similarity index 100% rename from zio-schema-msg-pack/src/test/scala-2/zio/schema/codec/MessagePackCodecSpec.scala rename to zio-schema-msg-pack/src/test/scala/zio/schema/codec/MessagePackCodecSpec.scala diff --git a/zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala b/zio-schema-protobuf/shared/src/test/scala/zio/schema/codec/ProtobufCodecSpec.scala similarity index 100% rename from zio-schema-protobuf/shared/src/test/scala-2/zio/schema/codec/ProtobufCodecSpec.scala rename to zio-schema-protobuf/shared/src/test/scala/zio/schema/codec/ProtobufCodecSpec.scala diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala b/zio-schema-thrift/src/test/scala/zio/schema/codec/ThriftCodecSpec.scala similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/ThriftCodecSpec.scala rename to zio-schema-thrift/src/test/scala/zio/schema/codec/ThriftCodecSpec.scala diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/BasicDouble.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicDouble.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/BasicDouble.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicDouble.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/BasicInt.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicInt.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/BasicInt.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicInt.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/BasicString.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicString.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/BasicString.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicString.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/BoolValue.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BoolValue.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/BoolValue.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BoolValue.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/Color.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Color.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/Color.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Color.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/Embedded.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Embedded.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/Embedded.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Embedded.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/EnumValue.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/EnumValue.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/EnumValue.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/EnumValue.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/Enumeration.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Enumeration.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/Enumeration.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Enumeration.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/HighArity.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/HighArity.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/HighArity.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/HighArity.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/IntList.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/IntList.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/IntList.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/IntList.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/IntValue.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/IntValue.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/IntValue.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/IntValue.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/MapValue.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/MapValue.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/MapValue.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/MapValue.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/OneOf.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/OneOf.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/OneOf.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/OneOf.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/Record.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Record.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/Record.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Record.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/SetValue.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/SetValue.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/SetValue.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/SetValue.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/StringList.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/StringList.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/StringList.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/StringList.java diff --git a/zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/StringValue.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/StringValue.java similarity index 100% rename from zio-schema-thrift/src/test/scala-2/zio/schema/codec/generated/StringValue.java rename to zio-schema-thrift/src/test/scala/zio/schema/codec/generated/StringValue.java From b1780627c45b185de1e877fb53454a32cc2b1f53 Mon Sep 17 00:00:00 2001 From: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:40:11 +0200 Subject: [PATCH 13/15] Update dependencies (#726) --- .github/workflows/ci.yml | 15 ++- build.sbt | 48 +++++---- project/BuildHelper.scala | 44 ++++---- project/plugins.sbt | 4 +- .../schema/codec/generated/BasicDouble.java | 8 +- .../zio/schema/codec/generated/BasicInt.java | 8 +- .../schema/codec/generated/BasicString.java | 8 +- .../zio/schema/codec/generated/BoolValue.java | 8 +- .../zio/schema/codec/generated/Color.java | 4 +- .../zio/schema/codec/generated/Embedded.java | 8 +- .../zio/schema/codec/generated/EnumValue.java | 16 +-- .../schema/codec/generated/Enumeration.java | 8 +- .../zio/schema/codec/generated/HighArity.java | 100 +++++++++--------- .../zio/schema/codec/generated/IntList.java | 10 +- .../zio/schema/codec/generated/IntValue.java | 8 +- .../zio/schema/codec/generated/MapValue.java | 14 +-- .../zio/schema/codec/generated/OneOf.java | 8 +- .../zio/schema/codec/generated/Record.java | 12 +-- .../zio/schema/codec/generated/SetValue.java | 10 +- .../schema/codec/generated/StringList.java | 10 +- .../schema/codec/generated/StringValue.java | 8 +- 21 files changed, 184 insertions(+), 175 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e5c785e55..d3d76f4aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,7 @@ name: CI env: - JDK_JAVA_OPTIONS: -XX:+PrintCommandLineFlags -Xmx6G -Xss4M -XX:+UseG1GC # JDK_JAVA_OPTIONS is _the_ env. variable to use for modern Java - JVM_OPTS: -XX:+PrintCommandLineFlags -Xmx6G -Xss4M -XX:+UseG1GC # for Java 8 only (sadly, it is not modern enough for JDK_JAVA_OPTIONS) + JDK_JAVA_OPTIONS: -XX:+PrintCommandLineFlags -Xmx6G -Xss4M -XX:+UseG1GC NODE_OPTIONS: --max_old_space_size=6144 on: @@ -38,16 +37,16 @@ jobs: strategy: fail-fast: false matrix: - java: ['adopt@1.11', 'openjdk@1.17'] + java: ['temurin:17', 'temurin:21'] scala: ['2.12.18', '2.13.12', '3.3.1'] platform: ['JVM', 'Native', 'JS'] steps: - uses: actions/checkout@v3.0.0 with: fetch-depth: 0 - - uses: olafurpg/setup-scala@v13 + - uses: coursier/setup-action@v1 with: - java-version: ${{ matrix.java }} + jvm: ${{ matrix.java }} - name: Cache scala dependencies uses: coursier/cache-action@v6 - name: Install libuv @@ -56,6 +55,12 @@ jobs: - name: Run tests run: sbt ++${{ matrix.scala }}! test${{ matrix.platform }} + ci: + runs-on: ubuntu-20.04 + needs: [build,lint] + steps: + - run: echo "All checks passed" + publish: runs-on: ubuntu-20.04 timeout-minutes: 45 diff --git a/build.sbt b/build.sbt index 8d7831f37..7c77d3458 100644 --- a/build.sbt +++ b/build.sbt @@ -2,6 +2,8 @@ import sbtcrossproject.CrossPlugin.autoImport._ import BuildHelper.{ crossProjectSettings, _ } import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ +Global / onChangedBuildSource := ReloadOnSourceChanges + inThisBuild( List( name := "zio-schema", @@ -127,13 +129,13 @@ lazy val zioSchemaMacros = crossProject(JSPlatform, JVMPlatform, NativePlatform) .nativeSettings(Test / fork := false) .nativeSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion ) ) .jsSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0", - "io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion, + "io.github.cquiroz" %%% "scala-java-time-tzdb" % scalaJavaTimeVersion ) ) .settings(testDeps) @@ -157,13 +159,13 @@ lazy val zioSchema = crossProject(JSPlatform, JVMPlatform, NativePlatform) .nativeSettings(Test / fork := false) .nativeSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion ) ) .jsSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0", - "io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion, + "io.github.cquiroz" %%% "scala-java-time-tzdb" % scalaJavaTimeVersion ) ) .settings(testDeps) @@ -212,13 +214,13 @@ lazy val zioSchemaDerivation = crossProject(JSPlatform, JVMPlatform, NativePlatf .nativeSettings(Test / fork := false) .nativeSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion ) ) .jsSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0", - "io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion, + "io.github.cquiroz" %%% "scala-java-time-tzdb" % scalaJavaTimeVersion ) ) .settings(testDeps) @@ -241,13 +243,13 @@ lazy val zioSchemaJson = crossProject(JSPlatform, JVMPlatform, NativePlatform) .nativeSettings(Test / fork := false) .nativeSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion ) ) .jsSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0", - "io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion, + "io.github.cquiroz" %%% "scala-java-time-tzdb" % scalaJavaTimeVersion ) ) .jsSettings(scalaJSLinkerConfig ~= { _.withOptimizer(false) }) @@ -268,13 +270,13 @@ lazy val zioSchemaProtobuf = crossProject(JSPlatform, JVMPlatform, NativePlatfor .nativeSettings(Test / fork := false) .nativeSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion ) ) .jsSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0", - "io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion, + "io.github.cquiroz" %%% "scala-java-time-tzdb" % scalaJavaTimeVersion ) ) .settings(testDeps) @@ -292,8 +294,8 @@ lazy val zioSchemaThrift = project .settings(buildInfoSettings("zio.schema.thrift")) .settings( libraryDependencies ++= Seq( - "org.apache.thrift" % "libthrift" % thriftVersion, - "javax.annotation" % "javax.annotation-api" % javaxAnnotationApiVersion + "org.apache.thrift" % "libthrift" % thriftVersion, + "jakarta.annotation" % "jakarta.annotation-api" % javaxAnnotationApiVersion ) ) .settings(testDeps) @@ -359,13 +361,13 @@ lazy val zioSchemaOptics = crossProject(JSPlatform, JVMPlatform, NativePlatform) .nativeSettings(Test / fork := false) .nativeSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion ) ) .jsSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0", - "io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion, + "io.github.cquiroz" %%% "scala-java-time-tzdb" % scalaJavaTimeVersion ) ) .settings(testDeps) @@ -389,13 +391,13 @@ lazy val zioSchemaExamples = crossProject(JSPlatform, JVMPlatform, NativePlatfor .nativeSettings(Test / fork := false) .nativeSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion ) ) .jsSettings( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.5.0", - "io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.5.0" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion, + "io.github.cquiroz" %%% "scala-java-time-tzdb" % scalaJavaTimeVersion ) ) .settings(testDeps) diff --git a/project/BuildHelper.scala b/project/BuildHelper.scala index 6d7780c8b..eda8731f6 100644 --- a/project/BuildHelper.scala +++ b/project/BuildHelper.scala @@ -1,12 +1,13 @@ -import sbt._ -import Keys._ - -import sbtcrossproject.CrossPlugin.autoImport._ -import sbtbuildinfo._ -import BuildInfoKeys._ -import scalafix.sbt.ScalafixPlugin.autoImport._ +import sbt.* +import Keys.* +import sbtcrossproject.CrossPlugin.autoImport.* +import sbtbuildinfo.* +import BuildInfoKeys.* +import scalafix.sbt.ScalafixPlugin.autoImport.* import scalanativecrossproject.NativePlatform +import scala.scalanative.sbtplugin.ScalaNativePlugin.autoImport.nativeConfig + object BuildHelper { private val versions: Map[String, String] = { @@ -26,20 +27,20 @@ object BuildHelper { val Scala213: String = versions("2.13") val Scala3: String = versions("3.3") - val zioVersion = "2.0.19" - val zioJsonVersion = "0.6.2" - val zioPreludeVersion = "1.0.0-RC21" - val zioOpticsVersion = "0.2.1" - val zioBsonVersion = "1.0.5" - val silencerVersion = "1.7.14" + val zioVersion = "2.1.7" + val zioJsonVersion = "0.7.2" + val zioPreludeVersion = "1.0.0-RC28" + val zioOpticsVersion = "0.2.2" + val zioBsonVersion = "1.0.6" val avroVersion = "1.11.3" - val bsonVersion = "4.11.1" - val zioConstraintlessVersion = "0.3.2" - val scalaCollectionCompatVersion = "2.10.0" - val msgpackVersion = "0.9.6" - val jacksonScalaVersion = "2.15.2" - val thriftVersion = "0.16.0" - val javaxAnnotationApiVersion = "1.3.2" + val bsonVersion = "4.11.3" + val zioConstraintlessVersion = "0.3.3" + val scalaCollectionCompatVersion = "2.12.0" + val msgpackVersion = "0.9.8" + val jacksonScalaVersion = "2.17.2" + val thriftVersion = "0.20.0" + val javaxAnnotationApiVersion = "1.3.5" + val scalaJavaTimeVersion = "2.6.0" def macroDefinitionSettings = Seq( scalacOptions += "-language:experimental.macros", @@ -186,7 +187,8 @@ object BuildHelper { "test", baseDirectory.value ) - } + }, + nativeConfig ~= { _.withMultithreading(false) } ) def buildInfoSettings(packageName: String) = Seq( diff --git a/project/plugins.sbt b/project/plugins.sbt index a16d7d128..c55a5cc1f 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,12 +1,12 @@ addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.5") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.11.1") addSbtPlugin("com.github.cb372" % "sbt-explicit-dependencies" % "0.3.1") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.15.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0") addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.3.2") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0") addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.12") addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.3.2") -addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.16") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.3") addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.6") addSbtPlugin("dev.zio" % "zio-sbt-website" % "0.4.0-alpha.22") diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicDouble.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicDouble.java index fcf810231..21d88c17a 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicDouble.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicDouble.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class BasicDouble implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("BasicDouble"); @@ -84,7 +84,7 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(BasicDouble.class, metaDataMap); @@ -295,7 +295,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, BasicDouble struct) while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -303,7 +303,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, BasicDouble struct) if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) { struct.value = iprot.readDouble(); struct.setValueIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicInt.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicInt.java index 6864e91e7..bd403c412 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicInt.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicInt.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class BasicInt implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("BasicInt"); @@ -84,7 +84,7 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(BasicInt.class, metaDataMap); @@ -295,7 +295,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, BasicInt struct) th while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -303,7 +303,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, BasicInt struct) th if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.value = iprot.readI32(); struct.setValueIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicString.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicString.java index 3727f5dae..86d3e57e4 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicString.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BasicString.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class BasicString implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("BasicString"); @@ -82,7 +82,7 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(BasicString.class, metaDataMap); @@ -298,7 +298,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, BasicString struct) while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -306,7 +306,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, BasicString struct) if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { struct.value = iprot.readString(); struct.setValueIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BoolValue.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BoolValue.java index ab08cfaf7..5e486be70 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BoolValue.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/BoolValue.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class BoolValue implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("BoolValue"); @@ -84,7 +84,7 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(BoolValue.class, metaDataMap); @@ -295,7 +295,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, BoolValue struct) t while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -303,7 +303,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, BoolValue struct) t if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) { struct.value = iprot.readBool(); struct.setValueIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Color.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Color.java index 7ec4b4d92..b0ed65f20 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Color.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Color.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public enum Color implements org.apache.thrift.TEnum { RED(0), GREEN(1), @@ -31,7 +31,7 @@ public int getValue() { * @return null if the value is not found. */ @org.apache.thrift.annotation.Nullable - public static Color findByValue(int value) { + public static Color findByValue(int value) { switch (value) { case 0: return RED; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Embedded.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Embedded.java index 6dabbc682..939881975 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Embedded.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Embedded.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class Embedded implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Embedded"); @@ -82,7 +82,7 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.EMBEDDED, new org.apache.thrift.meta_data.FieldMetaData("embedded", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.EMBEDDED, new org.apache.thrift.meta_data.FieldMetaData("embedded", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, BasicInt.class))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Embedded.class, metaDataMap); @@ -301,7 +301,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, Embedded struct) th while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -310,7 +310,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, Embedded struct) th struct.embedded = new BasicInt(); struct.embedded.read(iprot); struct.setEmbeddedIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/EnumValue.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/EnumValue.java index 6c0d5dec9..e6eb67fb2 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/EnumValue.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/EnumValue.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class EnumValue implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("EnumValue"); @@ -17,7 +17,7 @@ public class EnumValue implements org.apache.thrift.TBase metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, Color.class))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(EnumValue.class, metaDataMap); @@ -125,7 +125,7 @@ public void clear() { } /** - * + * * @see Color */ @org.apache.thrift.annotation.Nullable @@ -134,7 +134,7 @@ public Color getValue() { } /** - * + * * @see Color */ public EnumValue setValue(@org.apache.thrift.annotation.Nullable Color value) { @@ -314,7 +314,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, EnumValue struct) t while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -322,7 +322,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, EnumValue struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.value = zio.schema.codec.generated.Color.findByValue(iprot.readI32()); struct.setValueIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Enumeration.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Enumeration.java index 96f4031a5..8427c7301 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Enumeration.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Enumeration.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class Enumeration implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Enumeration"); @@ -82,7 +82,7 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, OneOf.class))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Enumeration.class, metaDataMap); @@ -298,7 +298,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, Enumeration struct) while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -307,7 +307,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, Enumeration struct) struct.value = new OneOf(); struct.value.read(iprot); struct.setValueIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/HighArity.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/HighArity.java index 162de0773..c155a03a0 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/HighArity.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/HighArity.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class HighArity implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("HighArity"); @@ -222,53 +222,53 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.F1, new org.apache.thrift.meta_data.FieldMetaData("f1", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F1, new org.apache.thrift.meta_data.FieldMetaData("f1", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F2, new org.apache.thrift.meta_data.FieldMetaData("f2", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F2, new org.apache.thrift.meta_data.FieldMetaData("f2", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F3, new org.apache.thrift.meta_data.FieldMetaData("f3", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F3, new org.apache.thrift.meta_data.FieldMetaData("f3", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F4, new org.apache.thrift.meta_data.FieldMetaData("f4", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F4, new org.apache.thrift.meta_data.FieldMetaData("f4", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F5, new org.apache.thrift.meta_data.FieldMetaData("f5", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F5, new org.apache.thrift.meta_data.FieldMetaData("f5", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F6, new org.apache.thrift.meta_data.FieldMetaData("f6", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F6, new org.apache.thrift.meta_data.FieldMetaData("f6", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F7, new org.apache.thrift.meta_data.FieldMetaData("f7", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F7, new org.apache.thrift.meta_data.FieldMetaData("f7", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F8, new org.apache.thrift.meta_data.FieldMetaData("f8", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F8, new org.apache.thrift.meta_data.FieldMetaData("f8", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F9, new org.apache.thrift.meta_data.FieldMetaData("f9", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F9, new org.apache.thrift.meta_data.FieldMetaData("f9", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F10, new org.apache.thrift.meta_data.FieldMetaData("f10", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F10, new org.apache.thrift.meta_data.FieldMetaData("f10", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F11, new org.apache.thrift.meta_data.FieldMetaData("f11", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F11, new org.apache.thrift.meta_data.FieldMetaData("f11", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F12, new org.apache.thrift.meta_data.FieldMetaData("f12", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F12, new org.apache.thrift.meta_data.FieldMetaData("f12", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F13, new org.apache.thrift.meta_data.FieldMetaData("f13", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F13, new org.apache.thrift.meta_data.FieldMetaData("f13", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F14, new org.apache.thrift.meta_data.FieldMetaData("f14", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F14, new org.apache.thrift.meta_data.FieldMetaData("f14", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F15, new org.apache.thrift.meta_data.FieldMetaData("f15", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F15, new org.apache.thrift.meta_data.FieldMetaData("f15", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F16, new org.apache.thrift.meta_data.FieldMetaData("f16", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F16, new org.apache.thrift.meta_data.FieldMetaData("f16", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F17, new org.apache.thrift.meta_data.FieldMetaData("f17", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F17, new org.apache.thrift.meta_data.FieldMetaData("f17", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F18, new org.apache.thrift.meta_data.FieldMetaData("f18", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F18, new org.apache.thrift.meta_data.FieldMetaData("f18", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F19, new org.apache.thrift.meta_data.FieldMetaData("f19", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F19, new org.apache.thrift.meta_data.FieldMetaData("f19", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F20, new org.apache.thrift.meta_data.FieldMetaData("f20", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F20, new org.apache.thrift.meta_data.FieldMetaData("f20", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F21, new org.apache.thrift.meta_data.FieldMetaData("f21", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F21, new org.apache.thrift.meta_data.FieldMetaData("f21", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F22, new org.apache.thrift.meta_data.FieldMetaData("f22", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F22, new org.apache.thrift.meta_data.FieldMetaData("f22", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F23, new org.apache.thrift.meta_data.FieldMetaData("f23", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F23, new org.apache.thrift.meta_data.FieldMetaData("f23", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.F24, new org.apache.thrift.meta_data.FieldMetaData("f24", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.F24, new org.apache.thrift.meta_data.FieldMetaData("f24", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(HighArity.class, metaDataMap); @@ -2020,7 +2020,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -2028,7 +2028,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f1 = iprot.readI32(); struct.setF1IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2036,7 +2036,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f2 = iprot.readI32(); struct.setF2IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2044,7 +2044,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f3 = iprot.readI32(); struct.setF3IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2052,7 +2052,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f4 = iprot.readI32(); struct.setF4IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2060,7 +2060,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f5 = iprot.readI32(); struct.setF5IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2068,7 +2068,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f6 = iprot.readI32(); struct.setF6IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2076,7 +2076,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f7 = iprot.readI32(); struct.setF7IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2084,7 +2084,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f8 = iprot.readI32(); struct.setF8IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2092,7 +2092,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f9 = iprot.readI32(); struct.setF9IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2100,7 +2100,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f10 = iprot.readI32(); struct.setF10IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2108,7 +2108,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f11 = iprot.readI32(); struct.setF11IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2116,7 +2116,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f12 = iprot.readI32(); struct.setF12IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2124,7 +2124,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f13 = iprot.readI32(); struct.setF13IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2132,7 +2132,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f14 = iprot.readI32(); struct.setF14IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2140,7 +2140,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f15 = iprot.readI32(); struct.setF15IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2148,7 +2148,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f16 = iprot.readI32(); struct.setF16IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2156,7 +2156,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f17 = iprot.readI32(); struct.setF17IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2164,7 +2164,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f18 = iprot.readI32(); struct.setF18IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2172,7 +2172,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f19 = iprot.readI32(); struct.setF19IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2180,7 +2180,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f20 = iprot.readI32(); struct.setF20IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2188,7 +2188,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f21 = iprot.readI32(); struct.setF21IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2196,7 +2196,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f22 = iprot.readI32(); struct.setF22IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2204,7 +2204,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f23 = iprot.readI32(); struct.setF23IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -2212,7 +2212,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, HighArity struct) t if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.f24 = iprot.readI32(); struct.setF24IsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/IntList.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/IntList.java index 88db2cfba..5d4167ad6 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/IntList.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/IntList.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class IntList implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("IntList"); @@ -82,8 +82,8 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.ITEMS, new org.apache.thrift.meta_data.FieldMetaData("items", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + tmpMap.put(_Fields.ITEMS, new org.apache.thrift.meta_data.FieldMetaData("items", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(IntList.class, metaDataMap); @@ -316,7 +316,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, IntList struct) thr while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -334,7 +334,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, IntList struct) thr iprot.readListEnd(); } struct.setItemsIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/IntValue.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/IntValue.java index 8f7e8b123..5eaee0b78 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/IntValue.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/IntValue.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class IntValue implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("IntValue"); @@ -84,7 +84,7 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(IntValue.class, metaDataMap); @@ -295,7 +295,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, IntValue struct) th while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -303,7 +303,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, IntValue struct) th if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.value = iprot.readI32(); struct.setValueIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/MapValue.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/MapValue.java index 632126e0a..4a93c197c 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/MapValue.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/MapValue.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class MapValue implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("MapValue"); @@ -82,9 +82,9 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Record.class)))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(MapValue.class, metaDataMap); @@ -323,7 +323,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, MapValue struct) th while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -344,7 +344,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, MapValue struct) th iprot.readMapEnd(); } struct.setValueIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -416,7 +416,7 @@ public void read(org.apache.thrift.protocol.TProtocol prot, MapValue struct) thr java.util.BitSet incoming = iprot.readBitSet(1); if (incoming.get(0)) { { - org.apache.thrift.protocol.TMap _map30 = iprot.readMapBegin(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT); + org.apache.thrift.protocol.TMap _map30 = iprot.readMapBegin(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT); struct.value = new java.util.HashMap(2*_map30.size); @org.apache.thrift.annotation.Nullable java.lang.String _key31; @org.apache.thrift.annotation.Nullable Record _val32; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/OneOf.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/OneOf.java index cea98e237..63d1c0815 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/OneOf.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/OneOf.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class OneOf extends org.apache.thrift.TUnion { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("OneOf"); private static final org.apache.thrift.protocol.TField STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue", org.apache.thrift.protocol.TType.STRUCT, (short)1); @@ -83,11 +83,11 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("stringValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, + tmpMap.put(_Fields.STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("stringValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, StringValue.class))); - tmpMap.put(_Fields.INT_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, + tmpMap.put(_Fields.INT_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IntValue.class))); - tmpMap.put(_Fields.BOOL_VALUE, new org.apache.thrift.meta_data.FieldMetaData("boolValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, + tmpMap.put(_Fields.BOOL_VALUE, new org.apache.thrift.meta_data.FieldMetaData("boolValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, BoolValue.class))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(OneOf.class, metaDataMap); diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Record.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Record.java index 6ece4a164..13f224c81 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Record.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/Record.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class Record implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Record"); @@ -89,9 +89,9 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Record.class, metaDataMap); @@ -377,7 +377,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, Record struct) thro while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -385,7 +385,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, Record struct) thro if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { struct.name = iprot.readString(); struct.setNameIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; @@ -393,7 +393,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, Record struct) thro if (schemeField.type == org.apache.thrift.protocol.TType.I32) { struct.value = iprot.readI32(); struct.setValueIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/SetValue.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/SetValue.java index 7bae51e0f..bae30c4fb 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/SetValue.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/SetValue.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class SetValue implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SetValue"); @@ -82,8 +82,8 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Record.class)))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SetValue.class, metaDataMap); @@ -319,7 +319,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, SetValue struct) th while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -338,7 +338,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, SetValue struct) th iprot.readSetEnd(); } struct.setValueIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/StringList.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/StringList.java index 964f5d919..93f89e55f 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/StringList.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/StringList.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class StringList implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("StringList"); @@ -82,8 +82,8 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.ITEMS, new org.apache.thrift.meta_data.FieldMetaData("items", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + tmpMap.put(_Fields.ITEMS, new org.apache.thrift.meta_data.FieldMetaData("items", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(StringList.class, metaDataMap); @@ -316,7 +316,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, StringList struct) while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -334,7 +334,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, StringList struct) iprot.readListEnd(); } struct.setItemsIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; diff --git a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/StringValue.java b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/StringValue.java index 2170de5c1..7010a61b5 100644 --- a/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/StringValue.java +++ b/zio-schema-thrift/src/test/scala/zio/schema/codec/generated/StringValue.java @@ -7,7 +7,7 @@ package zio.schema.codec.generated; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") +@jakarta.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.16.0)") public class StringValue implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("StringValue"); @@ -82,7 +82,7 @@ public java.lang.String getFieldName() { public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(StringValue.class, metaDataMap); @@ -298,7 +298,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, StringValue struct) while (true) { schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { break; } switch (schemeField.id) { @@ -306,7 +306,7 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, StringValue struct) if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { struct.value = iprot.readString(); struct.setValueIsSet(true); - } else { + } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; From ce3a315ced8904310f329e08b07a4dfc87eb4250 Mon Sep 17 00:00:00 2001 From: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:31:55 +0200 Subject: [PATCH 14/15] Non empty collection schemas (#717) (#723) --- build.sbt | 3 +- .../scala/zio/schema/DynamicValueGen.scala | 2 + .../scala/zio/schema/codec/AvroCodec.scala | 30 +++++- .../zio/schema/codec/AvroSchemaCodec.scala | 28 ++++-- .../schema/codec/AvroSchemaCodecSpec.scala | 5 +- .../zio/schema/codec/BsonSchemaCodec.scala | 68 +++++++------- .../schema/codec/BsonSchemaCodecSpec.scala | 4 +- .../main/scala/zio/schema/CachedDeriver.scala | 12 ++- .../scala/zio/schema/codec/JsonCodec.scala | 35 ++++--- .../zio/schema/optics/ZioOpticsBuilder.scala | 42 ++++++++- .../zio/schema/codec/ProtobufCodec.scala | 26 +++-- .../scala/zio/schema/codec/ThriftCodec.scala | 27 +++--- .../src/main/scala/zio/schema/Differ.scala | 10 +- .../MutableSchemaBasedValueBuilder.scala | 81 +++++++++++++++- .../MutableSchemaBasedValueProcessor.scala | 55 +++++++++++ .../src/main/scala/zio/schema/Schema.scala | 94 ++++++++++++++++++- .../schema/meta/ExtensibleMetaSchema.scala | 17 ++++ 17 files changed, 433 insertions(+), 106 deletions(-) diff --git a/build.sbt b/build.sbt index 7c77d3458..478857687 100644 --- a/build.sbt +++ b/build.sbt @@ -39,8 +39,7 @@ inThisBuild( ThisBuild / publishTo := sonatypePublishToBundle.value scalacOptions ++= Seq("-scalajs") -addCommandAlias("prepare", "fix; fmt") -addCommandAlias("fmt", "all scalafmtSbt scalafmtAll") +addCommandAlias("fmt", "all scalafmtSbt scalafmtAll;fix") addCommandAlias("fmtCheck", "all scalafmtSbtCheck scalafmtCheckAll") addCommandAlias("fix", "scalafixAll") addCommandAlias("fixCheck", "scalafixAll --check") diff --git a/tests/shared/src/test/scala/zio/schema/DynamicValueGen.scala b/tests/shared/src/test/scala/zio/schema/DynamicValueGen.scala index d17941483..0a311fae7 100644 --- a/tests/shared/src/test/scala/zio/schema/DynamicValueGen.scala +++ b/tests/shared/src/test/scala/zio/schema/DynamicValueGen.scala @@ -74,7 +74,9 @@ object DynamicValueGen { case Schema.Enum22(_, case1, case2, case3, case4, case5, case6, case7, case8, case9, case10, case11, case12, case13, case14, case15, case16, case17, case18, case19, case20, case21, case22, _) => anyDynamicValueOfEnum(Chunk(case1, case2, case3, case4, case5, case6, case7, case8, case9, case10, case11, case12, case13, case14, case15, case16, case17, case18, case19, case20, case21, case22)) case Schema.EnumN(_, cases, _) => anyDynamicValueOfEnum(Chunk.fromIterable(cases.toSeq)) case Schema.Sequence(schema, _, _, _, _) => Gen.chunkOfBounded(0, 2)(anyDynamicValueOfSchema(schema)).map(DynamicValue.Sequence(_)) + case Schema.NonEmptySequence(schema, _, _, _, _) => Gen.chunkOfBounded(1, 2)(anyDynamicValueOfSchema(schema)).map(DynamicValue.Sequence(_)) case Schema.Map(ks, vs, _) => Gen.chunkOfBounded(0, 2)(anyDynamicValueOfSchema(ks).zip(anyDynamicValueOfSchema(vs))).map(DynamicValue.Dictionary(_)) + case Schema.NonEmptyMap(ks, vs, _) => Gen.chunkOfBounded(1, 2)(anyDynamicValueOfSchema(ks).zip(anyDynamicValueOfSchema(vs))).map(DynamicValue.Dictionary(_)) case Schema.Set(schema, _) => Gen.setOfBounded(0, 2)(anyDynamicValueOfSchema(schema)).map(DynamicValue.SetValue(_)) case Schema.Optional(schema, _) => Gen.oneOf(anyDynamicSomeValueOfSchema(schema), Gen.const(DynamicValue.NoneValue)) case Schema.Tuple2(left, right, _) => anyDynamicTupleValue(left, right) diff --git a/zio-schema-avro/src/main/scala/zio/schema/codec/AvroCodec.scala b/zio-schema-avro/src/main/scala/zio/schema/codec/AvroCodec.scala index e1bca4ff5..a1b790e88 100644 --- a/zio-schema-avro/src/main/scala/zio/schema/codec/AvroCodec.scala +++ b/zio-schema-avro/src/main/scala/zio/schema/codec/AvroCodec.scala @@ -19,6 +19,7 @@ import org.apache.avro.io.{ DecoderFactory, EncoderFactory } import org.apache.avro.util.Utf8 import org.apache.avro.{ Conversions, LogicalTypes, Schema => SchemaAvro } +import zio.prelude.NonEmptyMap import zio.schema.{ Fallback, FieldSet, Schema, StandardType, TypeId } import zio.stream.ZPipeline import zio.{ Chunk, Unsafe, ZIO } @@ -201,9 +202,20 @@ object AvroCodec { case record: Schema.Record[_] => decodeRecord(raw, record).map(_.asInstanceOf[A]) case Schema.Sequence(element, f, _, _, _) => decodeSequence(raw, element.asInstanceOf[Schema[Any]]).map(f.asInstanceOf[Chunk[Any] => A]) + case nes @ Schema.NonEmptySequence(element, _, _, _, _) => + decodeSequence(raw, element.asInstanceOf[Schema[Any]]).map(nes.fromChunk.asInstanceOf[Chunk[Any] => A]) case Schema.Set(element, _) => decodeSequence(raw, element.asInstanceOf[Schema[Any]]).map(_.toSet.asInstanceOf[A]) case mapSchema: Schema.Map[_, _] => decodeMap(raw, mapSchema.asInstanceOf[Schema.Map[Any, Any]]).map(_.asInstanceOf[A]) + case mapSchema: Schema.NonEmptyMap[_, _] => + decodeMap( + raw, + Schema.Map( + mapSchema.keySchema.asInstanceOf[Schema[Any]], + mapSchema.valueSchema.asInstanceOf[Schema[Any]], + mapSchema.annotations + ) + ).map(mapSchema.asInstanceOf[Schema.NonEmptyMap[Any, Any]].fromMap(_).asInstanceOf[A]) case Schema.Transform(schema, f, _, _, _) => decodeValue(raw, schema).flatMap( a => f(a).left.map(msg => DecodeError.MalformedFieldWithPath(Chunk.single("Error"), msg)) @@ -662,12 +674,22 @@ object AvroCodec { c21, c22 ) - case Schema.GenericRecord(typeId, structure, _) => encodeGenericRecord(a, typeId, structure) - case Schema.Primitive(standardType, _) => encodePrimitive(a, standardType) - case Schema.Sequence(element, _, g, _, _) => encodeSequence(element, g(a)) - case Schema.Set(element, _) => encodeSet(element, a) + case Schema.GenericRecord(typeId, structure, _) => encodeGenericRecord(a, typeId, structure) + case Schema.Primitive(standardType, _) => encodePrimitive(a, standardType) + case Schema.Sequence(element, _, g, _, _) => encodeSequence(element, g(a)) + case Schema.NonEmptySequence(element, _, g, _, _) => encodeSequence(element, g(a)) + case Schema.Set(element, _) => encodeSet(element, a) case mapSchema: Schema.Map[_, _] => encodeMap(mapSchema.asInstanceOf[Schema.Map[Any, Any]], a.asInstanceOf[scala.collection.immutable.Map[Any, Any]]) + case mapSchema: Schema.NonEmptyMap[_, _] => + encodeMap( + Schema.Map( + mapSchema.keySchema.asInstanceOf[Schema[Any]], + mapSchema.valueSchema.asInstanceOf[Schema[Any]], + mapSchema.annotations + ), + a.asInstanceOf[NonEmptyMap[Any, Any]].toMap + ) case Schema.Transform(schema, _, g, _, _) => g(a).map(encodeValue(_, schema)).getOrElse(throw new Exception("Transform failed.")) case Schema.Optional(schema, _) => encodeOption(schema, a) diff --git a/zio-schema-avro/src/main/scala/zio/schema/codec/AvroSchemaCodec.scala b/zio-schema-avro/src/main/scala/zio/schema/codec/AvroSchemaCodec.scala index 95cf24b4c..7652f9d33 100644 --- a/zio-schema-avro/src/main/scala/zio/schema/codec/AvroSchemaCodec.scala +++ b/zio-schema-avro/src/main/scala/zio/schema/codec/AvroSchemaCodec.scala @@ -277,12 +277,14 @@ object AvroSchemaCodec extends AvroSchemaCodec { private def toAvroSchema(schema: Schema[_]): scala.util.Either[String, SchemaAvro] = { schema match { - case e: Enum[_] => toAvroEnum(e) - case record: Record[_] => toAvroRecord(record) - case map: Schema.Map[_, _] => toAvroMap(map) - case seq: Schema.Sequence[_, _, _] => toAvroSchema(seq.elementSchema).map(SchemaAvro.createArray) - case set: Schema.Set[_] => toAvroSchema(set.elementSchema).map(SchemaAvro.createArray) - case Transform(codec, _, _, _, _) => toAvroSchema(codec) + case e: Enum[_] => toAvroEnum(e) + case record: Record[_] => toAvroRecord(record) + case map: Schema.Map[_, _] => toAvroMap(map) + case map: Schema.NonEmptyMap[_, _] => toAvroMap(map) + case seq: Schema.Sequence[_, _, _] => toAvroSchema(seq.elementSchema).map(SchemaAvro.createArray) + case seq: Schema.NonEmptySequence[_, _, _] => toAvroSchema(seq.elementSchema).map(SchemaAvro.createArray) + case set: Schema.Set[_] => toAvroSchema(set.elementSchema).map(SchemaAvro.createArray) + case Transform(codec, _, _, _, _) => toAvroSchema(codec) case Primitive(standardType, _) => standardType match { case StandardType.UnitType => Right(SchemaAvro.create(SchemaAvro.Type.NULL)) @@ -624,6 +626,18 @@ object AvroSchemaCodec extends AvroSchemaCodec { toAvroSchema(tupleSchema).map(SchemaAvro.createArray) } + private[codec] def toAvroMap(map: NonEmptyMap[_, _]): scala.util.Either[String, SchemaAvro] = + map.keySchema match { + case p: Schema.Primitive[_] if p.standardType == StandardType.StringType => + toAvroSchema(map.valueSchema).map(SchemaAvro.createMap) + case _ => + val tupleSchema = Schema + .Tuple2(map.keySchema, map.valueSchema) + .annotate(AvroAnnotations.name("Tuple")) + .annotate(AvroAnnotations.namespace("scala")) + toAvroSchema(tupleSchema).map(SchemaAvro.createArray) + } + private[codec] def toAvroDecimal(schema: Schema[_]): scala.util.Either[String, SchemaAvro] = { val scale = schema.annotations.collectFirst { case AvroAnnotations.scale(s) => s } .getOrElse(AvroAnnotations.scale().scale) @@ -820,7 +834,9 @@ object AvroSchemaCodec extends AvroSchemaCodec { case c: Dynamic => Right(c) case c: GenericRecord => Right(c) case c: Map[_, _] => Right(c) + case c: NonEmptyMap[_, _] => Right(c) case c: Sequence[_, _, _] => Right(c) + case c: NonEmptySequence[_, _, _] => Right(c) case c: Set[_] => Right(c) case c: Fail[_] => Right(c) case c: Lazy[_] => Right(c) diff --git a/zio-schema-avro/src/test/scala/zio/schema/codec/AvroSchemaCodecSpec.scala b/zio-schema-avro/src/test/scala/zio/schema/codec/AvroSchemaCodecSpec.scala index bc19b6b82..7306bbce1 100644 --- a/zio-schema-avro/src/test/scala/zio/schema/codec/AvroSchemaCodecSpec.scala +++ b/zio-schema-avro/src/test/scala/zio/schema/codec/AvroSchemaCodecSpec.scala @@ -1918,10 +1918,7 @@ object AssertionHelper { def recordFields(assertion: Assertion[Iterable[Schema.Field[_, _]]]): Assertion[Schema.Record[_]] = Assertion.assertionRec[Schema.Record[_], Chunk[Field[_, _]]]("hasRecordField")( assertion - ) { - case r: Schema.Record[_] => Some(r.fields) - case _ => None - } + )((r: Schema.Record[_]) => Some(r.fields)) def hasSequenceElementSchema[A](assertion: Assertion[Schema[A]]): Assertion[Schema.Sequence[_, A, _]] = Assertion.hasField("schemaA", _.elementSchema, assertion) diff --git a/zio-schema-bson/src/main/scala/zio/schema/codec/BsonSchemaCodec.scala b/zio-schema-bson/src/main/scala/zio/schema/codec/BsonSchemaCodec.scala index bf3298813..2194993ec 100644 --- a/zio-schema-bson/src/main/scala/zio/schema/codec/BsonSchemaCodec.scala +++ b/zio-schema-bson/src/main/scala/zio/schema/codec/BsonSchemaCodec.scala @@ -457,22 +457,24 @@ object BsonSchemaCodec { //scalafmt: { maxColumn = 400, optIn.configStyleArguments = false } private[codec] def schemaEncoder[A](schema: Schema[A]): BsonEncoder[A] = schema match { - case Schema.Primitive(standardType, _) => primitiveCodec(standardType).encoder - case Schema.Sequence(schema, _, g, _, _) => chunkEncoder(schemaEncoder(schema)).contramap(g) - case Schema.Map(ks, vs, _) => mapEncoder(ks, vs) - case Schema.Set(s, _) => chunkEncoder(schemaEncoder(s)).contramap(m => Chunk.fromIterable(m)) - case Schema.Transform(c, _, g, _, _) => transformEncoder(c, g) - case Schema.Tuple2(l, r, _) => tuple2Encoder(schemaEncoder(l), schemaEncoder(r)) - case Schema.Optional(schema, _) => BsonEncoder.option(schemaEncoder(schema)) - case Schema.Fail(_, _) => unitEncoder.contramap(_ => ()) - case Schema.GenericRecord(_, structure, _) => genericRecordEncoder(structure.toChunk) - case Schema.Either(left, right, _) => eitherEncoder(schemaEncoder(left), schemaEncoder(right)) - case Schema.Fallback(left, right, _, _) => fallbackEncoder(schemaEncoder(left), schemaEncoder(right)) - case l @ Schema.Lazy(_) => schemaEncoder(l.schema) - case r: Schema.Record[A] => caseClassEncoder(r) - case e: Schema.Enum[A] => enumEncoder(e, e.cases) - case d @ Schema.Dynamic(_) => dynamicEncoder(d) - case null => throw new Exception(s"A captured schema is null, most likely due to wrong field initialization order") + case Schema.Primitive(standardType, _) => primitiveCodec(standardType).encoder + case Schema.Sequence(schema, _, g, _, _) => chunkEncoder(schemaEncoder(schema)).contramap(g) + case Schema.NonEmptySequence(schema, _, g, _, _) => chunkEncoder(schemaEncoder(schema)).contramap(g) + case Schema.Map(ks, vs, _) => mapEncoder(ks, vs) + case Schema.NonEmptyMap(ks, vs, _) => mapEncoder(ks, vs).contramap(_.toMap) + case Schema.Set(s, _) => chunkEncoder(schemaEncoder(s)).contramap(m => Chunk.fromIterable(m)) + case Schema.Transform(c, _, g, _, _) => transformEncoder(c, g) + case Schema.Tuple2(l, r, _) => tuple2Encoder(schemaEncoder(l), schemaEncoder(r)) + case Schema.Optional(schema, _) => BsonEncoder.option(schemaEncoder(schema)) + case Schema.Fail(_, _) => unitEncoder.contramap(_ => ()) + case Schema.GenericRecord(_, structure, _) => genericRecordEncoder(structure.toChunk) + case Schema.Either(left, right, _) => eitherEncoder(schemaEncoder(left), schemaEncoder(right)) + case Schema.Fallback(left, right, _, _) => fallbackEncoder(schemaEncoder(left), schemaEncoder(right)) + case l @ Schema.Lazy(_) => schemaEncoder(l.schema) + case r: Schema.Record[A] => caseClassEncoder(r) + case e: Schema.Enum[A] => enumEncoder(e, e.cases) + case d @ Schema.Dynamic(_) => dynamicEncoder(d) + case null => throw new Exception(s"A captured schema is null, most likely due to wrong field initialization order") } //scalafmt: { maxColumn = 120, optIn.configStyleArguments = true } @@ -773,22 +775,24 @@ object BsonSchemaCodec { //scalafmt: { maxColumn = 400, optIn.configStyleArguments = false } private[codec] def schemaDecoder[A](schema: Schema[A]): BsonDecoder[A] = schema match { - case Schema.Primitive(standardType, _) => primitiveCodec(standardType).decoder - case Schema.Optional(codec, _) => BsonDecoder.option(schemaDecoder(codec)) - case Schema.Tuple2(left, right, _) => tuple2Decoder(schemaDecoder(left), schemaDecoder(right)) - case Schema.Transform(codec, f, _, _, _) => schemaDecoder(codec).mapOrFail(f) - case Schema.Sequence(codec, f, _, _, _) => chunkDecoder(schemaDecoder(codec)).map(f) - case Schema.Map(ks, vs, _) => mapDecoder(ks, vs) - case Schema.Set(s, _) => chunkDecoder(schemaDecoder(s)).map(entries => entries.toSet) - case Schema.Fail(message, _) => failDecoder(message) - case Schema.GenericRecord(_, structure, _) => recordDecoder(structure.toChunk) - case Schema.Either(left, right, _) => eitherDecoder(schemaDecoder(left), schemaDecoder(right)) - case Schema.Fallback(left, right, _, _) => fallbackDecoder(schemaDecoder(left), schemaDecoder(right)) - case l @ Schema.Lazy(_) => schemaDecoder(l.schema) - case s: Schema.Record[A] => caseClassDecoder(s) - case e: Schema.Enum[A] => enumDecoder(e) - case d @ Schema.Dynamic(_) => dynamicDecoder(d) - case null => throw new Exception(s"Missing a handler for decoding of schema $schema.") + case Schema.Primitive(standardType, _) => primitiveCodec(standardType).decoder + case Schema.Optional(codec, _) => BsonDecoder.option(schemaDecoder(codec)) + case Schema.Tuple2(left, right, _) => tuple2Decoder(schemaDecoder(left), schemaDecoder(right)) + case Schema.Transform(codec, f, _, _, _) => schemaDecoder(codec).mapOrFail(f) + case Schema.Sequence(codec, f, _, _, _) => chunkDecoder(schemaDecoder(codec)).map(f) + case s @ Schema.NonEmptySequence(codec, _, _, _, _) => chunkDecoder(schemaDecoder(codec)).map(s.fromChunk) + case Schema.Map(ks, vs, _) => mapDecoder(ks, vs) + case s @ Schema.NonEmptyMap(ks, vs, _) => mapDecoder(ks, vs).map(s.fromMap) + case Schema.Set(s, _) => chunkDecoder(schemaDecoder(s)).map(entries => entries.toSet) + case Schema.Fail(message, _) => failDecoder(message) + case Schema.GenericRecord(_, structure, _) => recordDecoder(structure.toChunk) + case Schema.Either(left, right, _) => eitherDecoder(schemaDecoder(left), schemaDecoder(right)) + case Schema.Fallback(left, right, _, _) => fallbackDecoder(schemaDecoder(left), schemaDecoder(right)) + case l @ Schema.Lazy(_) => schemaDecoder(l.schema) + case s: Schema.Record[A] => caseClassDecoder(s) + case e: Schema.Enum[A] => enumDecoder(e) + case d @ Schema.Dynamic(_) => dynamicDecoder(d) + case _ => throw new Exception(s"Missing a handler for decoding of schema $schema.") } //scalafmt: { maxColumn = 120, optIn.configStyleArguments = true } diff --git a/zio-schema-bson/src/test/scala/zio/schema/codec/BsonSchemaCodecSpec.scala b/zio-schema-bson/src/test/scala/zio/schema/codec/BsonSchemaCodecSpec.scala index 941dc1450..e3c743c50 100644 --- a/zio-schema-bson/src/test/scala/zio/schema/codec/BsonSchemaCodecSpec.scala +++ b/zio-schema-bson/src/test/scala/zio/schema/codec/BsonSchemaCodecSpec.scala @@ -40,10 +40,10 @@ object BsonSchemaCodecSpec extends ZIOSpecDefault { implicit lazy val schema: Schema[Tree] = DeriveSchema.gen implicit lazy val codec: BsonCodec[Tree] = BsonSchemaCodec.bsonCodec(schema) - private val genLeaf = Gen.int.map(Leaf) + private val genLeaf = Gen.int.map(Leaf.apply) lazy val gen: Gen[Any, Tree] = Gen.sized { i => - if (i >= 2) Gen.oneOf(genLeaf, Gen.suspend(gen.zipWith(gen)(Branch)).resize(i / 2)) + if (i >= 2) Gen.oneOf(genLeaf, Gen.suspend(gen.zipWith(gen)(Branch.apply)).resize(i / 2)) else genLeaf } } diff --git a/zio-schema-derivation/shared/src/main/scala/zio/schema/CachedDeriver.scala b/zio-schema-derivation/shared/src/main/scala/zio/schema/CachedDeriver.scala index 53d516a65..3dd37ac99 100644 --- a/zio-schema-derivation/shared/src/main/scala/zio/schema/CachedDeriver.scala +++ b/zio-schema-derivation/shared/src/main/scala/zio/schema/CachedDeriver.scala @@ -126,18 +126,22 @@ private[schema] object CachedDeriver { final case class Tuple2[A, B](leftKey: CacheKey[A], rightKey: CacheKey[B]) extends CacheKey[(A, B)] final case class Set[A](element: CacheKey[A]) extends CacheKey[Set[A]] final case class Map[K, V](key: CacheKey[K], valuew: CacheKey[V]) extends CacheKey[Map[K, V]] + final case class NonEmptyMap[K, V](key: CacheKey[K], valuew: CacheKey[V]) extends CacheKey[NonEmptyMap[K, V]] final case class Misc[A](schema: Schema[A]) extends CacheKey[A] def fromStandardType[A](st: StandardType[A]): CacheKey[A] = Primitive(st) def fromSchema[A](schema: Schema[A]): CacheKey[A] = schema match { - case e: Schema.Enum[_] => WithId(e.id) - case record: Schema.Record[_] => WithId(record.id) - case seq: Schema.Sequence[_, _, _] => WithIdentityObject(fromSchema(seq.elementSchema), seq.identity) - case set: Schema.Set[_] => Set(fromSchema(set.elementSchema)).asInstanceOf[CacheKey[A]] + case e: Schema.Enum[_] => WithId(e.id) + case record: Schema.Record[_] => WithId(record.id) + case seq: Schema.Sequence[_, _, _] => WithIdentityObject(fromSchema(seq.elementSchema), seq.identity) + case seq: Schema.NonEmptySequence[_, _, _] => WithIdentityObject(fromSchema(seq.elementSchema), seq.identity) + case set: Schema.Set[_] => Set(fromSchema(set.elementSchema)).asInstanceOf[CacheKey[A]] case map: Schema.Map[_, _] => Map(fromSchema(map.keySchema), fromSchema(map.valueSchema)).asInstanceOf[CacheKey[A]] + case map: Schema.NonEmptyMap[_, _] => + Map(fromSchema(map.keySchema), fromSchema(map.valueSchema)).asInstanceOf[CacheKey[A]] case Schema.Transform(inner, _, _, _, identity) => WithIdentityObject(fromSchema(inner), identity) case Schema.Primitive(standardType, _) => fromStandardType(standardType) case optional: Schema.Optional[_] => Optional(fromSchema(optional.schema)).asInstanceOf[CacheKey[A]] diff --git a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala index 23a5f5635..93e9113ac 100644 --- a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala +++ b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala @@ -17,6 +17,7 @@ import zio.json.{ JsonFieldDecoder, JsonFieldEncoder } +import zio.prelude.NonEmptyMap import zio.schema._ import zio.schema.annotation._ import zio.schema.codec.DecodeError.ReadError @@ -182,9 +183,11 @@ object JsonCodec { //scalafmt: { maxColumn = 400, optIn.configStyleArguments = false } private[codec] def schemaEncoder[A](schema: Schema[A], cfg: Config, discriminatorTuple: DiscriminatorTuple = Chunk.empty): ZJsonEncoder[A] = schema match { - case Schema.Primitive(standardType, _) => primitiveCodec(standardType).encoder - case Schema.Sequence(schema, _, g, _, _) => ZJsonEncoder.chunk(schemaEncoder(schema, cfg, discriminatorTuple)).contramap(g) - case Schema.Map(ks, vs, _) => mapEncoder(ks, vs, discriminatorTuple, cfg) + case Schema.Primitive(standardType, _) => primitiveCodec(standardType).encoder + case Schema.Sequence(schema, _, g, _, _) => ZJsonEncoder.chunk(schemaEncoder(schema, cfg, discriminatorTuple)).contramap(g) + case Schema.NonEmptySequence(schema, _, g, _, _) => ZJsonEncoder.chunk(schemaEncoder(schema, cfg, discriminatorTuple)).contramap(g) + case Schema.Map(ks, vs, _) => mapEncoder(ks, vs, discriminatorTuple, cfg) + case Schema.NonEmptyMap(ks: Schema[kt], vs: Schema[vt], _) => mapEncoder(ks, vs, discriminatorTuple, cfg).contramap[NonEmptyMap[kt, vt]](_.toMap.asInstanceOf[Map[kt, vt]]).asInstanceOf[ZJsonEncoder[A]] case Schema.Set(s, _) => ZJsonEncoder.chunk(schemaEncoder(s, cfg, discriminatorTuple)).contramap(m => Chunk.fromIterable(m)) case Schema.Transform(c, _, g, a, _) => transformEncoder(a.foldLeft(c)((s, a) => s.annotate(a)), g, cfg) @@ -544,18 +547,20 @@ object JsonCodec { //scalafmt: { maxColumn = 400, optIn.configStyleArguments = false } private[codec] def schemaDecoder[A](schema: Schema[A], discriminator: Int = -1): ZJsonDecoder[A] = schema match { - case Schema.Primitive(standardType, _) => primitiveCodec(standardType).decoder - case Schema.Optional(codec, _) => option(schemaDecoder(codec, discriminator)) - case Schema.Tuple2(left, right, _) => ZJsonDecoder.tuple2(schemaDecoder(left, -1), schemaDecoder(right, -1)) - case Schema.Transform(c, f, _, a, _) => schemaDecoder(a.foldLeft(c)((s, a) => s.annotate(a)), discriminator).mapOrFail(f) - case Schema.Sequence(codec, f, _, _, _) => ZJsonDecoder.chunk(schemaDecoder(codec, -1)).map(f) - case Schema.Map(ks, vs, _) => mapDecoder(ks, vs) - case Schema.Set(s, _) => ZJsonDecoder.chunk(schemaDecoder(s, -1)).map(entries => entries.toSet) - case Schema.Fail(message, _) => failDecoder(message) - case Schema.GenericRecord(_, structure, _) => recordDecoder(structure.toChunk, schema.annotations.contains(rejectExtraFields())) - case Schema.Either(left, right, _) => ZJsonDecoder.either(schemaDecoder(left, -1), schemaDecoder(right, -1)) - case s @ Schema.Fallback(_, _, _, _) => fallbackDecoder(s) - case l @ Schema.Lazy(_) => schemaDecoder(l.schema, discriminator) + case Schema.Primitive(standardType, _) => primitiveCodec(standardType).decoder + case Schema.Optional(codec, _) => option(schemaDecoder(codec, discriminator)) + case Schema.Tuple2(left, right, _) => ZJsonDecoder.tuple2(schemaDecoder(left, -1), schemaDecoder(right, -1)) + case Schema.Transform(c, f, _, a, _) => schemaDecoder(a.foldLeft(c)((s, a) => s.annotate(a)), discriminator).mapOrFail(f) + case Schema.Sequence(codec, f, _, _, _) => ZJsonDecoder.chunk(schemaDecoder(codec, -1)).map(f) + case s @ Schema.NonEmptySequence(codec, _, _, _, _) => ZJsonDecoder.chunk(schemaDecoder(codec, -1)).map(s.fromChunk) + case Schema.Map(ks, vs, _) => mapDecoder(ks, vs) + case Schema.NonEmptyMap(ks, vs, _) => mapDecoder(ks, vs).mapOrFail(m => NonEmptyMap.fromMapOption(m).toRight("NonEmptyMap expected")) + case Schema.Set(s, _) => ZJsonDecoder.chunk(schemaDecoder(s, -1)).map(entries => entries.toSet) + case Schema.Fail(message, _) => failDecoder(message) + case Schema.GenericRecord(_, structure, _) => recordDecoder(structure.toChunk, schema.annotations.contains(rejectExtraFields())) + case Schema.Either(left, right, _) => ZJsonDecoder.either(schemaDecoder(left, -1), schemaDecoder(right, -1)) + case s @ Schema.Fallback(_, _, _, _) => fallbackDecoder(s) + case l @ Schema.Lazy(_) => schemaDecoder(l.schema, discriminator) //case Schema.Meta(_, _) => astDecoder case s @ Schema.CaseClass0(_, _, _) => caseClass0Decoder(discriminator, s) case s @ Schema.CaseClass1(_, _, _, _) => caseClass1Decoder(discriminator, s) diff --git a/zio-schema-optics/shared/src/main/scala/zio/schema/optics/ZioOpticsBuilder.scala b/zio-schema-optics/shared/src/main/scala/zio/schema/optics/ZioOpticsBuilder.scala index 6da76d0d8..73bf1b27f 100644 --- a/zio-schema-optics/shared/src/main/scala/zio/schema/optics/ZioOpticsBuilder.scala +++ b/zio-schema-optics/shared/src/main/scala/zio/schema/optics/ZioOpticsBuilder.scala @@ -3,6 +3,7 @@ package zio.schema.optics import scala.collection.immutable.ListMap import zio.optics._ +import zio.prelude.NonEmptyMap import zio.schema._ import zio.{ Chunk, ChunkBuilder } @@ -44,14 +45,24 @@ object ZioOpticsBuilder extends AccessorBuilder { collection match { case seq @ Schema.Sequence(_, _, _, _, _) => ZTraversal[S, S, A, A]( - ZioOpticsBuilder.makeSeqTraversalGet(seq), + ZioOpticsBuilder.makeSeqTraversalGet(seq.toChunk), ZioOpticsBuilder.makeSeqTraversalSet(seq) ) + case seq @ Schema.NonEmptySequence(_, _, _, _, _) => + ZTraversal[S, S, A, A]( + ZioOpticsBuilder.makeSeqTraversalGet(seq.toChunk), + ZioOpticsBuilder.makeNonEmptySeqTraversalSet(seq) + ) case Schema.Map(_: Schema[k], _: Schema[v], _) => ZTraversal( ZioOpticsBuilder.makeMapTraversalGet[k, v], ZioOpticsBuilder.makeMapTraversalSet[k, v] ) + case Schema.NonEmptyMap(_: Schema[k], _: Schema[v], _) => + ZTraversal( + ZioOpticsBuilder.makeMapTraversalGet[k, v], + ZioOpticsBuilder.makeNonEmptyMapTraversalSet[k, v] + ) case Schema.Set(_, _) => ZTraversal( ZioOpticsBuilder.makeSetTraversalGet[A], @@ -103,9 +114,9 @@ object ZioOpticsBuilder extends AccessorBuilder { } private[optics] def makeSeqTraversalGet[S, A]( - collection: Schema.Sequence[S, A, _] + toChunk: S => Chunk[A] ): S => Either[(OpticFailure, S), Chunk[A]] = { (whole: S) => - Right(collection.toChunk(whole)) + Right(toChunk(whole)) } private[optics] def makeSeqTraversalSet[S, A]( @@ -123,15 +134,40 @@ object ZioOpticsBuilder extends AccessorBuilder { } Right(collection.fromChunk(builder.result())) } + private[optics] def makeNonEmptySeqTraversalSet[S, A]( + collection: Schema.NonEmptySequence[S, A, _] + ): Chunk[A] => S => Either[(OpticFailure, S), S] = { (piece: Chunk[A]) => (whole: S) => + val builder = ChunkBuilder.make[A]() + val leftIterator = collection.toChunk(whole).iterator + val rightIterator = piece.iterator + while (leftIterator.hasNext && rightIterator.hasNext) { + val _ = leftIterator.next() + builder += rightIterator.next() + } + while (leftIterator.hasNext) { + builder += leftIterator.next() + } + Right(collection.fromChunk(builder.result())) + } private[optics] def makeMapTraversalGet[K, V](whole: Map[K, V]): Either[(OpticFailure, Map[K, V]), Chunk[(K, V)]] = Right(Chunk.fromIterable(whole)) + private[optics] def makeMapTraversalGet[K, V]( + whole: NonEmptyMap[K, V] + ): Either[(OpticFailure, NonEmptyMap[K, V]), Chunk[(K, V)]] = + Right(Chunk.fromIterable(whole.toMap)) + private[optics] def makeMapTraversalSet[K, V] : Chunk[(K, V)] => Map[K, V] => Either[(OpticFailure, Map[K, V]), Map[K, V]] = { (piece: Chunk[(K, V)]) => (whole: Map[K, V]) => Right(whole ++ piece.toList) } + private[optics] def makeNonEmptyMapTraversalSet[K, V] + : Chunk[(K, V)] => NonEmptyMap[K, V] => Either[(OpticFailure, NonEmptyMap[K, V]), NonEmptyMap[K, V]] = { + (piece: Chunk[(K, V)]) => (whole: NonEmptyMap[K, V]) => + Right(whole ++ piece.toList) + } private[optics] def makeSetTraversalGet[A](whole: Set[A]): Either[(OpticFailure, Set[A]), Chunk[A]] = Right(Chunk.fromIterable(whole)) diff --git a/zio-schema-protobuf/shared/src/main/scala/zio/schema/codec/ProtobufCodec.scala b/zio-schema-protobuf/shared/src/main/scala/zio/schema/codec/ProtobufCodec.scala index 77a87e90f..c51bafeef 100644 --- a/zio-schema-protobuf/shared/src/main/scala/zio/schema/codec/ProtobufCodec.scala +++ b/zio-schema-protobuf/shared/src/main/scala/zio/schema/codec/ProtobufCodec.scala @@ -54,16 +54,17 @@ object ProtobufCodec { */ @scala.annotation.tailrec private[codec] def canBePacked(schema: Schema[_]): Boolean = schema match { - case Schema.Sequence(element, _, _, _, _) => canBePacked(element) - case Schema.Transform(codec, _, _, _, _) => canBePacked(codec) - case Schema.Primitive(standardType, _) => canBePacked(standardType) - case _: Schema.Tuple2[_, _] => false - case _: Schema.Optional[_] => false - case _: Schema.Fail[_] => false - case _: Schema.Either[_, _] => false - case _: Schema.Fallback[_, _] => false - case lzy @ Schema.Lazy(_) => canBePacked(lzy.schema) - case _ => false + case Schema.Sequence(element, _, _, _, _) => canBePacked(element) + case Schema.NonEmptySequence(element, _, _, _, _) => canBePacked(element) + case Schema.Transform(codec, _, _, _, _) => canBePacked(codec) + case Schema.Primitive(standardType, _) => canBePacked(standardType) + case _: Schema.Tuple2[_, _] => false + case _: Schema.Optional[_] => false + case _: Schema.Fail[_] => false + case _: Schema.Either[_, _] => false + case _: Schema.Fallback[_, _] => false + case lzy @ Schema.Lazy(_) => canBePacked(lzy.schema) + case _ => false } private def canBePacked(standardType: StandardType[_]): Boolean = standardType match { @@ -181,8 +182,6 @@ object ProtobufCodec { encodeKey(rightWireType, Some(2)) ++ rightDecoder.remainder encodeKey(WireType.LengthDelimited(data.size), Some(seqIndex)) ++ data - case other => - throw new IllegalStateException(s"Invalid state in processDictionary: $other") } }.flatten val data = encodeKey( @@ -370,7 +369,7 @@ object ProtobufCodec { byteBuffer.order(ByteOrder.LITTLE_ENDIAN) byteBuffer.putDouble(v) encodeKey(WireType.Bit64, fieldNumber) ++ Chunk.fromArray(byteBuffer.array) - case (StandardType.BinaryType, bytes: Chunk[Byte]) => + case (StandardType.BinaryType, bytes: Chunk[Byte] @unchecked) => encodeKey(WireType.LengthDelimited(bytes.length), fieldNumber) ++ bytes case (StandardType.CharType, c: Char) => encodePrimitive(fieldNumber, StandardType.StringType, c.toString) @@ -780,7 +779,6 @@ object ProtobufCodec { override protected def finishedCreatingOneSequenceElement( context: DecoderContext, - schema: Schema.Sequence[_, _, _], index: Int ): Boolean = state.length(context) > 0 diff --git a/zio-schema-thrift/src/main/scala/zio/schema/codec/ThriftCodec.scala b/zio-schema-thrift/src/main/scala/zio/schema/codec/ThriftCodec.scala index bfc928d58..06ab301aa 100644 --- a/zio-schema-thrift/src/main/scala/zio/schema/codec/ThriftCodec.scala +++ b/zio-schema-thrift/src/main/scala/zio/schema/codec/ThriftCodec.scala @@ -432,18 +432,20 @@ object ThriftCodec { @tailrec final private def getType[A](schema: Schema[A]): Byte = schema match { - case _: Schema.Record[A] => TType.STRUCT - case Schema.Sequence(_, _, _, _, _) => TType.LIST - case Schema.Map(_, _, _) => TType.MAP - case Schema.Set(_, _) => TType.SET - case Schema.Transform(schema, _, _, _, _) => getType(schema) - case Schema.Primitive(standardType, _) => getPrimitiveType(standardType) - case Schema.Tuple2(_, _, _) => TType.STRUCT - case Schema.Optional(schema, _) => getType(schema) - case Schema.Either(_, _, _) => TType.STRUCT - case Schema.Lazy(lzy) => getType(lzy()) - case _: Schema.Enum[A] => TType.STRUCT - case _ => TType.VOID + case _: Schema.Record[A] => TType.STRUCT + case Schema.Sequence(_, _, _, _, _) => TType.LIST + case Schema.NonEmptySequence(_, _, _, _, _) => TType.LIST + case Schema.Map(_, _, _) => TType.MAP + case Schema.NonEmptyMap(_, _, _) => TType.MAP + case Schema.Set(_, _) => TType.SET + case Schema.Transform(schema, _, _, _, _) => getType(schema) + case Schema.Primitive(standardType, _) => getPrimitiveType(standardType) + case Schema.Tuple2(_, _, _) => TType.STRUCT + case Schema.Optional(schema, _) => getType(schema) + case Schema.Either(_, _, _) => TType.STRUCT + case Schema.Lazy(lzy) => getType(lzy()) + case _: Schema.Enum[A] => TType.STRUCT + case _ => TType.VOID } } @@ -691,7 +693,6 @@ object ThriftCodec { override protected def finishedCreatingOneSequenceElement( context: DecoderContext, - schema: Schema.Sequence[_, _, _], index: Int ): Boolean = context.expectedCount.map(_ - (index + 1)).exists(_ > 0) diff --git a/zio-schema/shared/src/main/scala/zio/schema/Differ.scala b/zio-schema/shared/src/main/scala/zio/schema/Differ.scala index 5796e53aa..132a01832 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Differ.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Differ.scala @@ -25,6 +25,7 @@ import java.util.{ Currency, UUID } import scala.annotation.nowarn import scala.collection.immutable.ListMap +import zio.prelude.NonEmptyMap import zio.schema.diff.Edit import zio.{ Chunk, ChunkBuilder } @@ -263,12 +264,13 @@ object Differ { Right(Currency.getInstance(s)) } catch { case e: Throwable => Left(s"$s is not a valid Currency: ${e.getMessage}") } ) - case Schema.Tuple2(leftSchema, rightSchema, _) => fromSchema(leftSchema) <*> fromSchema(rightSchema) - case Schema.Optional(schema, _) => fromSchema(schema).optional - case Schema.Sequence(schema, g, f, _, _) => - fromSchema(schema).chunk.transform(f, g) + case Schema.Tuple2(leftSchema, rightSchema, _) => fromSchema(leftSchema) <*> fromSchema(rightSchema) + case Schema.Optional(schema, _) => fromSchema(schema).optional + case Schema.Sequence(schema, g, f, _, _) => fromSchema(schema).chunk.transform(f, g) + case s @ Schema.NonEmptySequence(schema, _, f, _, _) => fromSchema(schema).chunk.transform(f, s.fromChunk) case Schema.Set(s, _) => set(s) case Schema.Map(k, v, _) => map(k, v) + case s @ Schema.NonEmptyMap(k: Schema[kt], v: Schema[vt], _) => map(k, v).transform[NonEmptyMap[kt, vt]](_.toMap.asInstanceOf[Map[kt, vt]], s.fromMap).asInstanceOf[Differ[A]] case Schema.Either(leftSchema, rightSchema, _) => either(fromSchema(leftSchema), fromSchema(rightSchema)) case Schema.Fallback(leftSchema, rightSchema, _, _) => fallback(fromSchema(leftSchema), fromSchema(rightSchema)) case s @ Schema.Lazy(_) => fromSchema(s.schema) diff --git a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala index 9234ffbfd..fab014698 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueBuilder.scala @@ -2,6 +2,7 @@ package zio.schema import scala.util.control.NonFatal +import zio.prelude.NonEmptyMap import zio.schema.MutableSchemaBasedValueBuilder.{ CreateValueFromSchemaError, ReadingFieldResult } import zio.{ Chunk, ChunkBuilder } @@ -63,7 +64,6 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { * is called. */ protected def finishedCreatingOneSequenceElement( context: Context, - schema: Schema.Sequence[_, _, _], index: Int ): Boolean @@ -542,7 +542,37 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { elems += elem contextStack = contextStack.tail - val continue = finishedCreatingOneSequenceElement(contextStack.head, s, index) + val continue = finishedCreatingOneSequenceElement(contextStack.head, index) + + if (continue) { + currentSchema = elementSchema + pushContext(startCreatingOneSequenceElement(contextStack.head, s)) + readOne(index + 1) + } else { + contextStack = contextStack.tail + finishWith(createSequence(contextStack.head, s, elems.result())) + } + } + + currentSchema = elementSchema + startCreatingSequence(currentContext, s) match { + case Some(startingState) => + pushContext(startingState) + pushContext(startCreatingOneSequenceElement(startingState, s)) + readOne(0) + case None => + finishWith(createSequence(currentContext, s, Chunk.empty)) + } + case nes @ Schema.NonEmptySequence(elementSchema, _, _, _, _) => + val s = Schema.Sequence(elementSchema, nes.fromChunk, nes.toChunk, nes.annotations, nes.identity) + val elems = ChunkBuilder.make[Target]() + + def readOne(index: Int): Unit = + push { elem => + elems += elem + + contextStack = contextStack.tail + val continue = finishedCreatingOneSequenceElement(contextStack.head, index) if (continue) { currentSchema = elementSchema @@ -600,6 +630,53 @@ trait MutableSchemaBasedValueBuilder[Target, Context] { case None => finishWith(createDictionary(contextStack.head, s, Chunk.empty)) } + case nem @ Schema.NonEmptyMap(ks: Schema[k], vs: Schema[v], _) => + val s = Schema.Map(ks, vs, nem.annotations) + val elems = ChunkBuilder.make[(Target, Target)]() + + def readOne(index: Int): Unit = + push { key => + currentSchema = vs + pushContext(startCreatingOneDictionaryValue(currentContext, s)) + + push { value => + val elem = (key, value) + elems += elem + + contextStack = contextStack.tail.tail + val continue = finishedCreatingOneDictionaryElement(contextStack.head, s, index) + + if (continue) { + currentSchema = ks + pushContext(startCreatingOneDictionaryElement(contextStack.head, s)) + readOne(index + 1) + } else { + val state = contextStack.head + contextStack = contextStack.tail + finishWith( + NonEmptyMap + .fromMapOption(createDictionary(state, s, elems.result()).asInstanceOf[Map[k, v]]) + .getOrElse(throw new IllegalStateException("NonEmpty map requires at least on element")) + .asInstanceOf[Target] + ) + } + } + } + + startCreatingDictionary(currentContext, s) match { + case Some(startingState) => + currentSchema = ks + pushContext(startingState) + pushContext(startCreatingOneDictionaryElement(startingState, s)) + readOne(0) + case None => + finishWith( + NonEmptyMap + .fromMapOption(createDictionary(contextStack.head, s, Chunk.empty).asInstanceOf[Map[k, v]]) + .getOrElse(throw new IllegalStateException("NonEmpty map requires at least on element")) + .asInstanceOf[Target] + ) + } case s @ Schema.Set(as: Schema[a], _) => val elems = ChunkBuilder.make[Target]() diff --git a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueProcessor.scala b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueProcessor.scala index dfc890104..734f86e44 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueProcessor.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/MutableSchemaBasedValueProcessor.scala @@ -2,6 +2,7 @@ package zio.schema import scala.collection.immutable.ListMap +import zio.prelude.NonEmptyMap import zio.{ Chunk, ChunkBuilder } /** Base trait for mutable value processors, processing a value with a known schema. An example @@ -760,6 +761,29 @@ trait MutableSchemaBasedValueProcessor[Target, Context] { } } + startProcessingSequence(currentContext, s, inputChunk.size) + pushContext(contextForSequence(currentContext, s, 0)) + processNext(0) + case nes @ Schema.NonEmptySequence(schema, _, _, _, _) => + val s = Schema.Sequence(schema, nes.fromChunk, nes.toChunk, nes.annotations, nes.identity) + val inputChunk = nes.toChunk.asInstanceOf[Any => Chunk[Any]](currentValue) + val resultChunk = ChunkBuilder.make[Target](inputChunk.size) + + def processNext(inputIdx: Int): Unit = { + contextStack = contextStack.tail + if (inputIdx == inputChunk.size) { + finishWith(processSequence(currentContext, s, resultChunk.result())) + } else { + currentSchema = schema + currentValue = inputChunk(inputIdx) + pushContext(contextForSequence(currentContext, s, inputIdx)) + push { dv => + resultChunk += dv + processNext(inputIdx + 1) + } + } + } + startProcessingSequence(currentContext, s, inputChunk.size) pushContext(contextForSequence(currentContext, s, 0)) processNext(0) @@ -768,6 +792,37 @@ trait MutableSchemaBasedValueProcessor[Target, Context] { val inputChunk = Chunk.fromIterable(currentValue.asInstanceOf[Map[k, v]]) val resultChunk = ChunkBuilder.make[(Target, Target)](inputChunk.size) + def processNext(inputIdx: Int): Unit = + if (inputIdx == inputChunk.size) { + finishWith(processDictionary(currentContext, s, resultChunk.result())) + } else { + currentSchema = ks + val currentTuple = inputChunk(inputIdx) + currentValue = currentTuple._1 + + pushContext(contextForMap(currentContext, s, inputIdx)) + push { (a: Target) => + contextStack = contextStack.tail + + currentSchema = vs + currentValue = currentTuple._2 + pushContext(contextForMap(currentContext, s, inputIdx)) + push { (b: Target) => + contextStack = contextStack.tail + val pair = (a, b) + resultChunk += pair + processNext(inputIdx + 1) + } + } + } + + startProcessingDictionary(currentContext, s, inputChunk.size) + processNext(0) + case nem @ Schema.NonEmptyMap(ks: Schema[k], vs: Schema[v], _) => + val s = Schema.Map(ks, vs, nem.annotations) + val inputChunk = Chunk.fromIterable(currentValue.asInstanceOf[NonEmptyMap[k, v]].toMap) + val resultChunk = ChunkBuilder.make[(Target, Target)](inputChunk.size) + def processNext(inputIdx: Int): Unit = if (inputIdx == inputChunk.size) { finishWith(processDictionary(currentContext, s, resultChunk.result())) diff --git a/zio-schema/shared/src/main/scala/zio/schema/Schema.scala b/zio-schema/shared/src/main/scala/zio/schema/Schema.scala index ec792b7ff..6b722ce8e 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/Schema.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/Schema.scala @@ -6,11 +6,12 @@ import java.time.temporal.ChronoUnit import scala.annotation.tailrec import scala.collection.immutable.ListMap +import zio.prelude.NonEmptySet import zio.schema.annotation._ import zio.schema.internal.SourceLocation import zio.schema.meta._ import zio.schema.validation._ -import zio.{ Chunk, Unsafe } +import zio.{ Chunk, NonEmptyChunk, Unsafe, prelude } /** * A `Schema[A]` describes the structure of some data type `A`, in terms of case classes, @@ -196,6 +197,8 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality { schema match { case Sequence(schema, _, toChunk, _, _) => toChunk(value).flatMap(value => loop(value, schema)) + case nes @ NonEmptySequence(schema, _, _, _, _) => + nes.toChunk(value).flatMap(value => loop(value, schema)) case Transform(schema, _, g, _, _) => g(value) match { case Right(value) => loop(value, schema) @@ -211,6 +214,10 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality { loop(tuple.extract1(value), left) ++ loop(tuple.extract2(value), right) case l @ Lazy(_) => loop(value, l.schema) + case Schema.NonEmptyMap(ks, vs, _) => + Chunk.fromIterable(value.toMap.keys).flatMap(loop(_, ks)) ++ Chunk + .fromIterable(value.values) + .flatMap(loop(_, vs)) case Schema.Map(ks, vs, _) => Chunk.fromIterable(value.keys).flatMap(loop(_, ks)) ++ Chunk.fromIterable(value.values).flatMap(loop(_, vs)) case set @ Schema.Set(as, _) => @@ -299,6 +306,30 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality { implicit def chunk[A](implicit schemaA: Schema[A]): Schema[Chunk[A]] = Schema.Sequence[Chunk[A], A, String](schemaA, identity, identity, Chunk.empty, "Chunk") + implicit def nonEmptyChunk[A](implicit schemaA: Schema[A]): Schema[NonEmptyChunk[A]] = + Schema.NonEmptySequence[NonEmptyChunk[A], A, String]( + schemaA, + NonEmptyChunk.fromChunk, + _.toChunk, + Chunk.empty, + "NonEmptyChunk" + ) + + implicit def nonEmptySet[A](implicit schemaA: Schema[A]): Schema[NonEmptySet[A]] = + Schema.NonEmptySequence[NonEmptySet[A], A, String]( + schemaA, + chunk => NonEmptySet.fromSetOption(chunk.toSet), + _.toNonEmptyChunk.toChunk, + Chunk.empty, + "NonEmptySet" + ) + + implicit def nonEmptyMap[K, V]( + implicit keySchema: Schema[K], + valueSchema: Schema[V] + ): Schema[prelude.NonEmptyMap[K, V]] = + Schema.NonEmptyMap[K, V](keySchema, valueSchema, Chunk.empty) + implicit def map[K, V]( implicit keySchema: Schema[K], valueSchema: Schema[V] @@ -788,6 +819,67 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality { b.makeTraversal(self, keySchema <*> valueSchema) } + final case class NonEmptyMap[K, V]( + keySchema: Schema[K], + valueSchema: Schema[V], + override val annotations: Chunk[Any] = Chunk.empty + ) extends Collection[prelude.NonEmptyMap[K, V], (K, V)] { + self => + override type Accessors[Lens[_, _, _], Prism[_, _, _], Traversal[_, _]] = + Traversal[prelude.NonEmptyMap[K, V], (K, V)] + + override def annotate(annotation: Any): NonEmptyMap[K, V] = + copy(annotations = (annotations :+ annotation).distinct) + + override def defaultValue: scala.Either[String, prelude.NonEmptyMap[K, V]] = + keySchema.defaultValue.flatMap( + defaultKey => valueSchema.defaultValue.map(defaultValue => prelude.NonEmptyMap(defaultKey -> defaultValue)) + ) + + def fromChunk(chunk: Chunk[(K, V)]): prelude.NonEmptyMap[K, V] = + fromChunkOption(chunk).getOrElse(throw new IllegalArgumentException("NonEmptyMap cannot be empty")) + + def fromChunkOption(chunk: Chunk[(K, V)]): Option[prelude.NonEmptyMap[K, V]] = + NonEmptyChunk.fromChunk(chunk).map(prelude.NonEmptyMap.fromNonEmptyChunk) + + def fromMap(map: scala.collection.immutable.Map[K, V]): prelude.NonEmptyMap[K, V] = + prelude.NonEmptyMap + .fromMapOption(map) + .getOrElse(throw new IllegalArgumentException("NonEmptyMap cannot be empty")) + + def toChunk(map: prelude.NonEmptyMap[K, V]): Chunk[(K, V)] = + Chunk.fromIterable(map.toList) + + override def makeAccessors(b: AccessorBuilder): b.Traversal[prelude.NonEmptyMap[K, V], (K, V)] = + b.makeTraversal(self, keySchema <*> valueSchema) + } + + final case class NonEmptySequence[Col, Elm, I]( + elementSchema: Schema[Elm], + fromChunkOption: Chunk[Elm] => Option[Col], + toChunk: Col => Chunk[Elm], + override val annotations: Chunk[Any] = Chunk.empty, + identity: I + ) extends Collection[Col, Elm] { + self => + override type Accessors[Lens[_, _, _], Prism[_, _, _], Traversal[_, _]] = Traversal[Col, Elm] + + val fromChunk: Chunk[Elm] => Col = (chunk: Chunk[Elm]) => + fromChunkOption(chunk).getOrElse( + throw new IllegalArgumentException(s"NonEmptySequence $identity cannot be empty") + ) + + override def annotate(annotation: Any): NonEmptySequence[Col, Elm, I] = + copy(annotations = (annotations :+ annotation).distinct) + + override def defaultValue: scala.util.Either[String, Col] = + elementSchema.defaultValue.map(fromChunk.compose(Chunk(_))) + + override def makeAccessors(b: AccessorBuilder): b.Traversal[Col, Elm] = b.makeTraversal(self, elementSchema) + + override def toString: String = s"NonEmptySequence($elementSchema, $identity)" + } + final case class Set[A](elementSchema: Schema[A], override val annotations: Chunk[Any] = Chunk.empty) extends Collection[scala.collection.immutable.Set[A], A] { self => diff --git a/zio-schema/shared/src/main/scala/zio/schema/meta/ExtensibleMetaSchema.scala b/zio-schema/shared/src/main/scala/zio/schema/meta/ExtensibleMetaSchema.scala index 5e8f9f2aa..3bee800a3 100644 --- a/zio-schema/shared/src/main/scala/zio/schema/meta/ExtensibleMetaSchema.scala +++ b/zio-schema/shared/src/main/scala/zio/schema/meta/ExtensibleMetaSchema.scala @@ -573,12 +573,20 @@ object ExtensibleMetaSchema { ) case Schema.Sequence(schema, _, _, _, _) => ListNode(item = subtree(NodePath.root / "item", Lineage.empty, schema), NodePath.root) + case Schema.NonEmptySequence(schema, _, _, _, _) => + ListNode(item = subtree(NodePath.root / "item", Lineage.empty, schema), NodePath.root) case Schema.Map(ks, vs, _) => Dictionary( keys = subtree(NodePath.root / "keys", Lineage.empty, ks), values = subtree(NodePath.root / "values", Lineage.empty, vs), NodePath.root ) + case Schema.NonEmptyMap(ks, vs, _) => + Dictionary( + keys = subtree(NodePath.root / "keys", Lineage.empty, ks), + values = subtree(NodePath.root / "values", Lineage.empty, vs), + NodePath.root + ) case Schema.Set(schema, _) => ListNode(item = subtree(NodePath.root / "item", Lineage.empty, schema), NodePath.root) case Schema.Transform(schema, _, _, _, _) => subtree(NodePath.root, Lineage.empty, schema) @@ -642,6 +650,8 @@ object ExtensibleMetaSchema { ) case Schema.Sequence(schema, _, _, _, _) => ListNode(item = subtree(path / "item", lineage, schema, optional = false), path, optional) + case Schema.NonEmptySequence(schema, _, _, _, _) => + ListNode(item = subtree(path / "item", lineage, schema, optional = false), path, optional) case Schema.Map(ks, vs, _) => Dictionary( keys = subtree(path / "keys", Lineage.empty, ks, optional = false), @@ -649,6 +659,13 @@ object ExtensibleMetaSchema { path, optional ) + case Schema.NonEmptyMap(ks, vs, _) => + Dictionary( + keys = subtree(path / "keys", Lineage.empty, ks, optional = false), + values = subtree(path / "values", Lineage.empty, vs, optional = false), + path, + optional + ) case Schema.Set(schema @ _, _) => ListNode(item = subtree(path / "item", lineage, schema, optional = false), path, optional) case Schema.Transform(schema, _, _, _, _) => subtree(path, lineage, schema, optional) From ce8cca1a137db61cf1ecea9a66a900795bdc34e6 Mon Sep 17 00:00:00 2001 From: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com> Date: Thu, 15 Aug 2024 00:21:27 +0200 Subject: [PATCH 15/15] Don't write null for empty option fields of generic records (#728) --- .../shared/src/main/scala/zio/schema/codec/JsonCodec.scala | 1 + .../shared/src/test/scala/zio/schema/codec/JsonCodecSpec.scala | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala index 93e9113ac..9eecca635 100644 --- a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala +++ b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala @@ -945,6 +945,7 @@ object JsonCodec { val isEmptyCollection = value match { case _: Iterable[_] => value.asInstanceOf[Iterable[_]].isEmpty + case None => true case _ => false } diff --git a/zio-schema-json/shared/src/test/scala/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala/zio/schema/codec/JsonCodecSpec.scala index c5222c89a..7bdeabc08 100644 --- a/zio-schema-json/shared/src/test/scala/zio/schema/codec/JsonCodecSpec.scala +++ b/zio-schema-json/shared/src/test/scala/zio/schema/codec/JsonCodecSpec.scala @@ -423,7 +423,7 @@ object JsonCodecSpec extends ZIOSpecDefault { RecordExample.schema.annotate(rejectExtraFields()), RecordExample(f1 = Some("test"), f3 = Some("transient")), charSequenceToByteChunk( - """{"$f1":"test","f2":null,"f4":null,"f5":null,"f6":null,"f7":null,"f8":null,"f9":null,"f10":null,"f11":null,"f12":null,"f13":null,"f14":null,"f15":null,"f16":null,"f17":null,"f18":null,"f19":null,"f20":null,"f21":null,"f22":null,"$f23":null}""".stripMargin + """{"$f1":"test"}""".stripMargin ) ) }