From 73dd56ba0022d99434aa7126180641777b264eaf Mon Sep 17 00:00:00 2001 From: Ivan Aristov Date: Tue, 21 Apr 2020 11:42:14 +0300 Subject: [PATCH] Add BsonWriter typeclass (#19) Add BsonWriter typeclass #12 --- build.sbt | 2 +- .../github/weakteam/mongo/AllInstances.scala | 3 ++ .../io/github/weakteam/mongo/AllSyntax.scala | 5 +++ .../{ => mongo}/bson/BsonSubtype.scala | 2 +- .../weakteam/{ => mongo}/bson/BsonValue.scala | 2 +- .../weakteam/mongo/bson/BsonWriter.scala | 19 ++++++++++ .../io/github/weakteam/mongo/implicits.scala | 3 ++ .../{ => mongo}/bson/BsonSubtypeSpec.scala | 4 +-- .../{ => mongo}/bson/BsonValueSpec.scala | 4 +-- .../weakteam/mongo/bson/BsonWriterSpec.scala | 35 +++++++++++++++++++ project/Dependencies.scala | 4 +-- 11 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 core/src/main/scala/io/github/weakteam/mongo/AllInstances.scala create mode 100644 core/src/main/scala/io/github/weakteam/mongo/AllSyntax.scala rename core/src/main/scala/io/github/weakteam/{ => mongo}/bson/BsonSubtype.scala (96%) rename core/src/main/scala/io/github/weakteam/{ => mongo}/bson/BsonValue.scala (98%) create mode 100644 core/src/main/scala/io/github/weakteam/mongo/bson/BsonWriter.scala create mode 100644 core/src/main/scala/io/github/weakteam/mongo/implicits.scala rename core/src/test/scala/io/github/weakteam/{ => mongo}/bson/BsonSubtypeSpec.scala (93%) rename core/src/test/scala/io/github/weakteam/{ => mongo}/bson/BsonValueSpec.scala (97%) create mode 100644 core/src/test/scala/io/github/weakteam/mongo/bson/BsonWriterSpec.scala diff --git a/build.sbt b/build.sbt index 8116db1..191f21a 100644 --- a/build.sbt +++ b/build.sbt @@ -106,7 +106,7 @@ lazy val core = project .settings(commonSettings: _*) .settings( libraryDependencies ++= - Seq(Dependencies.Libs.cats) ++ + Seq(Dependencies.Libs.cats, Dependencies.Libs.simulacrum) ++ Dependencies.Plugins.plugins ++ Dependencies.TestLibraries.testLibraries.map(_ % Test) ) diff --git a/core/src/main/scala/io/github/weakteam/mongo/AllInstances.scala b/core/src/main/scala/io/github/weakteam/mongo/AllInstances.scala new file mode 100644 index 0000000..414d5ae --- /dev/null +++ b/core/src/main/scala/io/github/weakteam/mongo/AllInstances.scala @@ -0,0 +1,3 @@ +package io.github.weakteam.mongo + +trait AllInstances diff --git a/core/src/main/scala/io/github/weakteam/mongo/AllSyntax.scala b/core/src/main/scala/io/github/weakteam/mongo/AllSyntax.scala new file mode 100644 index 0000000..1122252 --- /dev/null +++ b/core/src/main/scala/io/github/weakteam/mongo/AllSyntax.scala @@ -0,0 +1,5 @@ +package io.github.weakteam.mongo + +import io.github.weakteam.mongo.bson.BsonWriter + +trait AllSyntax extends BsonWriter.ToBsonWriterOps diff --git a/core/src/main/scala/io/github/weakteam/bson/BsonSubtype.scala b/core/src/main/scala/io/github/weakteam/mongo/bson/BsonSubtype.scala similarity index 96% rename from core/src/main/scala/io/github/weakteam/bson/BsonSubtype.scala rename to core/src/main/scala/io/github/weakteam/mongo/bson/BsonSubtype.scala index c588223..2254b91 100644 --- a/core/src/main/scala/io/github/weakteam/bson/BsonSubtype.scala +++ b/core/src/main/scala/io/github/weakteam/mongo/bson/BsonSubtype.scala @@ -1,4 +1,4 @@ -package io.github.weakteam.bson +package io.github.weakteam.mongo.bson import cats.Show diff --git a/core/src/main/scala/io/github/weakteam/bson/BsonValue.scala b/core/src/main/scala/io/github/weakteam/mongo/bson/BsonValue.scala similarity index 98% rename from core/src/main/scala/io/github/weakteam/bson/BsonValue.scala rename to core/src/main/scala/io/github/weakteam/mongo/bson/BsonValue.scala index ff3d62f..f050a83 100644 --- a/core/src/main/scala/io/github/weakteam/bson/BsonValue.scala +++ b/core/src/main/scala/io/github/weakteam/mongo/bson/BsonValue.scala @@ -1,4 +1,4 @@ -package io.github.weakteam.bson +package io.github.weakteam.mongo.bson import cats.Show import cats.syntax.show._ diff --git a/core/src/main/scala/io/github/weakteam/mongo/bson/BsonWriter.scala b/core/src/main/scala/io/github/weakteam/mongo/bson/BsonWriter.scala new file mode 100644 index 0000000..94dada7 --- /dev/null +++ b/core/src/main/scala/io/github/weakteam/mongo/bson/BsonWriter.scala @@ -0,0 +1,19 @@ +package io.github.weakteam.mongo.bson + +import cats.Contravariant +import simulacrum.typeclass + +@typeclass +trait BsonWriter[-T] { self => + def writeBson(arg: T): BsonValue +} + +object BsonWriter { + def instance[A](f: A => BsonValue): BsonWriter[A] = f(_) + + implicit val bsonWriterContravariantInstance: Contravariant[BsonWriter] = new Contravariant[BsonWriter] { + def contramap[A, B](fa: BsonWriter[A])(f: B => A): BsonWriter[B] = { arg => + fa.writeBson(f(arg)) + } + } +} diff --git a/core/src/main/scala/io/github/weakteam/mongo/implicits.scala b/core/src/main/scala/io/github/weakteam/mongo/implicits.scala new file mode 100644 index 0000000..43dacf8 --- /dev/null +++ b/core/src/main/scala/io/github/weakteam/mongo/implicits.scala @@ -0,0 +1,3 @@ +package io.github.weakteam.mongo + +object implicits extends AllSyntax with AllInstances diff --git a/core/src/test/scala/io/github/weakteam/bson/BsonSubtypeSpec.scala b/core/src/test/scala/io/github/weakteam/mongo/bson/BsonSubtypeSpec.scala similarity index 93% rename from core/src/test/scala/io/github/weakteam/bson/BsonSubtypeSpec.scala rename to core/src/test/scala/io/github/weakteam/mongo/bson/BsonSubtypeSpec.scala index c84a5f9..a56ff17 100644 --- a/core/src/test/scala/io/github/weakteam/bson/BsonSubtypeSpec.scala +++ b/core/src/test/scala/io/github/weakteam/mongo/bson/BsonSubtypeSpec.scala @@ -1,9 +1,9 @@ -package io.github.weakteam.bson +package io.github.weakteam.mongo.bson import org.scalatest.matchers.must.Matchers import org.scalatest.wordspec.AnyWordSpec import cats.syntax.show._ -import io.github.weakteam.bson.BsonSubtype._ +import BsonSubtype._ class BsonSubtypeSpec extends AnyWordSpec with Matchers { "BsonSubtypeShow" should { diff --git a/core/src/test/scala/io/github/weakteam/bson/BsonValueSpec.scala b/core/src/test/scala/io/github/weakteam/mongo/bson/BsonValueSpec.scala similarity index 97% rename from core/src/test/scala/io/github/weakteam/bson/BsonValueSpec.scala rename to core/src/test/scala/io/github/weakteam/mongo/bson/BsonValueSpec.scala index 55e798c..826cdfc 100644 --- a/core/src/test/scala/io/github/weakteam/bson/BsonValueSpec.scala +++ b/core/src/test/scala/io/github/weakteam/mongo/bson/BsonValueSpec.scala @@ -1,9 +1,9 @@ -package io.github.weakteam.bson +package io.github.weakteam.mongo.bson import org.scalatest.matchers.must.Matchers import org.scalatest.wordspec.AnyWordSpec import cats.syntax.show._ -import io.github.weakteam.bson.BsonValue._ +import BsonValue._ class BsonValueSpec extends AnyWordSpec with Matchers { "BsonValueShow" should { diff --git a/core/src/test/scala/io/github/weakteam/mongo/bson/BsonWriterSpec.scala b/core/src/test/scala/io/github/weakteam/mongo/bson/BsonWriterSpec.scala new file mode 100644 index 0000000..5c465a9 --- /dev/null +++ b/core/src/test/scala/io/github/weakteam/mongo/bson/BsonWriterSpec.scala @@ -0,0 +1,35 @@ +package io.github.weakteam.mongo.bson + +import io.github.weakteam.mongo.bson.BsonValue.BsonInt +import org.scalatest.matchers.must.Matchers +import org.scalatest.wordspec.AnyWordSpec +import io.github.weakteam.mongo.implicits._ +import cats.syntax.contravariant._ + +class BsonWriterSpec extends AnyWordSpec with Matchers { + "BsonWriter" should { + "return right value" in { + implicit val intBsonWriter: BsonWriter[Int] = BsonInt(_) + + 1.writeBson mustBe BsonInt(1) + } + + "return right value with contramap" in { + implicit val intBsonWriter: BsonWriter[Int] = BsonInt(_) + implicit val anyBsonWriter: BsonWriter[Any] = intBsonWriter.contramap { + case i: Int => i + case _ => 0 + } + + 1.writeBson mustBe BsonInt(1) + "".writeBson mustBe BsonInt(0) + 1L.writeBson mustBe BsonInt(0) + } + + "return right value with manual instance creation" in { + implicit val intBsonWriter: BsonWriter[Int] = BsonWriter.instance(BsonInt) + + 1.writeBson mustBe BsonInt(1) + } + } +} diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 12b9f66..39fdccc 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -17,7 +17,8 @@ object Dependencies { } object Libs { - val cats = "org.typelevel" %% "cats-core" % Versions.cats + val cats = "org.typelevel" %% "cats-core" % Versions.cats + val simulacrum = "org.typelevel" %% "simulacrum" % Versions.simulacrum } object TestLibraries { @@ -31,7 +32,6 @@ object Dependencies { object Plugins { val macroParadise = "org.scalamacros" % "paradise" % Versions.macroParadise cross CrossVersion.patch - val simulacrum = "org.typelevel" %% "simulacrum" % Versions.simulacrum val bm4Plugin = "com.olegpy" %% "better-monadic-for" % Versions.bm4 val kindProjectorPlugin = "org.typelevel" % "kind-projector" % Versions.kindProjector cross CrossVersion.patch val silencerPlugin = "com.github.ghik" %% "silencer-plugin" % Versions.silencer cross CrossVersion.full