Skip to content

Add sphere-mongo-3 and sphere-json-3 (the scala 3 version of similarly named modules) #651

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 148 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 113 commits
Commits
Show all changes
148 commits
Select commit Hold shift + click to select a range
ff4171a
sphere-mongo-derivation-scala-3
peter-empen Feb 21, 2024
6aab3f9
sphere-mongo-core, sphere-util compiles with both Scala 2 and 3
benko-ct Feb 22, 2024
91424e0
some macro test code
benko-ct Feb 22, 2024
04a2d75
some macro test code2
benko-ct Feb 22, 2024
bbabb8a
some macro test code2
benko-ct Feb 22, 2024
77787a9
some macro test code2
benko-ct Feb 22, 2024
33049ff
start module and case-class derivation
peter-empen Feb 23, 2024
4cee24d
Autoderivation example with fake bson
benko-ct Feb 26, 2024
3a120ca
brush up specs
peter-empen Feb 29, 2024
c888f4f
add .bsp to .gitignore
peter-empen Feb 29, 2024
cf41666
scalafmt
peter-empen Feb 29, 2024
4da664c
fix SBT warnings on target
peter-empen Mar 1, 2024
a8845d1
Port the initial implementation from FakeBson to Actual MongoDB types
benko-ct Apr 19, 2024
396417a
Add MongoKey and MongoEmbedded implementations
benko-ct Apr 29, 2024
dbee359
Add MongoTypeHint and MongoTypeHintField
benko-ct May 17, 2024
02388ea
ENE-49 Fix infinite loop in derivation
programaker May 23, 2024
9298ec3
ENE-49 Add a case with `implicit` keyword
programaker May 23, 2024
8ced215
add DefaultValuesSpec
peter-empen May 23, 2024
eccd881
Merge branch 'ENE-49__fix-derivation-infinite-loop' into scala-3
programaker May 23, 2024
e4ccd28
Fix OptionMongoFormatSpec
benko-ct May 23, 2024
244dd51
Refactor AnnotationReader macro functions and Remove bad imports.
benko-ct May 23, 2024
cccf067
Move TypedMongoFormat instances to DefaultMongoFormats
benko-ct May 23, 2024
e19d164
ENE-49 Enums work
programaker May 23, 2024
363d3e7
Merge branch 'ENE-49__dev' into scala-3
programaker May 23, 2024
2f5d1eb
Support default values
benko-ct May 23, 2024
1eb13a2
ENE-49 Solve merge conflicts
programaker May 23, 2024
e2b478a
ENE-49 Spec for class with fields with default value
programaker May 23, 2024
aecda6e
Add DeriveMongoFormatSpec
benko-ct May 23, 2024
67943d7
brushing up some code
peter-empen May 24, 2024
ba48367
stat with MongoIgnore
peter-empen May 24, 2024
1b85335
ENE-49 Porting Json Lib - Initial version
ysedira May 24, 2024
8f2d38e
Fix tests
benko-ct May 24, 2024
991644c
toMongoValue with MongoIgnore
peter-empen May 24, 2024
722edac
Fix some Option/Null behaviour
benko-ct Jun 17, 2024
425bc8d
remove warnings
benko-ct Jun 17, 2024
e5dc7f4
Fix sumtype writer
benko-ct Jun 17, 2024
0796166
change implicits to given
benko-ct Jun 17, 2024
76e0073
remove forProduct spec because it was only testing the internal detai…
benko-ct Jun 17, 2024
62a6b76
Add deriveSingletonJSON
benko-ct Jun 18, 2024
0294477
sphere-json-core now compiles with Scala3
benko-ct Jul 1, 2024
7bf1515
Turn off indentation based syntax.
benko-ct Jul 19, 2024
f4311e6
Turn off indentation based syntax.
benko-ct Jul 19, 2024
f2cbf08
Move sphere-json-derivation-3 to sphere-json-core (just the main, not…
benko-ct Jul 20, 2024
185d1c7
Merge branch 'refs/heads/main' into scala-3
benko-ct Aug 15, 2024
7b84b3c
move mongo-derivation-3 to mongo-3, separating the MongoFormat implem…
benko-ct Nov 22, 2024
3a509a5
Port DefaultMongoFormats to mongo-3
benko-ct Nov 25, 2024
bd03551
Add BaseMoneyMongoFormatTest
benko-ct Nov 25, 2024
a8490a8
Remove "New anonymous class definition will be duplicated at each inl…
benko-ct Nov 25, 2024
5c8db69
Revert "Remove "New anonymous class definition will be duplicated at …
benko-ct Nov 25, 2024
52e5e05
Small refactor
benko-ct Nov 25, 2024
4eb3676
Small refactor
benko-ct Nov 25, 2024
830e497
Revert "Move sphere-json-derivation-3 to sphere-json-core (just the m…
benko-ct Dec 5, 2024
ab83fdd
[ENE-49] util-3 and json-3 pure Scala 3 modules
programaker Dec 5, 2024
964f12e
[ENE-49] Remove fmpp from json-3. Remove json-derivation-3 module
programaker Dec 6, 2024
d35e499
Merge pull request #632 from commercetools/scala-3__json-3
benko-ct Dec 9, 2024
43438a2
Add mongoTypeSwitch
benko-ct Jan 30, 2025
f9f0ef5
Add mongoTypeSwitch
benko-ct Jan 30, 2025
e2cf5eb
Fix JSON derivation (moving the actual derivation to FromJSON and ToJ…
benko-ct Feb 21, 2025
e0a00e6
Merge branch 'main' into scala-3
benko-ct Feb 21, 2025
868050b
merge compiler option switches
benko-ct Feb 21, 2025
c6bf620
Remove util-3 as util is compatible with both scala 2 and 3
benko-ct Feb 21, 2025
65573fa
Formatting
benko-ct Feb 21, 2025
d2bd471
Trying to make the pipeline work
benko-ct Feb 21, 2025
214003f
Trying to make the pipeline work
benko-ct Feb 21, 2025
1b46be7
Trying to make the pipeline work
benko-ct Feb 21, 2025
d290d98
Trying to make the pipeline work
benko-ct Feb 21, 2025
f1ff371
Trying to make the pipeline work
benko-ct Feb 21, 2025
eed2c79
Trying to make the pipeline work
benko-ct Feb 21, 2025
c553fc9
Trying to make the pipeline work
benko-ct Feb 21, 2025
40ab176
Trying to make the pipeline work
benko-ct Feb 21, 2025
d1f850d
Remove useless code
benko-ct Feb 21, 2025
7e7c87a
Trying different cross compilation settings
benko-ct Feb 21, 2025
c43a36e
Fix some package names/imports
benko-ct Feb 21, 2025
ac35627
Trying different cross compilation settings
benko-ct Feb 21, 2025
563ddbe
1. removing redundant directory (json-derivation-scala-3)
benko-ct Apr 11, 2025
e78e849
1. Move remaining tests to json-core
benko-ct Apr 11, 2025
422c4d1
Fixing ci.yml
benko-ct Apr 11, 2025
8c2342e
move main parts of mongo-3 to mongo-core
benko-ct Apr 11, 2025
23c468f
Move tests from mongo-3
benko-ct Apr 11, 2025
86578b5
formatting
benko-ct Apr 11, 2025
d96edd8
fix ci.yml
benko-ct Apr 11, 2025
fe15e40
FromMongo.fields is not a Vector[String] instead of Set[String] becau…
benko-ct Apr 11, 2025
eb5e3ca
remove unnecessary change
benko-ct Apr 11, 2025
6db374a
Move back MongoFormatter.fields to Set
benko-ct Apr 24, 2025
9363968
Move FromJSON instances to a common file (between scala 2/3)
benko-ct Apr 24, 2025
54be0ab
Make the code work in the editor
programaker Apr 24, 2025
c00b484
Fix "New anonymous class definition will be duplicated at each inline…
programaker Apr 24, 2025
1756aad
Move ToJSON instances to a common file (between scala 2/3)
benko-ct Apr 25, 2025
c0c4599
Move MongoFormat instances to a common file (between scala 2/3)
benko-ct Apr 25, 2025
2172bf6
formatting
benko-ct Apr 25, 2025
1c81994
Move common values to objects
benko-ct Apr 25, 2025
436f004
Remove duplicated test files
benko-ct Apr 25, 2025
6beea22
Enabling some test for scala 3
benko-ct Apr 25, 2025
42ed16c
formatting
benko-ct Apr 25, 2025
fe78216
Move mongoEnum to its original package
benko-ct Apr 25, 2025
4cfe4b8
Enable enum instances/tests for Scala3
benko-ct Apr 25, 2025
a2bbfac
Fix warnings
programaker Apr 25, 2025
c39a9d1
Remove support for scala 2.12
programaker Apr 25, 2025
d7237a0
Trying to fix pipeline
benko-ct Apr 25, 2025
1fc8ed1
Turn on more test cases in JSONSpec
benko-ct Apr 25, 2025
6471cc0
Fix typehints
benko-ct Apr 25, 2025
67c17a4
Better implementation for nested typehint renames in typeswitch
benko-ct Apr 26, 2025
4bf30da
add custom implementation test case to typeswitch
benko-ct Apr 26, 2025
fed317f
Separate JSONTypeSwitch implementation to from and to JSON
benko-ct Apr 28, 2025
d0e2bd1
Adding last test in JSONSpec
benko-ct Apr 28, 2025
24ad816
Fix bug regards to nested type class derivation, Rename CaseClassMeta…
benko-ct May 1, 2025
a15a634
Enable nested trait deriving
benko-ct May 1, 2025
06cea48
Format
benko-ct May 1, 2025
0738ba6
Remove outdated experimental magnolia derivation
sbrunk May 2, 2025
cb2af67
Cross-compile all submodules; disable fmpp on Scala 3
sbrunk May 2, 2025
9e9cbc5
Cross-compile all submodules; disable fmpp on Scala 3
sbrunk May 2, 2025
7227566
Simplify CI cross-compilation
sbrunk May 2, 2025
9b1a4ae
Merge pull request #664 from commercetools/scala-3-cross
sbrunk May 6, 2025
a2d6c2d
moving more json derivation tests to the common section
benko-ct May 8, 2025
9c586f5
formatting
benko-ct May 8, 2025
da336cf
trying to fix build
benko-ct May 8, 2025
89c4fe6
moving more mongo derivation tests to the common section
benko-ct May 8, 2025
b8e86b6
move scala2 mongo derivation to its proper folder
benko-ct May 8, 2025
e08cd68
move scala2 json derivation to its proper folder
benko-ct May 8, 2025
0491618
formatting
benko-ct May 8, 2025
f8ea6ca
Fix DeriveSingleton import issue
benko-ct May 8, 2025
0338731
formatting
benko-ct May 8, 2025
da44d9a
Decrease differences between JSONSpec scala2/scala3
benko-ct May 8, 2025
6c12f67
Use typeSwitches for the trait case of derivations.
benko-ct May 10, 2025
9e6a6eb
add enum object support to json-annotationreader too.
benko-ct May 10, 2025
5304270
Refactor AnnotationReader so common parts can be used by both json an…
benko-ct May 10, 2025
a13cd6f
renames
benko-ct May 10, 2025
0b585cd
improve naming
benko-ct May 10, 2025
941fe88
Fix package structure
benko-ct May 23, 2025
da63668
Add scala-2 syntax for 'jsonTypeSwitch' methods for scala3
benko-ct May 23, 2025
e479bdf
test syntax improvements
benko-ct May 23, 2025
de01add
Merge branch 'main' into scala-3
benko-ct Jun 20, 2025
37765be
Fix merge
benko-ct Jun 20, 2025
2b04357
change names
benko-ct Jun 26, 2025
cd8b331
Syntax changes
benko-ct Jun 26, 2025
d5ea170
set sbt scala version back
benko-ct Jun 26, 2025
e903fd4
Refactor JsonTypeSwitch so it can be "merged" with other json instanc…
benko-ct Jun 30, 2025
54cb965
Api backwards compatibility fix
benko-ct Jun 30, 2025
ef94c44
scalafmt
benko-ct Jun 30, 2025
e33816a
minor refactor
benko-ct Jun 30, 2025
5583c76
scalafmt
benko-ct Jun 30, 2025
415cc9d
reenable tests in JsonTypeSwitchSpec
benko-ct Jul 24, 2025
e60304b
Merge branch 'main' into scala-3
benko-ct Jul 24, 2025
84c3974
Move scala2 specific test to their folder
benko-ct Jul 24, 2025
687c752
Add tests for subTypeNames in JSON
benko-ct Jul 24, 2025
e6254cc
set sbt ThisBuild/scalaversion back to 2.13
benko-ct Jul 24, 2025
2cea052
Use Class instead of String for ToFormatters
benko-ct Jul 25, 2025
17d506e
Use Class instead of String for ToFormatters
benko-ct Jul 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 3 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
scala: [2.12.20, 2.13.16, 3.3.5]
scala: [2.13.16, 3.3.5]
java: [temurin@21]
runs-on: ${{ matrix.os }}
steps:
Expand All @@ -50,16 +50,11 @@ jobs:
- name: Check that workflows are up to date
run: sbt '++ ${{ matrix.scala }}' githubWorkflowCheck

- name: Build Scala 2 project
if: matrix.scala != '3.3.5'
- name: Build project
run: sbt '++ ${{ matrix.scala }}' test

- name: Build Scala 3 project
if: matrix.scala == '3.3.5'
run: sbt '++ ${{ matrix.scala }}' sphere-util/test sphere-json-core/test sphere-mongo-core/test

- name: Compress target directories
run: tar cf targets.tar benchmarks/target mongo/target json/json-core/target mongo/mongo-core/target json/target util/target json/json-derivation/target mongo/mongo-derivation-magnolia/target target mongo/mongo-derivation/target project/target
run: tar cf targets.tar benchmarks/target mongo/target json/json-core/target mongo/mongo-core/target json/target util/target json/json-derivation/target target mongo/mongo-derivation/target project/target

- name: Upload target directories
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -94,16 +89,6 @@ jobs:
- name: Setup sbt
uses: sbt/setup-sbt@v1

- name: Download target directories (2.12.20)
uses: actions/download-artifact@v4
with:
name: target-${{ matrix.os }}-2.12.20-${{ matrix.java }}

- name: Inflate target directories (2.12.20)
run: |
tar xf targets.tar
rm targets.tar

- name: Download target directories (2.13.16)
uses: actions/download-artifact@v4
with:
Expand Down
3 changes: 2 additions & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
version = 3.8.3

runner.dialect = scala213
runner.dialect = scala3
runner.dialectOverride.allowSignificantIndentation = false

maxColumn = 100

Expand Down
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the benchmarks cannot run on scala 3?

Copy link
Contributor

@sbrunk sbrunk May 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scala 3 compilation was disabled before on the benchmarks module. I tried to compile while doing #664 but it uses jsonProduct and mongoProduct that seem to be only available on Scala 2 in the corresponding derivation modules, so I also disabled it for now for Scala 3.

File renamed without changes.
53 changes: 15 additions & 38 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import pl.project13.scala.sbt.JmhPlugin

lazy val scala212 = "2.12.20"
lazy val scala213 = "2.13.16"
lazy val scala3 = "3.3.5"

// sbt-github-actions needs configuration in `ThisBuild`
ThisBuild / crossScalaVersions := Seq(scala212, scala213, scala3)
ThisBuild / crossScalaVersions := Seq(scala213, scala3)
ThisBuild / scalaVersion := scala213
ThisBuild / githubWorkflowPublishTargetBranches := List()
ThisBuild / githubWorkflowJavaVersions := List(JavaSpec.temurin("21"))
Expand All @@ -14,21 +13,6 @@ ThisBuild / githubWorkflowBuildPreamble ++= List(
)
ThisBuild / githubWorkflowBuildMatrixFailFast := Some(false)

// workaround for CI because `sbt ++3.3.4 test` used by sbt-github-actions
// still tries to compile the Scala 2 only projects leading to weird issues
// note that `sbt +test` is working fine to run cross-compiled tests locally
ThisBuild / githubWorkflowBuild := Seq(
WorkflowStep.Sbt(
commands = List("test"),
name = Some("Build Scala 2 project"),
cond = Some(s"matrix.scala != '$scala3'")),
WorkflowStep.Sbt(
commands = List("sphere-util/test", "sphere-json-core/test", "sphere-mongo-core/test"),
name = Some("Build Scala 3 project"),
cond = Some(s"matrix.scala == '$scala3'")
)
)

// Release

inThisBuild(
Expand Down Expand Up @@ -65,7 +49,7 @@ lazy val standardSettings = Defaults.coreDefaultSettings ++ Seq(
javacOptions ++= Seq("-deprecation", "-Xlint:unchecked"),
// targets Java 8 bytecode (scalac & javac)
scalacOptions ++= {
if (scalaVersion.value.startsWith("2.12") || scalaVersion.value.startsWith("3")) Seq.empty
if (scalaVersion.value.startsWith("3")) Seq("-noindent")
else Seq("-target", "8")
},
ThisBuild / javacOptions ++= Seq("-source", "8", "-target", "8"),
Expand Down Expand Up @@ -93,69 +77,62 @@ lazy val `sphere-libs` = project
`sphere-mongo`,
`sphere-mongo-core`,
`sphere-mongo-derivation`,
`sphere-mongo-derivation-magnolia`,
`benchmarks`
)

lazy val `sphere-util` = project
.in(file("./util"))
.settings(standardSettings: _*)
.settings(crossScalaVersions := Seq(scala212, scala213, scala3))
.settings(homepage := Some(url("https://github.com/commercetools/sphere-scala-libs/README.md")))

lazy val `sphere-json-core` = project
.in(file("./json/json-core"))
.settings(standardSettings: _*)
.settings(crossScalaVersions := Seq(scala212, scala213, scala3))
.dependsOn(`sphere-util`)

lazy val `sphere-mongo-core` = project
.in(file("./mongo/mongo-core"))
.settings(standardSettings: _*)
.dependsOn(`sphere-util`)

lazy val `sphere-json-derivation` = project
.in(file("./json/json-derivation"))
.settings(standardSettings: _*)
.settings(Fmpp.settings: _*)
.settings(crossScalaVersions := Seq(scala212, scala213))
.settings(
inConfig(Compile)(
sourceGenerators ++= (if (scalaVersion.value.startsWith("2")) Seq(Fmpp.fmpp.taskValue)
else Seq())))
.dependsOn(`sphere-json-core`)

lazy val `sphere-json` = project
.in(file("./json"))
.settings(standardSettings: _*)
.settings(homepage := Some(
url("https://github.com/commercetools/sphere-scala-libs/blob/master/json/README.md")))
.settings(crossScalaVersions := Seq(scala212, scala213))
.dependsOn(`sphere-json-core`, `sphere-json-derivation`)

lazy val `sphere-mongo-core` = project
.in(file("./mongo/mongo-core"))
.settings(standardSettings: _*)
.settings(crossScalaVersions := Seq(scala212, scala213, scala3))
.dependsOn(`sphere-util`)

lazy val `sphere-mongo-derivation` = project
.in(file("./mongo/mongo-derivation"))
.settings(standardSettings: _*)
.settings(Fmpp.settings: _*)
.settings(crossScalaVersions := Seq(scala212, scala213))
.dependsOn(`sphere-mongo-core`)

lazy val `sphere-mongo-derivation-magnolia` = project
.in(file("./mongo/mongo-derivation-magnolia"))
.settings(standardSettings: _*)
.settings(crossScalaVersions := Seq(scala212, scala213))
.settings(
inConfig(Compile)(
sourceGenerators ++= (if (scalaVersion.value.startsWith("2")) Seq(Fmpp.fmpp.taskValue)
else Seq())))
.dependsOn(`sphere-mongo-core`)

lazy val `sphere-mongo` = project
.in(file("./mongo"))
.settings(standardSettings: _*)
.settings(homepage := Some(
url("https://github.com/commercetools/sphere-scala-libs/blob/master/mongo/README.md")))
.settings(crossScalaVersions := Seq(scala212, scala213))
.dependsOn(`sphere-mongo-core`, `sphere-mongo-derivation`)

// benchmarks

lazy val benchmarks = project
.settings(standardSettings: _*)
.settings(publishArtifact := false, publish := {})
.settings(crossScalaVersions := Seq(scala212, scala213))
.enablePlugins(JmhPlugin)
.dependsOn(`sphere-util`, `sphere-json`, `sphere-mongo`)
23 changes: 23 additions & 0 deletions json/json-core/src/main/scala-2/io/sphere/json/FromJSON.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.sphere.json

import org.json4s.JsonAST._

import scala.annotation.implicitNotFound

/** Type class for types that can be read from JSON. */
@implicitNotFound("Could not find an instance of FromJSON for ${A}")
trait FromJSON[@specialized A] extends Serializable {
def read(jval: JValue): JValidation[A]
final protected def fail(msg: String) = jsonParseError(msg)

/** needed JSON fields - ignored if empty */
val fields: Set[String] = FromJSON.emptyFieldsSet
}

object FromJSON extends FromJSONInstances with FromJSONCatsInstances {

private[FromJSON] val emptyFieldsSet: Set[String] = Set.empty

@inline def apply[A](implicit instance: FromJSON[A]): FromJSON[A] = instance

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import scala.annotation.implicitNotFound
@implicitNotFound("Could not find an instance of JSON for ${A}")
trait JSON[A] extends FromJSON[A] with ToJSON[A]

object JSON extends JSONInstances with JSONLowPriorityImplicits {
object JSON extends JSONCatsInstances with JSONLowPriorityImplicits {
@inline def apply[A](implicit instance: JSON[A]): JSON[A] = instance
}

Expand Down
25 changes: 25 additions & 0 deletions json/json-core/src/main/scala-2/io/sphere/json/ToJSON.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.sphere.json

import scala.annotation.implicitNotFound
import java.time
import org.json4s.JsonAST.JValue

/** Type class for types that can be written to JSON. */
@implicitNotFound("Could not find an instance of ToJSON for ${A}")
trait ToJSON[@specialized A] extends Serializable {
def write(value: A): JValue
}

class JSONWriteException(msg: String) extends JSONException(msg)

object ToJSON extends ToJSONInstances with ToJSONCatsInstances {

@inline def apply[A](implicit instance: ToJSON[A]): ToJSON[A] = instance

/** construct an instance from a function
*/
def instance[T](toJson: T => JValue): ToJSON[T] = new ToJSON[T] {
override def write(value: T): JValue = toJson(value)
}

}
27 changes: 27 additions & 0 deletions json/json-core/src/main/scala-3/io.sphere.json/FromJSON.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.sphere.json

import io.sphere.json.JValidation
import org.json4s.JsonAST.JValue

/** Type class for types that can be read from JSON. */
trait FromJSON[A] extends Serializable {
def read(jval: JValue): JValidation[A]
final protected def fail(msg: String) = jsonParseError(msg)

/** needed JSON fields - ignored if empty */
val fields: Set[String] = FromJSON.emptyFieldsSet
}

object FromJSON extends FromJSONInstances with FromJSONCatsInstances with generic.DeriveFromJSON {
val emptyFieldsSet: Set[String] = Set.empty

inline def apply[A](using instance: FromJSON[A]): FromJSON[A] = instance

def instance[A](
readFn: JValue => JValidation[A],
fieldSet: Set[String] = emptyFieldsSet): FromJSON[A] = new {

override def read(jval: JValue): JValidation[A] = readFn(jval)
override val fields: Set[String] = fieldSet
}
}
44 changes: 44 additions & 0 deletions json/json-core/src/main/scala-3/io.sphere.json/JSON.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.sphere.json

import cats.implicits.*
import org.json4s.JsonAST.JValue

import scala.deriving.Mirror

trait JSON[A] extends FromJSON[A] with ToJSON[A]

inline def deriveJSON[A](using Mirror.Of[A]): JSON[A] = JSON.derived

object JSON extends JSONCatsInstances {
inline def apply[A: JSON]: JSON[A] = summon[JSON[A]]
inline given derived[A](using fromJSON: FromJSON[A], toJSON: ToJSON[A]): JSON[A] = instance

def instance[A](
readFn: JValue => JValidation[A],
writeFn: A => JValue,
fieldSet: Set[String] = FromJSON.emptyFieldsSet): JSON[A] = new {

override def read(jval: JValue): JValidation[A] = readFn(jval)
override def write(value: A): JValue = writeFn(value)
override val fields: Set[String] = fieldSet
}

private def instance[A](using fromJSON: FromJSON[A], toJSON: ToJSON[A]): JSON[A] =
new JSON[A] {
override def read(jval: JValue): JValidation[A] = fromJSON.read(jval)

override def write(value: A): JValue = toJSON.write(value)

override val fields: Set[String] = fromJSON.fields
}
}

class JSONException(msg: String) extends RuntimeException(msg)

sealed abstract class JSONError
case class JSONFieldError(path: List[String], message: String) extends JSONError {
override def toString = path.mkString(" -> ") + ": " + message
}
case class JSONParseError(message: String) extends JSONError {
override def toString = message
}
24 changes: 24 additions & 0 deletions json/json-core/src/main/scala-3/io.sphere.json/ToJSON.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.sphere.json

import org.json4s.JsonAST.JValue

import java.time
import java.util.{Currency, Locale, UUID}

/** Type class for types that can be written to JSON. */
trait ToJSON[A] extends Serializable {
def write(value: A): JValue
}

class JSONWriteException(msg: String) extends JSONException(msg)

object ToJSON extends ToJSONInstances with ToJSONCatsInstances with generic.DeriveToJSON {
inline def apply[A](implicit instance: ToJSON[A]): ToJSON[A] = instance
inline def apply[A: JSON]: ToJSON[A] = summon[ToJSON[A]]

/** construct an instance from a function
*/
def instance[T](toJson: T => JValue): ToJSON[T] = new ToJSON[T] {
override def write(value: T): JValue = toJson(value)
}
}
Loading