Skip to content

Commit

Permalink
refined support module
Browse files Browse the repository at this point in the history
  • Loading branch information
danslapman committed Jan 2, 2024
1 parent 43f646e commit b3d9ce1
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
14 changes: 13 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ val `oolong-bson` = (project in file("oolong-bson"))
Test / fork := true,
)

val `oolong-bson-refined` = (project in file("oolong-bson-refined"))
.settings(Settings.common)
.dependsOn(`oolong-bson`)
.settings(
libraryDependencies ++= Seq(
"eu.timepit" %% "refined" % "0.11.0",
"org.scalatest" %% "scalatest" % "3.2.15" % Test,
"com.ironcorelabs" %% "cats-scalatest" % "4.0.0" % Test
),
Test / fork := true,
)

val `oolong-core` = (project in file("oolong-core"))
.settings(Settings.common)
.dependsOn(`oolong-bson`)
Expand Down Expand Up @@ -95,7 +107,7 @@ val `oolong-mongo-it` = (project in file("oolong-mongo-it"))

val root = (project in file("."))
.settings(Settings.common)
.aggregate(`oolong-bson`, `oolong-core`, `oolong-mongo`, `oolong-mongo-it`)
.aggregate(`oolong-bson`, `oolong-bson-refined`, `oolong-core`, `oolong-mongo`, `oolong-mongo-it`)
.settings(
pullRemoteCache := {},
pushRemoteCache := {},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package oolong.bson.refined

import scala.util.Failure
import scala.util.Success
import scala.util.Try

import eu.timepit.refined.api.RefType
import eu.timepit.refined.api.Validate
import oolong.bson.BsonDecoder
import oolong.bson.BsonEncoder
import oolong.bson.BsonKeyDecoder
import oolong.bson.BsonKeyEncoder
import oolong.bson.DeserializationError
import org.mongodb.scala.bson.BsonValue

given [T, P, F[_, _]](using BsonDecoder[T], Validate[T, P], RefType[F]): BsonDecoder[F[T, P]] with
def fromBson(value: BsonValue): Try[F[T, P]] =
BsonDecoder[T].fromBson(value) match {
case Success(t0) =>
RefType[F].refine(t0) match {
case Left(err) => Failure(DeserializationError(err))
case Right(t) => Success(t)
}
case Failure(exc) => Failure(exc)
}

given [T, P, F[_, _]](using BsonEncoder[T], Validate[T, P], RefType[F]): BsonEncoder[F[T, P]] with
extension (value: F[T, P]) def bson: BsonValue = RefType[F].unwrap(value).bson

given [T, P, F[_, _]](using BsonKeyDecoder[T], Validate[T, P], RefType[F]): BsonKeyDecoder[F[T, P]] with
def decode(value: String): Try[F[T, P]] =
BsonKeyDecoder[T].decode(value) match {
case Success(t0) =>
RefType[F].refine(t0) match {
case Left(err) => Failure(DeserializationError(err))
case Right(t) => Success(t)
}
case Failure(exc) => Failure(exc)
}

given [T, P, F[_, _]](using BsonKeyEncoder[T], Validate[T, P], RefType[F]): BsonKeyEncoder[F[T, P]] with
def encode(t: F[T, P]): String = BsonKeyEncoder[T].encode(RefType[F].unwrap(t))
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package oolong.bson.refined

import eu.timepit.refined.*
import eu.timepit.refined.api.Refined
import eu.timepit.refined.numeric.*
import oolong.bson.{*, given}
import org.scalatest.TryValues
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers
import cats.scalatest.EitherValues

class RoundRobinSpec extends AnyFunSuite with Matchers with TryValues with EitherValues {
test("Refined serialization") {
val refinedVal: Int Refined Positive = refineV[Positive](5).value

val sut = BsonDecoder[Int Refined Positive].fromBson(refinedVal.bson)

sut.success.value shouldEqual refinedVal
}
}

0 comments on commit b3d9ce1

Please sign in to comment.