From 63f2e01fca37b734c1a7f5136b83b93dcb2af807 Mon Sep 17 00:00:00 2001 From: Thijs Broersen Date: Sat, 16 Nov 2024 20:49:21 +0100 Subject: [PATCH] fmt and fix all --- .../scala/zio/json/golden/filehelpers.scala | 8 +- .../main/scala/zio/json/golden/package.scala | 11 +- .../zio/json/interop/refined/package.scala | 2 +- .../src/main/scala/zio/json/jsonDerive.scala | 3 +- .../scala/zio/json/yaml/YamlOptions.scala | 6 +- .../yaml/internal/YamlValueConstruction.scala | 2 +- .../main/scala/zio/json/yaml/package.scala | 2 +- .../zio/json/GoogleMapsAPIBenchmarks.scala | 4 +- .../scala/zio/json/SyntheticBenchmarks.scala | 2 +- .../json/internal/SafeNumbersBenchmarks.scala | 6 +- .../json/JsonDecoderPlatformSpecific.scala | 14 +- .../json/DecoderPlatformSpecificSpec.scala | 4 +- .../json/EncoderPlatformSpecificSpec.scala | 4 +- .../src/test/scala/zio/json/TestUtils.scala | 6 +- .../zio/json/internal/SafeNumbersSpec.scala | 3 +- .../zio/json/internal/StringMatrixSpec.scala | 6 +- .../src/main/scala-2.x/zio/json/macros.scala | 74 ++-- .../zio/json/JsonDecoderVersionSpecific.scala | 10 +- .../scala-3/zio/json/union_derivation.scala | 2 +- .../src/main/scala/zio/json/JsonCodec.scala | 15 +- .../src/main/scala/zio/json/JsonDecoder.scala | 45 ++- .../src/main/scala/zio/json/JsonEncoder.scala | 38 +- .../src/main/scala/zio/json/JsonError.scala | 4 +- .../src/main/scala/zio/json/ast/ast.scala | 61 +-- .../scala/zio/json/codegen/Generator.scala | 5 +- .../main/scala/zio/json/internal/lexer.scala | 2 +- .../scala/zio/json/internal/numbers.scala | 353 +++++++++--------- .../scala/zio/json/internal/readers.scala | 15 +- .../scala/zio/json/javatime/serializers.scala | 6 +- .../src/main/scala/zio/json/package.scala | 8 +- .../json/ConfigurableDeriveCodecSpec.scala | 3 +- .../scala-3/zio/json/DerivedCodecSpec.scala | 2 +- .../scala-3/zio/json/DerivedDecoderSpec.scala | 6 +- .../src/test/scala/zio/json/CodecSpec.scala | 3 +- .../shared/src/test/scala/zio/json/Gens.scala | 43 +-- .../zio/json/codegen/GeneratorSpec.scala | 3 +- 36 files changed, 378 insertions(+), 403 deletions(-) diff --git a/zio-json-golden/src/main/scala/zio/json/golden/filehelpers.scala b/zio-json-golden/src/main/scala/zio/json/golden/filehelpers.scala index 21a57da4b..b6303877d 100644 --- a/zio-json-golden/src/main/scala/zio/json/golden/filehelpers.scala +++ b/zio-json-golden/src/main/scala/zio/json/golden/filehelpers.scala @@ -1,13 +1,11 @@ package zio.json.golden -import java.io.{ File, IOException } -import java.nio.file.{ Path } -import zio.{ test => _, _ } import zio.json._ - import zio.stacktracer.TracingImplicits.disableAutoTrace +import zio.{ test => _, _ } -import java.nio.file.Files +import java.io.{ File, IOException } +import java.nio.file.{ Files, Path } object filehelpers { diff --git a/zio-json-golden/src/main/scala/zio/json/golden/package.scala b/zio-json-golden/src/main/scala/zio/json/golden/package.scala index 8bdf6aec8..954c38690 100644 --- a/zio-json-golden/src/main/scala/zio/json/golden/package.scala +++ b/zio-json-golden/src/main/scala/zio/json/golden/package.scala @@ -1,17 +1,14 @@ package zio.json -import scala.annotation.nowarn - -import zio.Tag -import zio.{ test => _, _ } +import zio.json.ast._ import zio.json.golden.filehelpers._ import zio.stacktracer.TracingImplicits.disableAutoTrace import zio.test._ -import zio.test.diff._ import zio.test.diff.Diff._ -import java.nio.file.{ Paths, Path, Files } +import zio.test.diff._ +import zio.{ Tag, test => _, _ } -import zio.json.ast._ +import java.nio.file.{ Files, Path, Paths } package object golden { diff --git a/zio-json-interop-refined/shared/src/main/scala/zio/json/interop/refined/package.scala b/zio-json-interop-refined/shared/src/main/scala/zio/json/interop/refined/package.scala index ba558edc8..65d874923 100644 --- a/zio-json-interop-refined/shared/src/main/scala/zio/json/interop/refined/package.scala +++ b/zio-json-interop-refined/shared/src/main/scala/zio/json/interop/refined/package.scala @@ -1,7 +1,7 @@ package zio.json.interop import eu.timepit.refined.api.{ Refined, Validate } -import eu.timepit.refined.{ refineV } +import eu.timepit.refined.refineV import zio.json._ package object refined { diff --git a/zio-json-macros/shared/src/main/scala/zio/json/jsonDerive.scala b/zio-json-macros/shared/src/main/scala/zio/json/jsonDerive.scala index 8c35c9994..ed7dc1f80 100644 --- a/zio-json-macros/shared/src/main/scala/zio/json/jsonDerive.scala +++ b/zio-json-macros/shared/src/main/scala/zio/json/jsonDerive.scala @@ -74,12 +74,11 @@ private[json] final class DeriveCodecMacros(val c: blackbox.Context) { private[this] val EncoderClass = typeOf[JsonEncoder[_]].typeSymbol.asType private[this] val CodecClass = typeOf[JsonCodec[_]].typeSymbol.asType - private[this] val macroName: Tree = { + private[this] val macroName: Tree = c.prefix.tree match { case Apply(Select(New(name), _), _) => name case _ => c.abort(c.enclosingPosition, "Unexpected macro application") } - } private[this] val (codecStyle: JsonCodecStyle, codecType: JsonCodecType) = { val style: JsonCodecStyle = macroName match { diff --git a/zio-json-yaml/src/main/scala/zio/json/yaml/YamlOptions.scala b/zio-json-yaml/src/main/scala/zio/json/yaml/YamlOptions.scala index df4940b46..238316069 100644 --- a/zio-json-yaml/src/main/scala/zio/json/yaml/YamlOptions.scala +++ b/zio-json-yaml/src/main/scala/zio/json/yaml/YamlOptions.scala @@ -1,8 +1,7 @@ package zio.json.yaml -import org.yaml.snakeyaml.DumperOptions.{ FlowStyle, LineBreak, NonPrintableStyle, ScalarStyle } import org.yaml.snakeyaml.DumperOptions - +import org.yaml.snakeyaml.DumperOptions.{ FlowStyle, LineBreak, NonPrintableStyle, ScalarStyle } import zio.json.ast.Json case class YamlOptions( @@ -20,11 +19,10 @@ case class YamlOptions( ) object YamlOptions { - private val defaultLineBreak: LineBreak = { + private val defaultLineBreak: LineBreak = Set(LineBreak.MAC, LineBreak.WIN, LineBreak.UNIX) .find(_.getString == System.lineSeparator()) .getOrElse(LineBreak.UNIX) - } val default: YamlOptions = YamlOptions( () => new DumperOptions(), diff --git a/zio-json-yaml/src/main/scala/zio/json/yaml/internal/YamlValueConstruction.scala b/zio-json-yaml/src/main/scala/zio/json/yaml/internal/YamlValueConstruction.scala index af34ded1a..724f67484 100644 --- a/zio-json-yaml/src/main/scala/zio/json/yaml/internal/YamlValueConstruction.scala +++ b/zio-json-yaml/src/main/scala/zio/json/yaml/internal/YamlValueConstruction.scala @@ -1,8 +1,8 @@ package zio.json.yaml.internal +import org.yaml.snakeyaml.LoaderOptions import org.yaml.snakeyaml.constructor.SafeConstructor import org.yaml.snakeyaml.nodes.{ MappingNode, Node } -import org.yaml.snakeyaml.LoaderOptions private[yaml] final class YamlValueConstruction extends SafeConstructor(new LoaderOptions()) { def toJavaValue(node: Node): AnyRef = diff --git a/zio-json-yaml/src/main/scala/zio/json/yaml/package.scala b/zio-json-yaml/src/main/scala/zio/json/yaml/package.scala index a82339fd2..48f31c936 100644 --- a/zio-json-yaml/src/main/scala/zio/json/yaml/package.scala +++ b/zio-json-yaml/src/main/scala/zio/json/yaml/package.scala @@ -1,13 +1,13 @@ package zio.json import org.yaml.snakeyaml.DumperOptions.{ NonPrintableStyle, ScalarStyle } +import org.yaml.snakeyaml.Yaml import org.yaml.snakeyaml.emitter.Emitter import org.yaml.snakeyaml.error.YAMLException import org.yaml.snakeyaml.nodes.{ ScalarNode, _ } import org.yaml.snakeyaml.reader.StreamReader import org.yaml.snakeyaml.resolver.Resolver import org.yaml.snakeyaml.serializer._ -import org.yaml.snakeyaml.Yaml import zio.Chunk import zio.json.ast.Json import zio.json.yaml.internal.YamlValueConstruction diff --git a/zio-json/jvm/src/jmh/scala/zio/json/GoogleMapsAPIBenchmarks.scala b/zio-json/jvm/src/jmh/scala/zio/json/GoogleMapsAPIBenchmarks.scala index 277455ad1..d8e994145 100644 --- a/zio-json/jvm/src/jmh/scala/zio/json/GoogleMapsAPIBenchmarks.scala +++ b/zio-json/jvm/src/jmh/scala/zio/json/GoogleMapsAPIBenchmarks.scala @@ -62,8 +62,8 @@ class GoogleMapsAPIBenchmarks { @Setup def setup(): Unit = { - //Distance Matrix API call for top-10 by population cities in US: - //https://maps.googleapis.com/maps/api/distancematrix/json?origins=New+York|Los+Angeles|Chicago|Houston|Phoenix+AZ|Philadelphia|San+Antonio|San+Diego|Dallas|San+Jose&destinations=New+York|Los+Angeles|Chicago|Houston|Phoenix+AZ|Philadelphia|San+Antonio|San+Diego|Dallas|San+Jose + // Distance Matrix API call for top-10 by population cities in US: + // https://maps.googleapis.com/maps/api/distancematrix/json?origins=New+York|Los+Angeles|Chicago|Houston|Phoenix+AZ|Philadelphia|San+Antonio|San+Diego|Dallas|San+Jose&destinations=New+York|Los+Angeles|Chicago|Houston|Phoenix+AZ|Philadelphia|San+Antonio|San+Diego|Dallas|San+Jose jsonString = getResourceAsString("google_maps_api_response.json") jsonChars = asChars(jsonString) jsonStringCompact = getResourceAsString( diff --git a/zio-json/jvm/src/jmh/scala/zio/json/SyntheticBenchmarks.scala b/zio-json/jvm/src/jmh/scala/zio/json/SyntheticBenchmarks.scala index 26e2ddaad..1f04cd89c 100644 --- a/zio-json/jvm/src/jmh/scala/zio/json/SyntheticBenchmarks.scala +++ b/zio-json/jvm/src/jmh/scala/zio/json/SyntheticBenchmarks.scala @@ -38,7 +38,7 @@ object Nested { @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) @Fork(value = 1) class SyntheticBenchmarks { - //@Param(Array("100", "1000")) + // @Param(Array("100", "1000")) var size: Int = 500 var jsonString: String = _ var jsonChars: CharSequence = _ diff --git a/zio-json/jvm/src/jmh/scala/zio/json/internal/SafeNumbersBenchmarks.scala b/zio-json/jvm/src/jmh/scala/zio/json/internal/SafeNumbersBenchmarks.scala index 624f8827d..18bf3a5a0 100644 --- a/zio-json/jvm/src/jmh/scala/zio/json/internal/SafeNumbersBenchmarks.scala +++ b/zio-json/jvm/src/jmh/scala/zio/json/internal/SafeNumbersBenchmarks.scala @@ -10,7 +10,7 @@ import org.openjdk.jmh.annotations._ @Fork(value = 1) class SafeNumbersBenchInt { - //@Param(Array("100", "1000")) + // @Param(Array("100", "1000")) var size: Int = 10000 // invalid input. e.g. out of range longs @@ -69,7 +69,7 @@ class SafeNumbersBenchInt { @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) @Fork(value = 1) class SafeNumbersBenchFloat { - //@Param(Array("100", "1000")) + // @Param(Array("100", "1000")) var size: Int = 10000 var invalids: Array[String] = _ @@ -135,7 +135,7 @@ class SafeNumbersBenchFloat { @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) @Fork(value = 1) class SafeNumbersBenchBigDecimal { - //@Param(Array("100", "1000")) + // @Param(Array("100", "1000")) var size: Int = 10000 var invalids: Array[String] = _ diff --git a/zio-json/jvm/src/main/scala/zio/json/JsonDecoderPlatformSpecific.scala b/zio-json/jvm/src/main/scala/zio/json/JsonDecoderPlatformSpecific.scala index 11da0dbfd..7e442f983 100644 --- a/zio-json/jvm/src/main/scala/zio/json/JsonDecoderPlatformSpecific.scala +++ b/zio-json/jvm/src/main/scala/zio/json/JsonDecoderPlatformSpecific.scala @@ -20,12 +20,13 @@ trait JsonDecoderPlatformSpecific[A] { self: JsonDecoder[A] => } /** - * Attempts to decode a stream of bytes using the user supplied Charset into a single value of type `A`, but may fail with - * a human-readable exception if the stream does not encode a value of this type. + * Attempts to decode a stream of bytes using the user supplied Charset into a single value of type `A`, but may fail + * with a human-readable exception if the stream does not encode a value of this type. * * Note: This method may not consume the full string. * - * @see [[decodeJsonStream]] For a `Char` stream variant + * @see + * [[decodeJsonStream]] For a `Char` stream variant */ final def decodeJsonStreamInput[R]( stream: ZStream[R, Throwable, Byte], @@ -41,12 +42,13 @@ trait JsonDecoderPlatformSpecific[A] { self: JsonDecoder[A] => } /** - * Attempts to decode a stream of characters into a single value of type `A`, but may fail with - * a human-readable exception if the stream does not encode a value of this type. + * Attempts to decode a stream of characters into a single value of type `A`, but may fail with a human-readable + * exception if the stream does not encode a value of this type. * * Note: This method may not consume the full string. * - * @see also [[decodeJsonStreamInput]] + * @see + * also [[decodeJsonStreamInput]] */ final def decodeJsonStream[R](stream: ZStream[R, Throwable, Char]): ZIO[R, Throwable, A] = ZIO.scoped[R](stream.toReader.flatMap(readAll)) diff --git a/zio-json/jvm/src/test/scala-2/zio/json/DecoderPlatformSpecificSpec.scala b/zio-json/jvm/src/test/scala-2/zio/json/DecoderPlatformSpecificSpec.scala index 4654e418c..5966849fc 100644 --- a/zio-json/jvm/src/test/scala-2/zio/json/DecoderPlatformSpecificSpec.scala +++ b/zio-json/jvm/src/test/scala-2/zio/json/DecoderPlatformSpecificSpec.scala @@ -18,7 +18,7 @@ import java.nio.file.Paths object DecoderPlatformSpecificSpec extends ZIOSpecDefault { - val spec = + val spec: Spec[Annotations with Live with Sized with TestConfig, Throwable] = suite("Decoder")( test("excessively nested structures") { // JVM specific: getResourceAsString not yet supported @@ -273,7 +273,7 @@ object DecoderPlatformSpecificSpec extends ZIOSpecDefault { ) ) - def testAst(label: String) = + def testAst(label: String): Spec[Any, Throwable] = test(label) { getResourceAsStringM(s"jawn/$label.json").flatMap { input => val expected = jawn.JParser.parseFromString(input).toEither.map(fromJawn) diff --git a/zio-json/jvm/src/test/scala-2/zio/json/EncoderPlatformSpecificSpec.scala b/zio-json/jvm/src/test/scala-2/zio/json/EncoderPlatformSpecificSpec.scala index 7479e378b..59e0cd6e8 100644 --- a/zio-json/jvm/src/test/scala-2/zio/json/EncoderPlatformSpecificSpec.scala +++ b/zio-json/jvm/src/test/scala-2/zio/json/EncoderPlatformSpecificSpec.scala @@ -9,7 +9,7 @@ import zio.Chunk import zio.json.ast.Json import zio.stream.{ ZSink, ZStream } import zio.test.Assertion._ -import zio.test.{ ZIOSpecDefault, assert, _ } +import zio.test.{ Spec, ZIOSpecDefault, assert, _ } import java.io.IOException import java.nio.file.Files @@ -17,7 +17,7 @@ import java.nio.file.Files object EncoderPlatformSpecificSpec extends ZIOSpecDefault { import testzio.json.DecoderSpec.logEvent._ - val spec = + val spec: Spec[Any, Throwable] = suite("Encoder")( suite("roundtrip")( testRoundTrip[DistanceMatrix]("google_maps_api_response"), diff --git a/zio-json/jvm/src/test/scala/zio/json/TestUtils.scala b/zio-json/jvm/src/test/scala/zio/json/TestUtils.scala index e96cfdae7..498fc9cc2 100644 --- a/zio-json/jvm/src/test/scala/zio/json/TestUtils.scala +++ b/zio-json/jvm/src/test/scala/zio/json/TestUtils.scala @@ -15,9 +15,9 @@ object TestUtils { def getResourceAsString(res: String): String = { val is = getClass.getClassLoader.getResourceAsStream(res) try { - val baos = new java.io.ByteArrayOutputStream() - val data = Array.ofDim[Byte](2048) - var len: Int = 0 + val baos = new java.io.ByteArrayOutputStream() + val data = Array.ofDim[Byte](2048) + var len: Int = 0 def read(): Int = { len = is.read(data); len } while (read() != -1) baos.write(data, 0, len) diff --git a/zio-json/jvm/src/test/scala/zio/json/internal/SafeNumbersSpec.scala b/zio-json/jvm/src/test/scala/zio/json/internal/SafeNumbersSpec.scala index 41f184676..afa680ba8 100644 --- a/zio-json/jvm/src/test/scala/zio/json/internal/SafeNumbersSpec.scala +++ b/zio-json/jvm/src/test/scala/zio/json/internal/SafeNumbersSpec.scala @@ -1,12 +1,13 @@ package testzio.json.internal import testzio.json.Gens._ +import zio.Scope import zio.json.internal._ import zio.test.Assertion._ import zio.test._ object SafeNumbersSpec extends ZIOSpecDefault { - val spec = + val spec: Spec[Environment with TestEnvironment with Scope, Any] = suite("SafeNumbers")( test("valid big decimals") { check(genBigDecimal)(i => assert(SafeNumbers.bigDecimal(i.toString, 2048))(isSome(equalTo(i)))) diff --git a/zio-json/jvm/src/test/scala/zio/json/internal/StringMatrixSpec.scala b/zio-json/jvm/src/test/scala/zio/json/internal/StringMatrixSpec.scala index 8ae865a76..1b57d100d 100644 --- a/zio-json/jvm/src/test/scala/zio/json/internal/StringMatrixSpec.scala +++ b/zio-json/jvm/src/test/scala/zio/json/internal/StringMatrixSpec.scala @@ -110,16 +110,16 @@ object StringMatrixSpec extends ZIOSpecDefault { } ) - val genNonEmptyString = + val genNonEmptyString: Gen[Any, String] = Gen.alphaNumericString.filter(_.nonEmpty) - val genTestStrings = + val genTestStrings: Gen[Any, List[String]] = for { n <- Gen.int(1, 63) xs <- Gen.setOfN(n)(genNonEmptyString) } yield xs.toList - val genTestStringsAndAliases = + val genTestStringsAndAliases: Gen[Any, (List[String], List[(String, Int)])] = for { xsn <- Gen.int(1, 63) xs <- Gen.setOfN(xsn)(genNonEmptyString) diff --git a/zio-json/shared/src/main/scala-2.x/zio/json/macros.scala b/zio-json/shared/src/main/scala-2.x/zio/json/macros.scala index 42fffbb92..41ce81556 100644 --- a/zio-json/shared/src/main/scala-2.x/zio/json/macros.scala +++ b/zio-json/shared/src/main/scala-2.x/zio/json/macros.scala @@ -12,8 +12,7 @@ import scala.annotation._ import scala.language.experimental.macros /** - * If used on a case class field, determines the name of the JSON field. - * Defaults to the case class field name. + * If used on a case class field, determines the name of the JSON field. Defaults to the case class field name. */ final case class jsonField(name: String) extends Annotation @@ -25,17 +24,14 @@ final case class jsonAliases(alias: String, aliases: String*) extends Annotation final class jsonExplicitNull extends Annotation /** - * If used on a sealed class, will determine the name of the field for - * disambiguating classes. + * If used on a sealed class, will determine the name of the field for disambiguating classes. * - * The default is to not use a typehint field and instead - * have an object with a single key that is the class name. + * The default is to not use a typehint field and instead have an object with a single key that is the class name. * - * Note that using a discriminator is less performant, uses more memory, and may - * be prone to DOS attacks that are impossible with the default encoding. In - * addition, there is slightly less type safety when using custom product - * encoders (which must write an unenforced object type). Only use this option - * if you must model an externally defined schema. + * Note that using a discriminator is less performant, uses more memory, and may be prone to DOS attacks that are + * impossible with the default encoding. In addition, there is slightly less type safety when using custom product + * encoders (which must write an unenforced object type). Only use this option if you must model an externally defined + * schema. */ final case class jsonDiscriminator(name: String) extends Annotation // TODO a strategy where the constructor is inferred from the field names, only @@ -80,16 +76,14 @@ object ziojson_03 { } /** - * If used on a case class, determines the strategy of member names - * transformation during serialization and deserialization. Four common - * strategies are provided above and a custom one to support specific use cases. + * If used on a case class, determines the strategy of member names transformation during serialization and + * deserialization. Four common strategies are provided above and a custom one to support specific use cases. */ final case class jsonMemberNames(format: JsonMemberFormat) extends Annotation private[json] object jsonMemberNames { /** - * ~~Stolen~~ Borrowed from jsoniter-scala by Andriy Plokhotnyuk - * (he even granted permission for this, imagine that!) + * ~~Stolen~~ Borrowed from jsoniter-scala by Andriy Plokhotnyuk (he even granted permission for this, imagine that!) */ import java.lang.Character._ @@ -172,27 +166,26 @@ private[json] object jsonMemberNames { } /** - * If used on a case class will determine the type hint value for disambiguating - * sealed traits. Defaults to the short type name. + * If used on a case class will determine the type hint value for disambiguating sealed traits. Defaults to the short + * type name. */ final case class jsonHint(name: String) extends Annotation /** - * If used on a sealed class will determine the strategy of type hint value transformation for disambiguating - * classes during serialization and deserialization. Same strategies are provided as for [[jsonMemberNames]]. + * If used on a sealed class will determine the strategy of type hint value transformation for disambiguating classes + * during serialization and deserialization. Same strategies are provided as for [[jsonMemberNames]]. */ final case class jsonHintNames(format: JsonMemberFormat) extends Annotation /** - * If used on a case class, will exit early if any fields are in the JSON that - * do not correspond to field names in the case class. + * If used on a case class, will exit early if any fields are in the JSON that do not correspond to field names in the + * case class. * - * This adds extra protections against a DOS attacks but means that changes in - * the schema will result in a hard error rather than silently ignoring those - * fields. + * This adds extra protections against a DOS attacks but means that changes in the schema will result in a hard error + * rather than silently ignoring those fields. * - * Cannot be combined with `@jsonDiscriminator` since it is considered an extra - * field from the perspective of the case class. + * Cannot be combined with `@jsonDiscriminator` since it is considered an extra field from the perspective of the case + * class. */ final class jsonNoExtraFields extends Annotation @@ -205,10 +198,14 @@ final class jsonExclude extends Annotation /** * Implicit codec derivation configuration. * - * @param sumTypeHandling see [[jsonDiscriminator]] - * @param fieldNameMapping see [[jsonMemberNames]] - * @param allowExtraFields see [[jsonNoExtraFields]] - * @param sumTypeMapping see [[jsonHintNames]] + * @param sumTypeHandling + * see [[jsonDiscriminator]] + * @param fieldNameMapping + * see [[jsonMemberNames]] + * @param allowExtraFields + * see [[jsonNoExtraFields]] + * @param sumTypeMapping + * see [[jsonHintNames]] */ final case class JsonCodecConfiguration( sumTypeHandling: SumTypeHandling = WrapperWithClassNameField, @@ -235,18 +232,15 @@ object JsonCodecConfiguration { } /** - * For sealed classes, will determine the name of the field for - * disambiguating classes. + * For sealed classes, will determine the name of the field for disambiguating classes. * - * The default is to not use a typehint field and instead - * have an object with a single key that is the class name. + * The default is to not use a typehint field and instead have an object with a single key that is the class name. * See [[WrapperWithClassNameField]]. * - * Note that using a discriminator is less performant, uses more memory, and may - * be prone to DOS attacks that are impossible with the default encoding. In - * addition, there is slightly less type safety when using custom product - * encoders (which must write an unenforced object type). Only use this option - * if you must model an externally defined schema. + * Note that using a discriminator is less performant, uses more memory, and may be prone to DOS attacks that are + * impossible with the default encoding. In addition, there is slightly less type safety when using custom product + * encoders (which must write an unenforced object type). Only use this option if you must model an externally + * defined schema. */ final case class DiscriminatorField(name: String) extends SumTypeHandling { override def discriminatorField: Option[String] = Some(name) diff --git a/zio-json/shared/src/main/scala-3/zio/json/JsonDecoderVersionSpecific.scala b/zio-json/shared/src/main/scala-3/zio/json/JsonDecoderVersionSpecific.scala index ad020b005..6f87ed6e5 100644 --- a/zio-json/shared/src/main/scala-3/zio/json/JsonDecoderVersionSpecific.scala +++ b/zio-json/shared/src/main/scala-3/zio/json/JsonDecoderVersionSpecific.scala @@ -11,10 +11,8 @@ trait DecoderLowPriorityVersionSpecific { inline given unionOfStringEnumeration[T](using IsUnionOf[String, T]): JsonDecoder[T] = val values = UnionDerivation.constValueUnionTuple[String, T] - JsonDecoder.string.mapOrFail( - { - case raw if values.toList.contains(raw) => Right(raw.asInstanceOf[T]) - case _ => Left("expected one of: " + values.toList.mkString(", ")) - } - ) + JsonDecoder.string.mapOrFail { + case raw if values.toList.contains(raw) => Right(raw.asInstanceOf[T]) + case _ => Left("expected one of: " + values.toList.mkString(", ")) + } } diff --git a/zio-json/shared/src/main/scala-3/zio/json/union_derivation.scala b/zio-json/shared/src/main/scala-3/zio/json/union_derivation.scala index c260f472c..e733473eb 100644 --- a/zio-json/shared/src/main/scala-3/zio/json/union_derivation.scala +++ b/zio-json/shared/src/main/scala-3/zio/json/union_derivation.scala @@ -15,7 +15,7 @@ private[json] object IsUnionOf: private def deriveImpl[T, A](using quotes: Quotes, t: Type[T], a: Type[A]): Expr[IsUnionOf[T, A]] = import quotes.reflect.* - val tpe: TypeRepr = TypeRepr.of[A] + val tpe: TypeRepr = TypeRepr.of[A] val bound: TypeRepr = TypeRepr.of[T] def validateTypes(tpe: TypeRepr): Unit = diff --git a/zio-json/shared/src/main/scala/zio/json/JsonCodec.scala b/zio-json/shared/src/main/scala/zio/json/JsonCodec.scala index 32e3c53ec..25d368f73 100644 --- a/zio-json/shared/src/main/scala/zio/json/JsonCodec.scala +++ b/zio-json/shared/src/main/scala/zio/json/JsonCodec.scala @@ -20,20 +20,17 @@ import zio.{ Chunk, NonEmptyChunk } import scala.collection.immutable /** - * A `JsonCodec[A]` instance has the ability to encode values of type `A` into JSON, together with - * the ability to decode such JSON into values of type `A`. + * A `JsonCodec[A]` instance has the ability to encode values of type `A` into JSON, together with the ability to decode + * such JSON into values of type `A`. * - * Instances of this trait should satisfy round-tripping laws: that is, for every value, instances - * must be able to successfully encode the value into JSON, and then successfully decode the same - * value from such JSON. + * Instances of this trait should satisfy round-tripping laws: that is, for every value, instances must be able to + * successfully encode the value into JSON, and then successfully decode the same value from such JSON. * * For more information, see [[JsonDecoder]] and [[JsonEncoder]]. * - * {{ - * val intCodec: JsonCodec[Int] = JsonCodec[Int] + * {{ val intCodec: JsonCodec[Int] = JsonCodec[Int] * - * intCodec.encodeJson(intCodec.encodeJson(42)) == Right(42) - * }} + * intCodec.encodeJson(intCodec.encodeJson(42)) == Right(42) }} */ final case class JsonCodec[A](encoder: JsonEncoder[A], decoder: JsonDecoder[A]) { self => diff --git a/zio-json/shared/src/main/scala/zio/json/JsonDecoder.scala b/zio-json/shared/src/main/scala/zio/json/JsonDecoder.scala index 5be8a54ec..7e24886c3 100644 --- a/zio-json/shared/src/main/scala/zio/json/JsonDecoder.scala +++ b/zio-json/shared/src/main/scala/zio/json/JsonDecoder.scala @@ -28,8 +28,8 @@ import scala.collection.{ immutable, mutable } import scala.util.control.NoStackTrace /** - * A `JsonDecoder[A]` instance has the ability to decode JSON to values of type `A`, potentially - * failing with an error if the JSON content does not encode a value of the given type. + * A `JsonDecoder[A]` instance has the ability to decode JSON to values of type `A`, potentially failing with an error + * if the JSON content does not encode a value of the given type. */ trait JsonDecoder[A] extends JsonDecoderPlatformSpecific[A] { self => @@ -60,8 +60,8 @@ trait JsonDecoder[A] extends JsonDecoderPlatformSpecific[A] { final def <*[B](that: => JsonDecoder[B]): JsonDecoder[A] = self.zipLeft(that) /** - * Attempts to decode a value of type `A` from the specified `CharSequence`, but may fail with - * a human-readable error message if the provided text does not encode a value of this type. + * Attempts to decode a value of type `A` from the specified `CharSequence`, but may fail with a human-readable error + * message if the provided text does not encode a value of this type. * * Note: This method may not entirely consume the specified character sequence. */ @@ -79,13 +79,11 @@ trait JsonDecoder[A] extends JsonDecoderPlatformSpecific[A] { final def widen[B >: A]: JsonDecoder[B] = self.asInstanceOf[JsonDecoder[B]] /** - * Returns a new codec that combines this codec and the specified codec using fallback semantics: - * such that if this codec fails, the specified codec will be tried instead. - * This method may be unsafe from a security perspective: it can use more memory than hand coded - * alternative and so lead to DOS. + * Returns a new codec that combines this codec and the specified codec using fallback semantics: such that if this + * codec fails, the specified codec will be tried instead. This method may be unsafe from a security perspective: it + * can use more memory than hand coded alternative and so lead to DOS. * - * For example, in the case of an alternative between `Int` and `Boolean`, a hand coded - * alternative would look like: + * For example, in the case of an alternative between `Int` and `Boolean`, a hand coded alternative would look like: * * ``` * val decoder: JsonDecoder[AnyVal] = JsonDecoder.peekChar[AnyVal] { @@ -127,8 +125,8 @@ trait JsonDecoder[A] extends JsonDecoderPlatformSpecific[A] { } /** - * Returns a new codec that combines this codec and the specified codec using fallback semantics: - * such that if this codec fails, the specified codec will be tried instead. + * Returns a new codec that combines this codec and the specified codec using fallback semantics: such that if this + * codec fails, the specified codec will be tried instead. */ final def orElseEither[B](that: => JsonDecoder[B]): JsonDecoder[Either[A, B]] = self.map(Left(_)).orElse(that.map(Right(_))) @@ -151,8 +149,8 @@ trait JsonDecoder[A] extends JsonDecoderPlatformSpecific[A] { } /** - * Returns a new codec whose decoded values will be mapped by the specified function, which may - * itself decide to fail with some type of error. + * Returns a new codec whose decoded values will be mapped by the specified function, which may itself decide to fail + * with some type of error. */ final def mapOrFail[B](f: A => Either[String, B]): JsonDecoder[B] = new JsonDecoder[B] { @@ -180,8 +178,8 @@ trait JsonDecoder[A] extends JsonDecoderPlatformSpecific[A] { } /** - * Returns a new codec that combines this codec and the specified codec into a single codec that - * decodes a tuple of the values decoded by the respective codecs. + * Returns a new codec that combines this codec and the specified codec into a single codec that decodes a tuple of + * the values decoded by the respective codecs. */ final def zip[B](that: => JsonDecoder[B]): JsonDecoder[(A, B)] = JsonDecoder.tuple2(this, that) @@ -205,8 +203,8 @@ trait JsonDecoder[A] extends JsonDecoderPlatformSpecific[A] { throw JsonDecoder.UnsafeJson(JsonError.Message("missing") :: trace) /** - * Low-level, unsafe method to decode a value or throw an exception. This method should not be - * called in application code, although it can be implemented for user-defined data structures. + * Low-level, unsafe method to decode a value or throw an exception. This method should not be called in application + * code, although it can be implemented for user-defined data structures. */ def unsafeDecode(trace: List[JsonError], in: RetractReader): A @@ -216,8 +214,8 @@ trait JsonDecoder[A] extends JsonDecoderPlatformSpecific[A] { /** * Decode a value from an already parsed Json AST. * - * The default implementation encodes the Json to a byte stream and uses decode to parse that. - * Override to provide a more performant implementation. + * The default implementation encodes the Json to a byte stream and uses decode to parse that. Override to provide a + * more performant implementation. */ final def fromJsonAST(json: Json): Either[String, A] = try Right(unsafeFromJsonAST(Nil, json)) @@ -236,10 +234,9 @@ object JsonDecoder extends GeneratedTupleDecoders with DecoderLowPriority1 with def apply[A](implicit a: JsonDecoder[A]): JsonDecoder[A] = a /** - * Design note: we could require the position in the stream here to improve - * debugging messages. But the cost would be that the RetractReader would need - * to keep track and any wrappers would need to preserve the position. It may - * still be desirable to do this but at the moment it is not necessary. + * Design note: we could require the position in the stream here to improve debugging messages. But the cost would be + * that the RetractReader would need to keep track and any wrappers would need to preserve the position. It may still + * be desirable to do this but at the moment it is not necessary. */ final case class UnsafeJson(trace: List[JsonError]) extends Exception("If you see this, a developer made a mistake using JsonDecoder") diff --git a/zio-json/shared/src/main/scala/zio/json/JsonEncoder.scala b/zio-json/shared/src/main/scala/zio/json/JsonEncoder.scala index 7098a1b83..d49b178a4 100644 --- a/zio-json/shared/src/main/scala/zio/json/JsonEncoder.scala +++ b/zio-json/shared/src/main/scala/zio/json/JsonEncoder.scala @@ -29,8 +29,8 @@ trait JsonEncoder[A] extends JsonEncoderPlatformSpecific[A] { self => /** - * Returns a new encoder, with a new input type, which can be transformed to the old input type - * by the specified user-defined function. + * Returns a new encoder, with a new input type, which can be transformed to the old input type by the specified + * user-defined function. */ final def contramap[B](f: B => A): JsonEncoder[B] = new JsonEncoder[B] { @@ -44,25 +44,22 @@ trait JsonEncoder[A] extends JsonEncoderPlatformSpecific[A] { } /** - * Returns a new encoder that can accepts an `Either[A, B]` to either, and uses either this - * encoder or the specified encoder to encode the two different types of values. + * Returns a new encoder that can accepts an `Either[A, B]` to either, and uses either this encoder or the specified + * encoder to encode the two different types of values. */ final def either[B](that: => JsonEncoder[B]): JsonEncoder[Either[A, B]] = JsonEncoder.either[A, B](self, that) /** - * Returns a new encoder that can accepts an `Either[A, B]` to either, and uses either this - * encoder or the specified encoder to encode the two different types of values. - * The difference with the classic `either` encoder is that the resulting JSON has no field - * `Left` or `Right`. - * What should be: `{"Right": "John Doe"}` is encoded as `"John Doe"` + * Returns a new encoder that can accepts an `Either[A, B]` to either, and uses either this encoder or the specified + * encoder to encode the two different types of values. The difference with the classic `either` encoder is that the + * resulting JSON has no field `Left` or `Right`. What should be: `{"Right": "John Doe"}` is encoded as `"John Doe"` */ final def orElseEither[B](that: => JsonEncoder[B]): JsonEncoder[Either[A, B]] = JsonEncoder.orElseEither[A, B](self, that) /** - * Returns a new encoder with a new input type, which can be transformed to either the input - * type of this encoder, or the input type of the specified encoder, using the user-defined - * transformation function. + * Returns a new encoder with a new input type, which can be transformed to either the input type of this encoder, or + * the input type of the specified encoder, using the user-defined transformation function. */ final def eitherWith[B, C](that: => JsonEncoder[B])(f: C => Either[A, B]): JsonEncoder[C] = self.either(that).contramap(f) @@ -77,8 +74,7 @@ trait JsonEncoder[A] extends JsonEncoderPlatformSpecific[A] { } /** - * This default may be overridden when this value may be missing within a JSON object and still - * be encoded. + * This default may be overridden when this value may be missing within a JSON object and still be encoded. */ def isNothing(a: A): Boolean = false @@ -92,22 +88,20 @@ trait JsonEncoder[A] extends JsonEncoderPlatformSpecific[A] { /** * Converts a value to a Json AST * - * The default implementation encodes the value to a Json byte stream and - * uses decode to parse that back to an AST. Override to provide a more performant - * implementation. + * The default implementation encodes the value to a Json byte stream and uses decode to parse that back to an AST. + * Override to provide a more performant implementation. */ def toJsonAST(a: A): Either[String, Json] = Json.decoder.decodeJson(encodeJson(a, None)) /** - * Returns a new encoder that is capable of encoding a tuple containing the values of this - * encoder and the specified encoder. + * Returns a new encoder that is capable of encoding a tuple containing the values of this encoder and the specified + * encoder. */ final def zip[B](that: => JsonEncoder[B]): JsonEncoder[(A, B)] = JsonEncoder.tuple2(self, that) /** - * Returns a new encoder that is capable of encoding a user-defined value, which is create from - * a tuple of the values of this encoder and the specified encoder, from the specified user- - * defined function. + * Returns a new encoder that is capable of encoding a user-defined value, which is create from a tuple of the values + * of this encoder and the specified encoder, from the specified user- defined function. */ final def zipWith[B, C](that: => JsonEncoder[B])(f: C => (A, B)): JsonEncoder[C] = self.zip(that).contramap(f) } diff --git a/zio-json/shared/src/main/scala/zio/json/JsonError.scala b/zio-json/shared/src/main/scala/zio/json/JsonError.scala index b9525ad06..f82ded949 100644 --- a/zio-json/shared/src/main/scala/zio/json/JsonError.scala +++ b/zio-json/shared/src/main/scala/zio/json/JsonError.scala @@ -16,8 +16,8 @@ package zio.json /** - * A `JsonError` value describes the ways in which decoding could fail. This structure is used - * to facilitate human-readable error messages during decoding failures. + * A `JsonError` value describes the ways in which decoding could fail. This structure is used to facilitate + * human-readable error messages during decoding failures. */ sealed abstract class JsonError diff --git a/zio-json/shared/src/main/scala/zio/json/ast/ast.scala b/zio-json/shared/src/main/scala/zio/json/ast/ast.scala index 694d95ae1..a1f44f21a 100644 --- a/zio-json/shared/src/main/scala/zio/json/ast/ast.scala +++ b/zio-json/shared/src/main/scala/zio/json/ast/ast.scala @@ -24,19 +24,15 @@ import zio.json.internal._ import scala.annotation._ /** - * This AST of JSON is made available so that arbitrary JSON may be included as - * part of a business object, it is not used as an intermediate representation, - * unlike most other JSON libraries. It is not advised to `.map` or `.mapOrFail` + * This AST of JSON is made available so that arbitrary JSON may be included as part of a business object, it is not + * used as an intermediate representation, unlike most other JSON libraries. It is not advised to `.map` or `.mapOrFail` * from these decoders, since a higher performance decoder is often available. * - * Beware of the potential for DOS attacks, since an attacker can provide much - * more data than is perhaps needed. + * Beware of the potential for DOS attacks, since an attacker can provide much more data than is perhaps needed. * - * Also beware of converting `Num` (a `BigDecimal`) into any other kind of - * number, since many of the stdlib functions are non-total or are known DOS - * vectors (e.g. calling `.toBigInteger` on a "1e214748364" will consume an - * excessive amount of heap memory). - * JsonValue / Json / JValue + * Also beware of converting `Num` (a `BigDecimal`) into any other kind of number, since many of the stdlib functions + * are non-total or are known DOS vectors (e.g. calling `.toBigInteger` on a "1e214748364" will consume an excessive + * amount of heap memory). JsonValue / Json / JValue */ sealed abstract class Json { self => final def as[A](implicit decoder: JsonDecoder[A]): Either[String, A] = decoder.fromJsonAST(self) @@ -70,8 +66,10 @@ sealed abstract class Json { self => /** * Deletes json node specified by given cursor - * @param cursor Cursor which specifies node to delete - * @return Json without specified node if node specified by cursor exists, error otherwise + * @param cursor + * Cursor which specifies node to delete + * @return + * Json without specified node if node specified by cursor exists, error otherwise */ final def delete(cursor: JsonCursor[_, _]): Either[String, Json] = { val c = cursor.asInstanceOf[JsonCursor[_, Json]] @@ -189,10 +187,11 @@ sealed abstract class Json { self => } /** - * Intersects JSON values. If both values are `Obj` or `Arr` method returns intersections of its fields/elements, otherwise - * it returns error + * Intersects JSON values. If both values are `Obj` or `Arr` method returns intersections of its fields/elements, + * otherwise it returns error * @param that - * @return Intersected json if type are compatible, error otherwise + * @return + * Intersected json if type are compatible, error otherwise */ final def intersect(that: Json): Either[String, Json] = (self, that) match { @@ -204,12 +203,12 @@ sealed abstract class Json { self => } /** - * - merging objects results in a new objects with all pairs of both sides, with the right hand - * side being used on key conflicts + * - merging objects results in a new objects with all pairs of both sides, with the right hand side being used on + * key conflicts * - * - merging arrays results in all of the individual elements being merged + * - merging arrays results in all of the individual elements being merged * - * - scalar values will be replaced by the right hand side + * - scalar values will be replaced by the right hand side */ final def merge(that: Json): Json = (self, that) match { @@ -221,10 +220,14 @@ sealed abstract class Json { self => /** * Relocates Json node from location specified by `from` cursor to location specified by `to` cursor. * - * @param from Cursor which specifies node to relocate - * @return Json without specified node if node specified by cursor exists, error otherwise - * @param to Cursor which specifies location where to relocate node - * @return Json with relocated node if node specified by cursors exist, error otherwise + * @param from + * Cursor which specifies node to relocate + * @return + * Json without specified node if node specified by cursor exists, error otherwise + * @param to + * Cursor which specifies location where to relocate node + * @return + * Json with relocated node if node specified by cursors exist, error otherwise */ final def relocate(from: JsonCursor[_, _], to: JsonCursor[_, _]): Either[String, Json] = { val f = from.asInstanceOf[JsonCursor[_, Json]] @@ -234,10 +237,14 @@ sealed abstract class Json { self => /** * Transforms json node specified by given cursor - * @param cursor Cursor which specifies node to transform - * @param f Function used to transform node - * @tparam A refined node type - * @return Json with transformed node if node specified by cursor exists, error otherwise + * @param cursor + * Cursor which specifies node to transform + * @param f + * Function used to transform node + * @tparam A + * refined node type + * @return + * Json with transformed node if node specified by cursor exists, error otherwise */ final def transformAt[A <: Json](cursor: JsonCursor[_, A])(f: A => Json): Either[String, Json] = transformOrDelete(cursor, delete = false)(x => Right(f(x))) diff --git a/zio-json/shared/src/main/scala/zio/json/codegen/Generator.scala b/zio-json/shared/src/main/scala/zio/json/codegen/Generator.scala index 523dd35b1..b787b61ab 100644 --- a/zio-json/shared/src/main/scala/zio/json/codegen/Generator.scala +++ b/zio-json/shared/src/main/scala/zio/json/codegen/Generator.scala @@ -6,8 +6,8 @@ import zio.json.ast.Json import zio.json.codegen.Generator.pascalFormat import zio.json.codegen.JsonType._ -import java.time.{ LocalDate, LocalDateTime } import java.time.format.DateTimeFormatter +import java.time.{ LocalDate, LocalDateTime } import java.util.UUID import scala.collection.immutable.ListMap import scala.math.BigDecimal.javaBigDecimal2bigDecimal @@ -16,8 +16,7 @@ import scala.util.Try object Generator { /** - * Renders the JSON string as a series of Scala case classes derived from the - * structure of the JSON. + * Renders the JSON string as a series of Scala case classes derived from the structure of the JSON. * * For example, the following JSON: * diff --git a/zio-json/shared/src/main/scala/zio/json/internal/lexer.scala b/zio-json/shared/src/main/scala/zio/json/internal/lexer.scala index 39dc7fd2a..35ef7dbe8 100644 --- a/zio-json/shared/src/main/scala/zio/json/internal/lexer.scala +++ b/zio-json/shared/src/main/scala/zio/json/internal/lexer.scala @@ -413,7 +413,7 @@ final class StringMatrix(val xs: Array[String], aliases: Array[(String, Int)] = require(aliases.forall(_._1.nonEmpty)) require(aliases.forall(p => p._2 >= 0 && p._2 < xs.length)) - val width = xs.length + aliases.length + val width: Int = xs.length + aliases.length val height: Int = xs.map(_.length).max max (if (aliases.isEmpty) 0 else aliases.map(_._1.length).max) val lengths: Array[Int] = xs.map(_.length) ++ aliases.map(_._1.length) val initial: Long = (0 until width).foldLeft(0L)((bs, r) => bs | (1L << r)) diff --git a/zio-json/shared/src/main/scala/zio/json/internal/numbers.scala b/zio-json/shared/src/main/scala/zio/json/internal/numbers.scala index c869f113e..038bdc7a9 100644 --- a/zio-json/shared/src/main/scala/zio/json/internal/numbers.scala +++ b/zio-json/shared/src/main/scala/zio/json/internal/numbers.scala @@ -21,28 +21,22 @@ import scala.util.control.NoStackTrace /** * Total, fast, number parsing. * - * The Java and Scala standard libraries throw exceptions when we attempt to - * parse an invalid number. Unfortunately, exceptions are very expensive, and - * untrusted data can be maliciously constructed to DOS a server. + * The Java and Scala standard libraries throw exceptions when we attempt to parse an invalid number. Unfortunately, + * exceptions are very expensive, and untrusted data can be maliciously constructed to DOS a server. * - * This suite of functions mitigates against such attacks by building up the - * numbers one character at a time, which has been shown through extensive - * benchmarking to be orders of magnitude faster than exception-throwing stdlib - * parsers, for valid and invalid inputs. This approach, proposed by alexknvl, - * was also benchmarked against regexp-based pre-validation. + * This suite of functions mitigates against such attacks by building up the numbers one character at a time, which has + * been shown through extensive benchmarking to be orders of magnitude faster than exception-throwing stdlib parsers, + * for valid and invalid inputs. This approach, proposed by alexknvl, was also benchmarked against regexp-based + * pre-validation. * - * Note that although the behaviour is identical to the Java stdlib when given - * the canonical form of a primitive (i.e. the .toString) of a number there may - * be differences in behaviour for non-canonical forms. e.g. the Java stdlib - * may reject "1.0" when parsed as an `BigInteger` but we may parse it as a - * `1`, although "1.1" would be rejected. Parsing of `BigDecimal` preserves the - * trailing zeros on the right but not on the left, e.g. "000.00001000" will be - * "1.000e-5", which is useful in cases where the trailing zeros denote - * measurement accuracy. + * Note that although the behaviour is identical to the Java stdlib when given the canonical form of a primitive (i.e. + * the .toString) of a number there may be differences in behaviour for non-canonical forms. e.g. the Java stdlib may + * reject "1.0" when parsed as an `BigInteger` but we may parse it as a `1`, although "1.1" would be rejected. Parsing + * of `BigDecimal` preserves the trailing zeros on the right but not on the left, e.g. "000.00001000" will be + * "1.000e-5", which is useful in cases where the trailing zeros denote measurement accuracy. * - * `BigInteger`, `BigDecimal`, `Float` and `Double` have a configurable bit - * limit on the size of the significand, to avoid OOM style attacks, which is - * 128 bits by default. + * `BigInteger`, `BigDecimal`, `Float` and `Double` have a configurable bit limit on the size of the significand, to + * avoid OOM style attacks, which is 128 bits by default. * * Results are contained in a specialisation of Option that avoids boxing. */ @@ -100,93 +94,95 @@ object SafeNumbers { if (x != x) """"NaN"""" else if (bits < 0) """"-Infinity"""" else """"Infinity"""" - } else { - val s = new java.lang.StringBuilder(24) - if (bits < 0) s.append('-') - if (x == 0.0f) s.append('0').append('.').append('0') - else { - var e = ieeeExponent - 1075 - var m = ieeeMantissa | 0x10000000000000L - var dv = 0L - var exp = 0 - if (e == 0) dv = m - else if (e >= -52 && e < 0 && m << e == 0) dv = m >> -e + } else + { + val s = new java.lang.StringBuilder(24) + if (bits < 0) s.append('-') + if (x == 0.0f) s.append('0').append('.').append('0') else { - var expShift, expCorr = 0 - var cblShift = 2 - if (ieeeExponent == 0) { - e = -1074 - m = ieeeMantissa - if (ieeeMantissa < 3) { - m *= 10 - expShift = 1 + var e = ieeeExponent - 1075 + var m = ieeeMantissa | 0x10000000000000L + var dv = 0L + var exp = 0 + if (e == 0) dv = m + else if (e >= -52 && e < 0 && m << e == 0) dv = m >> -e + else { + var expShift, expCorr = 0 + var cblShift = 2 + if (ieeeExponent == 0) { + e = -1074 + m = ieeeMantissa + if (ieeeMantissa < 3) { + m *= 10 + expShift = 1 + } + } else if (ieeeMantissa == 0 && ieeeExponent > 1) { + expCorr = 131007 + cblShift = 1 } - } else if (ieeeMantissa == 0 && ieeeExponent > 1) { - expCorr = 131007 - cblShift = 1 - } - exp = e * 315653 - expCorr >> 20 - val i = exp + 324 << 1 - val g1 = gs(i) - val g0 = gs(i + 1) - val h = (-exp * 108853 >> 15) + e + 2 - val cb = m << 2 - val outm1 = (m.toInt & 0x1) - 1 - val vb = rop(g1, g0, cb << h) - val vbls = rop(g1, g0, cb - cblShift << h) + outm1 - val vbrd = outm1 - rop(g1, g0, cb + 2 << h) - val s = vb >> 2 - if ( - s < 100 || { - dv = s / 10 // FIXME: Use Math.multiplyHigh(s, 1844674407370955168L) instead after dropping JDK 8 support - val sp40 = dv * 40 - val upin = (vbls - sp40).toInt - (((sp40 + vbrd).toInt + 40) ^ upin) >= 0 || { - dv += ~upin >>> 31 - exp += 1 - false + exp = e * 315653 - expCorr >> 20 + val i = exp + 324 << 1 + val g1 = gs(i) + val g0 = gs(i + 1) + val h = (-exp * 108853 >> 15) + e + 2 + val cb = m << 2 + val outm1 = (m.toInt & 0x1) - 1 + val vb = rop(g1, g0, cb << h) + val vbls = rop(g1, g0, cb - cblShift << h) + outm1 + val vbrd = outm1 - rop(g1, g0, cb + 2 << h) + val s = vb >> 2 + if ( + s < 100 || { + dv = + s / 10 // FIXME: Use Math.multiplyHigh(s, 1844674407370955168L) instead after dropping JDK 8 support + val sp40 = dv * 40 + val upin = (vbls - sp40).toInt + (((sp40 + vbrd).toInt + 40) ^ upin) >= 0 || { + dv += ~upin >>> 31 + exp += 1 + false + } } + ) { + val s4 = s << 2 + val uin = (vbls - s4).toInt + dv = (~ { + if ((((s4 + vbrd).toInt + 4) ^ uin) < 0) uin + else (vb.toInt & 0x3) + (s.toInt & 0x1) - 3 + } >>> 31) + s + exp -= expShift } - ) { - val s4 = s << 2 - val uin = (vbls - s4).toInt - dv = (~ { - if ((((s4 + vbrd).toInt + 4) ^ uin) < 0) uin - else (vb.toInt & 0x3) + (s.toInt & 0x1) - 3 - } >>> 31) + s - exp -= expShift } + val len = digitCount(dv) + exp += len - 1 + if (exp < -3 || exp >= 7) { + val dotOff = s.length + 1 + s.append(dv) + var i = s.length - 1 + while (i > dotOff && s.charAt(i) == '0') i -= 1 + s.setLength(i + 1) + s.insert(dotOff, '.').append('E').append(exp) + } else if (exp < 0) { + s.append('0').append('.') + while ({ + exp += 1 + exp != 0 + }) s.append('0') + s.append(dv) + var i = s.length - 1 + while (s.charAt(i) == '0') i -= 1 + s.setLength(i + 1) + s + } else if (exp + 1 < len) { + val dotOff = s.length + exp + 1 + s.append(dv) + var i = s.length - 1 + while (s.charAt(i) == '0') i -= 1 + s.setLength(i + 1) + s.insert(dotOff, '.') + } else s.append(dv).append('.').append('0') } - val len = digitCount(dv) - exp += len - 1 - if (exp < -3 || exp >= 7) { - val dotOff = s.length + 1 - s.append(dv) - var i = s.length - 1 - while (i > dotOff && s.charAt(i) == '0') i -= 1 - s.setLength(i + 1) - s.insert(dotOff, '.').append('E').append(exp) - } else if (exp < 0) { - s.append('0').append('.') - while ({ - exp += 1 - exp != 0 - }) s.append('0') - s.append(dv) - var i = s.length - 1 - while (s.charAt(i) == '0') i -= 1 - s.setLength(i + 1) - s - } else if (exp + 1 < len) { - val dotOff = s.length + exp + 1 - s.append(dv) - var i = s.length - 1 - while (s.charAt(i) == '0') i -= 1 - s.setLength(i + 1) - s.insert(dotOff, '.') - } else s.append(dv).append('.').append('0') - } - }.toString + }.toString } def toString(x: Float): String = { @@ -197,90 +193,91 @@ object SafeNumbers { if (x != x) """"NaN"""" else if (bits < 0) """"-Infinity"""" else """"Infinity"""" - } else { - val s = new java.lang.StringBuilder(16) - if (bits < 0) s.append('-') - if (x == 0.0f) s.append('0').append('.').append('0') - else { - var e = ieeeExponent - 150 - var m = ieeeMantissa | 0x800000 - var dv, exp = 0 - if (e == 0) dv = m - else if (e >= -23 && e < 0 && m << e == 0) dv = m >> -e + } else + { + val s = new java.lang.StringBuilder(16) + if (bits < 0) s.append('-') + if (x == 0.0f) s.append('0').append('.').append('0') else { - var expShift, expCorr = 0 - var cblShift = 2 - if (ieeeExponent == 0) { - e = -149 - m = ieeeMantissa - if (ieeeMantissa < 8) { - m *= 10 - expShift = 1 + var e = ieeeExponent - 150 + var m = ieeeMantissa | 0x800000 + var dv, exp = 0 + if (e == 0) dv = m + else if (e >= -23 && e < 0 && m << e == 0) dv = m >> -e + else { + var expShift, expCorr = 0 + var cblShift = 2 + if (ieeeExponent == 0) { + e = -149 + m = ieeeMantissa + if (ieeeMantissa < 8) { + m *= 10 + expShift = 1 + } + } else if (ieeeMantissa == 0 && ieeeExponent > 1) { + expCorr = 131007 + cblShift = 1 } - } else if (ieeeMantissa == 0 && ieeeExponent > 1) { - expCorr = 131007 - cblShift = 1 - } - exp = e * 315653 - expCorr >> 20 - val g1 = gs(exp + 324 << 1) + 1 - val h = (-exp * 108853 >> 15) + e + 1 - val cb = m << 2 - val outm1 = (m & 0x1) - 1 - val vb = rop(g1, cb << h) - val vbls = rop(g1, cb - cblShift << h) + outm1 - val vbrd = outm1 - rop(g1, cb + 2 << h) - val s = vb >> 2 - if ( - s < 100 || { - dv = (s * 3435973837L >>> 35).toInt // divide a positive int by 10 - val sp40 = dv * 40 - val upin = vbls - sp40 - ((sp40 + vbrd + 40) ^ upin) >= 0 || { - dv += ~upin >>> 31 - exp += 1 - false + exp = e * 315653 - expCorr >> 20 + val g1 = gs(exp + 324 << 1) + 1 + val h = (-exp * 108853 >> 15) + e + 1 + val cb = m << 2 + val outm1 = (m & 0x1) - 1 + val vb = rop(g1, cb << h) + val vbls = rop(g1, cb - cblShift << h) + outm1 + val vbrd = outm1 - rop(g1, cb + 2 << h) + val s = vb >> 2 + if ( + s < 100 || { + dv = (s * 3435973837L >>> 35).toInt // divide a positive int by 10 + val sp40 = dv * 40 + val upin = vbls - sp40 + ((sp40 + vbrd + 40) ^ upin) >= 0 || { + dv += ~upin >>> 31 + exp += 1 + false + } } + ) { + val s4 = s << 2 + val uin = vbls - s4 + dv = (~ { + if (((s4 + vbrd + 4) ^ uin) < 0) uin + else (vb & 0x3) + (s & 0x1) - 3 + } >>> 31) + s + exp -= expShift } - ) { - val s4 = s << 2 - val uin = vbls - s4 - dv = (~ { - if (((s4 + vbrd + 4) ^ uin) < 0) uin - else (vb & 0x3) + (s & 0x1) - 3 - } >>> 31) + s - exp -= expShift } + val len = digitCount(dv.toLong) + exp += len - 1 + if (exp < -3 || exp >= 7) { + val dotOff = s.length + 1 + s.append(dv) + var i = s.length - 1 + while (i > dotOff && s.charAt(i) == '0') i -= 1 + s.setLength(i + 1) + s.insert(dotOff, '.').append('E').append(exp) + } else if (exp < 0) { + s.append('0').append('.') + while ({ + exp += 1 + exp != 0 + }) s.append('0') + s.append(dv) + var i = s.length - 1 + while (s.charAt(i) == '0') i -= 1 + s.setLength(i + 1) + s + } else if (exp + 1 < len) { + val dotOff = s.length + exp + 1 + s.append(dv) + var i = s.length - 1 + while (s.charAt(i) == '0') i -= 1 + s.setLength(i + 1) + s.insert(dotOff, '.') + } else s.append(dv).append('.').append('0') } - val len = digitCount(dv.toLong) - exp += len - 1 - if (exp < -3 || exp >= 7) { - val dotOff = s.length + 1 - s.append(dv) - var i = s.length - 1 - while (i > dotOff && s.charAt(i) == '0') i -= 1 - s.setLength(i + 1) - s.insert(dotOff, '.').append('E').append(exp) - } else if (exp < 0) { - s.append('0').append('.') - while ({ - exp += 1 - exp != 0 - }) s.append('0') - s.append(dv) - var i = s.length - 1 - while (s.charAt(i) == '0') i -= 1 - s.setLength(i + 1) - s - } else if (exp + 1 < len) { - val dotOff = s.length + exp + 1 - s.append(dv) - var i = s.length - 1 - while (s.charAt(i) == '0') i -= 1 - s.setLength(i + 1) - s.insert(dotOff, '.') - } else s.append(dv).append('.').append('0') - } - }.toString + }.toString } private[this] def rop(g1: Long, g0: Long, cp: Long): Long = { diff --git a/zio-json/shared/src/main/scala/zio/json/internal/readers.scala b/zio-json/shared/src/main/scala/zio/json/internal/readers.scala index 6d81eb43a..95a715b8f 100644 --- a/zio-json/shared/src/main/scala/zio/json/internal/readers.scala +++ b/zio-json/shared/src/main/scala/zio/json/internal/readers.scala @@ -75,9 +75,8 @@ private[zio] final class RewindTwice /** * A Reader that can retract and replay the last char that it read. * - * This is essential when parsing contents that do not have a terminator - * character, e.g. numbers, whilst preserving the non-significant character for - * further processing. + * This is essential when parsing contents that do not have a terminator character, e.g. numbers, whilst preserving the + * non-significant character for further processing. */ sealed trait RetractReader extends OneCharReader { @@ -150,13 +149,11 @@ final class WithRetractReader(in: java.io.Reader) extends RetractReader with Aut } /** - * Records the contents of an underlying Reader and allows rewinding back to - * the beginning once. If rewound and reading continues past the - * recording, the recording no longer continues. + * Records the contents of an underlying Reader and allows rewinding back to the beginning once. If rewound and reading + * continues past the recording, the recording no longer continues. * - * To avoid feature interaction edge cases, `retract` is not allowed as the - * first action nor is `retract` allowed to happen immediately before or after - * a `rewind`. + * To avoid feature interaction edge cases, `retract` is not allowed as the first action nor is `retract` allowed to + * happen immediately before or after a `rewind`. */ private[zio] sealed trait RecordingReader extends RetractReader { def rewind(): Unit diff --git a/zio-json/shared/src/main/scala/zio/json/javatime/serializers.scala b/zio-json/shared/src/main/scala/zio/json/javatime/serializers.scala index 9fa4365b7..4f58364c6 100644 --- a/zio-json/shared/src/main/scala/zio/json/javatime/serializers.scala +++ b/zio-json/shared/src/main/scala/zio/json/javatime/serializers.scala @@ -57,9 +57,9 @@ private[json] object serializers { val epochDay = (if (epochSecond >= 0) epochSecond else epochSecond - 86399) / 86400 // 86400 == seconds per day - val secsOfDay = (epochSecond - epochDay * 86400).toInt - var marchZeroDay = epochDay + 719468 // 719468 == 719528 - 60 == days 0000 to 1970 - days 1st Jan to 1st Mar - var adjustYear = 0 + val secsOfDay = (epochSecond - epochDay * 86400).toInt + var marchZeroDay = epochDay + 719468 // 719468 == 719528 - 60 == days 0000 to 1970 - days 1st Jan to 1st Mar + var adjustYear = 0 if (marchZeroDay < 0) { // adjust negative years to positive for calculation val adjust400YearCycles = to400YearCycle(marchZeroDay + 1) - 1 adjustYear = adjust400YearCycles * 400 diff --git a/zio-json/shared/src/main/scala/zio/json/package.scala b/zio-json/shared/src/main/scala/zio/json/package.scala index b9747b164..7ec99fd4a 100644 --- a/zio-json/shared/src/main/scala/zio/json/package.scala +++ b/zio-json/shared/src/main/scala/zio/json/package.scala @@ -32,11 +32,9 @@ package object json extends JsonPackagePlatformSpecific { /** * Attempts to decode the raw JSON string as an `A`. * - * On failure a human readable message is returned using a jq friendly - * format. For example the error - * `.rows[0].elements[0].distance.value(missing)"` tells us the location of a - * missing field named "value". We can use part of the error message in the - * `jq` command line tool for further inspection, e.g. + * On failure a human readable message is returned using a jq friendly format. For example the error + * `.rows[0].elements[0].distance.value(missing)"` tells us the location of a missing field named "value". We can + * use part of the error message in the `jq` command line tool for further inspection, e.g. * * {{{jq '.rows[0].elements[0].distance' input.json}}} */ diff --git a/zio-json/shared/src/test/scala-2.x/zio/json/ConfigurableDeriveCodecSpec.scala b/zio-json/shared/src/test/scala-2.x/zio/json/ConfigurableDeriveCodecSpec.scala index 2cafc819f..bb1f8b695 100644 --- a/zio-json/shared/src/test/scala-2.x/zio/json/ConfigurableDeriveCodecSpec.scala +++ b/zio-json/shared/src/test/scala-2.x/zio/json/ConfigurableDeriveCodecSpec.scala @@ -1,5 +1,6 @@ package zio.json +import zio.Scope import zio.json.JsonCodecConfiguration.SumTypeHandling.DiscriminatorField import zio.json.ast.Json import zio.test._ @@ -16,7 +17,7 @@ object ConfigurableDeriveCodecSpec extends ZIOSpecDefault { case class OptionalField(a: Option[Int]) - def spec = suite("ConfigurableDeriveCodecSpec")( + def spec: Spec[Environment with TestEnvironment with Scope, Any] = suite("ConfigurableDeriveCodecSpec")( suite("defaults")( suite("string")( test("should not map field names by default") { diff --git a/zio-json/shared/src/test/scala-3/zio/json/DerivedCodecSpec.scala b/zio-json/shared/src/test/scala-3/zio/json/DerivedCodecSpec.scala index 84d1f2313..433042bd5 100644 --- a/zio-json/shared/src/test/scala-3/zio/json/DerivedCodecSpec.scala +++ b/zio-json/shared/src/test/scala-3/zio/json/DerivedCodecSpec.scala @@ -32,6 +32,6 @@ object DerivedCodecSpec extends ZIOSpecDefault { case class Foo(aOrB: "A" | "B", optA: Option["A"]) derives JsonCodec assertTrue(Foo("A", Some("A")).toJson.fromJson[Foo] == Right(Foo("A", Some("A")))) - }, + } ) } diff --git a/zio-json/shared/src/test/scala-3/zio/json/DerivedDecoderSpec.scala b/zio-json/shared/src/test/scala-3/zio/json/DerivedDecoderSpec.scala index b99dd7cd2..d599c5b72 100644 --- a/zio-json/shared/src/test/scala-3/zio/json/DerivedDecoderSpec.scala +++ b/zio-json/shared/src/test/scala-3/zio/json/DerivedDecoderSpec.scala @@ -22,7 +22,7 @@ object DerivedDecoderSpec extends ZIOSpecDefault { case Qux val result = "\"Qux\"".fromJson[Foo] - + assertTrue(result == Right(Foo.Qux)) }, test("Derives for a sum sealed trait Enumeration type") { @@ -33,7 +33,7 @@ object DerivedDecoderSpec extends ZIOSpecDefault { case object Qux extends Foo val result = "\"Qux\"".fromJson[Foo] - + assertTrue(result == Right(Foo.Qux)) }, test("Derives for a sum sealed trait Enumeration type with discriminator") { @@ -45,7 +45,7 @@ object DerivedDecoderSpec extends ZIOSpecDefault { case object Qux extends Foo val result = """{"$type":"Qux"}""".fromJson[Foo] - + assertTrue(result == Right(Foo.Qux)) }, test("Derives for a sum ADT type") { diff --git a/zio-json/shared/src/test/scala/zio/json/CodecSpec.scala b/zio-json/shared/src/test/scala/zio/json/CodecSpec.scala index 468017ecc..39057f569 100644 --- a/zio-json/shared/src/test/scala/zio/json/CodecSpec.scala +++ b/zio-json/shared/src/test/scala/zio/json/CodecSpec.scala @@ -7,7 +7,6 @@ import zio.test.Assertion._ import zio.test.TestAspect.jvmOnly import zio.test._ -import java.math.BigInteger import scala.collection.immutable object CodecSpec extends ZIOSpecDefault { @@ -37,7 +36,7 @@ object CodecSpec extends ZIOSpecDefault { ) }, test("primitives") { - val exampleBDString = "234234.234" + // this big integer consumes more than 256 bits assert( "170141183460469231731687303715884105728489465165484668486513574864654818964653168465316546851" diff --git a/zio-json/shared/src/test/scala/zio/json/Gens.scala b/zio-json/shared/src/test/scala/zio/json/Gens.scala index 354140c64..dd605640a 100644 --- a/zio-json/shared/src/test/scala/zio/json/Gens.scala +++ b/zio-json/shared/src/test/scala/zio/json/Gens.scala @@ -2,58 +2,59 @@ package testzio.json import zio.test.Gen -import java.time._ +import java.math.BigInteger +import java.time.{ ZoneId, _ } import scala.jdk.CollectionConverters._ import scala.util.Try object Gens { - val genBigInteger = + val genBigInteger: Gen[Any, BigInteger] = Gen .bigInt((BigInt(2).pow(128) - 1) * -1, BigInt(2).pow(128) - 1) .map(_.bigInteger) .filter(_.bitLength < 128) - val genBigDecimal = + val genBigDecimal: Gen[Any, java.math.BigDecimal] = Gen .bigDecimal((BigDecimal(2).pow(128) - 1) * -1, BigDecimal(2).pow(128) - 1) .map(_.bigDecimal) .filter(_.toBigInteger.bitLength < 128) - val genUsAsciiString = + val genUsAsciiString: Gen[Any, String] = Gen.string(Gen.oneOf(Gen.char('!', '~'))) - val genAlphaLowerString = + val genAlphaLowerString: Gen[Any, String] = Gen.string(Gen.oneOf(Gen.char('a', 'z'))) - val genYear = + val genYear: Gen[Any, Year] = Gen.oneOf(Gen.int(-9999, 9999), Gen.int(-999999999, 999999999)).map(Year.of) - val genLocalDate = for { + val genLocalDate: Gen[Any, LocalDate] = for { year <- genYear month <- Gen.int(1, 12) day <- Gen.int(1, Month.of(month).length(year.isLeap)) } yield LocalDate.of(year.getValue, month, day) - val genLocalTime = for { + val genLocalTime: Gen[Any, LocalTime] = for { hour <- Gen.int(0, 23) minute <- Gen.int(0, 59) second <- Gen.int(0, 59) nano <- Gen.int(0, 999999999) } yield LocalTime.of(hour, minute, second, nano) - val genInstant = for { + val genInstant: Gen[Any, Instant] = for { epochSecond <- Gen.long(Instant.MIN.getEpochSecond, Instant.MAX.getEpochSecond) nanoAdjustment <- Gen.long(Long.MinValue, Long.MaxValue) fallbackInstant <- Gen.elements(Instant.MIN, Instant.EPOCH, Instant.MAX) } yield Try(Instant.ofEpochSecond(epochSecond, nanoAdjustment)).getOrElse(fallbackInstant) - val genZoneOffset = Gen.oneOf( + val genZoneOffset: Gen[Any, ZoneOffset] = Gen.oneOf( Gen.int(-18, 18).map(ZoneOffset.ofHours), Gen.int(-18 * 60, 18 * 60).map(x => ZoneOffset.ofHoursMinutes(x / 60, x % 60)), Gen.int(-18 * 60 * 60, 18 * 60 * 60).map(ZoneOffset.ofTotalSeconds) ) - val genZoneId = Gen.oneOf( + val genZoneId: Gen[Any, ZoneId] = Gen.oneOf( genZoneOffset, genZoneOffset.map(zo => ZoneId.ofOffset("UT", zo)), genZoneOffset.map(zo => ZoneId.ofOffset("UTC", zo)), @@ -62,17 +63,17 @@ object Gens { Gen.elements(ZoneId.SHORT_IDS.values().asScala.toSeq: _*).map(ZoneId.of) ) - val genLocalDateTime = for { + val genLocalDateTime: Gen[Any, LocalDateTime] = for { localDate <- genLocalDate localTime <- genLocalTime } yield LocalDateTime.of(localDate, localTime) - val genZonedDateTime = for { + val genZonedDateTime: Gen[Any, ZonedDateTime] = for { localDateTime <- genLocalDateTime zoneId <- genZoneId } yield ZonedDateTime.of(localDateTime, zoneId) - val genDuration = Gen.oneOf( + val genDuration: Gen[Any, Duration] = Gen.oneOf( Gen.long(Long.MinValue / 86400, Long.MaxValue / 86400).map(Duration.ofDays), Gen.long(Long.MinValue / 3600, Long.MaxValue / 3600).map(Duration.ofHours), Gen.long(Long.MinValue / 60, Long.MaxValue / 60).map(Duration.ofMinutes), @@ -81,33 +82,33 @@ object Gens { Gen.long(Int.MinValue, Int.MaxValue.toLong).map(Duration.ofNanos) ) - val genMonthDay = for { + val genMonthDay: Gen[Any, MonthDay] = for { month <- Gen.int(1, 12) day <- Gen.int(1, 29) } yield MonthDay.of(month, day) - val genOffsetDateTime = for { + val genOffsetDateTime: Gen[Any, OffsetDateTime] = for { localDateTime <- genLocalDateTime zoneOffset <- genZoneOffset } yield OffsetDateTime.of(localDateTime, zoneOffset) - val genOffsetTime = for { + val genOffsetTime: Gen[Any, OffsetTime] = for { localTime <- genLocalTime zoneOffset <- genZoneOffset } yield OffsetTime.of(localTime, zoneOffset) - val genPeriod = for { + val genPeriod: Gen[Any, Period] = for { year <- Gen.int month <- Gen.int day <- Gen.int } yield Period.of(year, month, day) - val genYearMonth = for { + val genYearMonth: Gen[Any, YearMonth] = for { year <- genYear month <- Gen.int(1, 12) } yield YearMonth.of(year.getValue, month) - val genDayOfWeek = Gen.int(1, 7).map(DayOfWeek.of) + val genDayOfWeek: Gen[Any, DayOfWeek] = Gen.int(1, 7).map(DayOfWeek.of) - val genMonth = Gen.int(1, 12).map(Month.of) + val genMonth: Gen[Any, Month] = Gen.int(1, 12).map(Month.of) } diff --git a/zio-json/shared/src/test/scala/zio/json/codegen/GeneratorSpec.scala b/zio-json/shared/src/test/scala/zio/json/codegen/GeneratorSpec.scala index aff2e766e..fdc6b7b42 100644 --- a/zio-json/shared/src/test/scala/zio/json/codegen/GeneratorSpec.scala +++ b/zio-json/shared/src/test/scala/zio/json/codegen/GeneratorSpec.scala @@ -1,11 +1,12 @@ package zio.json.codegen +import zio.Scope import zio.json._ import zio.json.ast.Json import zio.test._ object GeneratorSpec extends ZIOSpecDefault { - def spec = suite("GeneratorSpec")( + def spec: Spec[Environment with TestEnvironment with Scope, Any] = suite("GeneratorSpec")( suite("generates case classes from JSON strings")( test("simple object") { val json =