-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
made scala2 specific suites for some features that won't go to Scala 3 immediately. stubbed out some methods in auto to get compilation working
- Loading branch information
Showing
31 changed files
with
247 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
21 changes: 21 additions & 0 deletions
21
generic-extras/src/main/scala-3/io/circe/generic/extras/auto.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package io.circe.generic.extras | ||
|
||
import io.circe.{ Decoder, Encoder } | ||
import io.circe.`export`.Exported | ||
import scala.deriving.Mirror | ||
|
||
/** | ||
* Fully automatic codec derivation. | ||
* | ||
* Extending this trait provides [[io.circe.Decoder]] and [[io.circe.Encoder]] | ||
* instances for case classes (if all members have instances), sealed | ||
* trait hierarchies, etc. | ||
*/ | ||
trait AutoDerivation { | ||
implicit inline final def deriveDecoder[A](using inline A: Mirror.Of[A]): Exported[Decoder[A]] = | ||
Exported(Decoder.derived[A]) | ||
implicit inline final def deriveEncoder[A](using inline A: Mirror.Of[A]): Exported[Encoder.AsObject[A]] = | ||
Exported(Encoder.AsObject.derived[A]) | ||
} | ||
|
||
object auto extends AutoDerivation |
73 changes: 73 additions & 0 deletions
73
generic-extras/src/main/scala-3/io/circe/generic/extras/semiauto.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package io.circe.generic.extras | ||
|
||
import io.circe.{ Codec, Decoder, Encoder } | ||
import scala.deriving.Mirror | ||
|
||
/** | ||
* Semi-automatic codec derivation. | ||
* | ||
* This object provides helpers for creating [[io.circe.Decoder]] and [[io.circe.ObjectEncoder]] | ||
* instances for case classes, "incomplete" case classes, sealed trait hierarchies, etc. | ||
* | ||
* Typical usage will look like the following: | ||
* | ||
* {{{ | ||
* import io.circe._, io.circe.generic.semiauto._ | ||
* | ||
* case class Foo(i: Int, p: (String, Double)) | ||
* | ||
* object Foo { | ||
* implicit val decodeFoo: Decoder[Foo] = deriveDecoder[Foo] | ||
* implicit val encodeFoo: Encoder.AsObject[Foo] = deriveEncoder[Foo] | ||
* } | ||
* }}} | ||
*/ | ||
object semiauto { | ||
inline final def deriveConfiguredDecoder[A](using inline A: Mirror.Of[A], configuration: Configuration): Decoder[A] = ??? | ||
inline final def deriveConfiguredEncoder[A](using inline A: Mirror.Of[A], configuration: Configuration): Encoder.AsObject[A] = ??? | ||
inline final def deriveConfiguredCodec[A](using inline A: Mirror.Of[A], configuration: Configuration): Codec.AsObject[A] = ??? | ||
|
||
inline final def deriveExtrasDecoder[A](using inline A: Mirror.Of[A], configuration: Configuration): ExtrasDecoder[A] = ??? | ||
inline final def deriveExtrasEncoder[A](using inline A: Mirror.Of[A], configuration: Configuration): Encoder.AsObject[A] = ??? | ||
inline final def deriveExtrasCodec[A](using inline A: Mirror.Of[A], configuration: Configuration): ExtrasAsObjectCodec[A] = ??? | ||
|
||
/** | ||
* Derive a decoder for a sealed trait hierarchy made up of case objects. | ||
* | ||
* Note that this differs from the usual derived decoder in that the leaves of the ADT are represented as JSON | ||
* strings. | ||
*/ | ||
def deriveEnumerationDecoder[A](): Decoder[A] = ??? | ||
|
||
/** | ||
* Derive an encoder for a sealed trait hierarchy made up of case objects. | ||
* | ||
* Note that this differs from the usual derived encoder in that the leaves of the ADT are represented as JSON | ||
* strings. | ||
*/ | ||
def deriveEnumerationEncoder[A](): Encoder[A] = ??? | ||
|
||
/** | ||
* Derive a codec for a sealed trait hierarchy made up of case objects. | ||
* | ||
* Note that this differs from the usual derived encoder in that the leaves of the ADT are represented as JSON | ||
* strings. | ||
*/ | ||
def deriveEnumerationCodec[A](): Codec[A] = ??? | ||
|
||
/** | ||
* Derive a decoder for a value class. | ||
*/ | ||
def deriveUnwrappedDecoder[A](): Decoder[A] = ??? | ||
|
||
/** | ||
* Derive an encoder for a value class. | ||
*/ | ||
def deriveUnwrappedEncoder[A](): Encoder[A] = ??? | ||
|
||
/** | ||
* Derive a codec for a value class. | ||
*/ | ||
def deriveUnwrappedCodec[A](): Codec[A] = ??? | ||
|
||
} |
32 changes: 32 additions & 0 deletions
32
...ic-extras/src/test/scala-2/io/circe/generic/extras/ConfiguredAutoDerivedScala2Suite.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package io.circe.generic.extras | ||
|
||
import cats.data.Validated | ||
import cats.kernel.Eq | ||
import io.circe.{ Decoder, DecodingFailure, Encoder, Json } | ||
import io.circe.CursorOp.DownField | ||
import io.circe.generic.extras.auto._ | ||
import io.circe.literal._ | ||
import io.circe.testing.CodecTests | ||
import org.scalacheck.{ Arbitrary, Gen } | ||
import org.scalacheck.Arbitrary.arbitrary | ||
import org.scalacheck.Prop.forAll | ||
import examples._ | ||
|
||
class ConfiguredAutoDerivedScala2Suite extends CirceSuite { | ||
|
||
import defaults._ | ||
|
||
property("Decoder[Int => Qux[String]] should decode partial JSON representations") { | ||
forAll { (i: Int, s: String, j: Int) => | ||
val result = Json | ||
.obj( | ||
"a" -> Json.fromString(s), | ||
"j" -> Json.fromInt(j) | ||
) | ||
.as[Int => Qux[String]] | ||
.map(_(i)) | ||
|
||
assert(result === Right(Qux(i, s, j))) | ||
} | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
76 changes: 76 additions & 0 deletions
76
...xtras/src/test/scala-2/io/circe/generic/extras/ConfiguredSemiautoDerivedScala2Suite.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package io.circe.generic.extras | ||
|
||
import cats.kernel.Eq | ||
import io.circe.{ Codec, Decoder, DecodingFailure, Encoder, Json } | ||
import io.circe.generic.extras.semiauto._ | ||
import io.circe.literal._ | ||
import io.circe.testing.CodecTests | ||
import org.scalacheck.{ Arbitrary, Gen } | ||
import org.scalacheck.Arbitrary.arbitrary | ||
import shapeless.Witness | ||
import shapeless.labelled.{ FieldType, field } | ||
import org.scalacheck.Prop.forAll | ||
|
||
import examples._ | ||
import cats.laws.discipline.ScalaVersionSpecific | ||
|
||
object ConfiguredSemiautoDerivedScala2Suite { | ||
implicit val customConfig: Configuration = | ||
Configuration.default.withSnakeCaseMemberNames.withDefaults.withDiscriminator("type").withSnakeCaseConstructorNames | ||
|
||
implicit val decodeJlessQux: Decoder[FieldType[Witness.`'j`.T, Int] => Qux[String]] = | ||
deriveConfiguredFor[FieldType[Witness.`'j`.T, Int] => Qux[String]].incomplete | ||
|
||
implicit val decodeIntlessQux: Decoder[Int => Qux[String]] = | ||
deriveConfiguredFor[Int => Qux[String]].incomplete | ||
|
||
implicit val decodeQuxPatch: Decoder[Qux[String] => Qux[String]] = deriveConfiguredFor[Qux[String]].patch | ||
} | ||
|
||
class ConfiguredSemiautoDerivedScala2Suite extends CirceSuite { | ||
import ConfiguredSemiautoDerivedScala2Suite._ | ||
|
||
property("Decoder[FieldType[Witness.`'j`.T, Int] => Qux[String]] should decode partial JSON representations") { | ||
forAll { (i: Int, s: String, j: Int) => | ||
val result = Json | ||
.obj( | ||
"i" -> Json.fromInt(i), | ||
"a" -> Json.fromString(s) | ||
) | ||
.as[FieldType[Witness.`'j`.T, Int] => Qux[String]] | ||
.map( | ||
_(field(j)) | ||
) | ||
|
||
assert(result === Right(Qux(i, s, j))) | ||
} | ||
} | ||
|
||
property("Decoder[Int => Qux[String]] should decode partial JSON representations") { | ||
forAll { (i: Int, s: String, j: Int) => | ||
val result = Json | ||
.obj( | ||
"a" -> Json.fromString(s), | ||
"j" -> Json.fromInt(j) | ||
) | ||
.as[Int => Qux[String]] | ||
.map(_(i)) | ||
|
||
assert(result === Right(Qux(i, s, j))) | ||
} | ||
} | ||
|
||
property("Decoder[Qux[String] => Qux[String]] should decode patch JSON representations") { | ||
forAll { (q: Qux[String], i: Option[Int], a: Option[String], j: Option[Int]) => | ||
val json = Json.obj( | ||
"i" -> Encoder[Option[Int]].apply(i), | ||
"a" -> Encoder[Option[String]].apply(a), | ||
"j" -> Encoder[Option[Int]].apply(j) | ||
) | ||
|
||
val expected = Qux[String](i.getOrElse(q.i), a.getOrElse(q.a), j.getOrElse(q.j)) | ||
|
||
assert(json.as[Qux[String] => Qux[String]].map(_(q)) === Right(expected)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.