Skip to content

Commit

Permalink
Add readers and writers instances for some cats-collections
Browse files Browse the repository at this point in the history
  • Loading branch information
Roman-Statsura committed Apr 23, 2024
1 parent 6d72556 commit b4092af
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 2 deletions.
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ lazy val scala3 = "3.3.0"
ThisBuild / scalaVersion := scala3

lazy val commonSettings = Seq(
version := "0.28.4",
version := "0.28.5",
organization := "com.tethys-json",
licenses := Seq("Apache-2.0" -> url("https://www.apache.org/licenses/LICENSE-2.0")),
homepage := Some(url("https://github.com/tethys-json/tethys")),
Expand Down Expand Up @@ -114,6 +114,7 @@ lazy val cats = project.in(modules / "cats")
name := "tethys-cats",
libraryDependencies ++= Seq(
"org.typelevel" %% "cats-core" % "2.10.0",
"org.typelevel" %% "cats-collections-core" % "0.9.8",
)
)
.dependsOn(core)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
package tethys.cats.readers

import cats.{Hash, Order}
import cats.collections.{
AvlSet,
BitSet,
Dequeue,
HashMap,
HashSet,
Heap,
PairingHeap,
TreeList
}
import cats.data._
import tethys.readers.tokens.TokenIterator
import tethys.readers.{FieldName, ReaderError}
import tethys.readers.{FieldName, KeyReader, ReaderError}
import tethys.JsonReader
import tethys.JsonReader.iterableReader

Expand Down Expand Up @@ -53,4 +64,31 @@ trait CatsReaders {
}
}

implicit val readerForBitSet: JsonReader[BitSet] =
JsonReader[Seq[Int]].map(seq => BitSet(seq: _*))

implicit def readerForCatsDequeue[T: JsonReader]: JsonReader[Dequeue[T]] =
JsonReader[Seq[T]].map(seq => Dequeue(seq: _*))

implicit def readerForCatsHashMap[K: KeyReader: Hash, V: JsonReader]
: JsonReader[HashMap[K, V]] =
JsonReader[Map[K, V]].map(m => HashMap(m.toSeq: _*))

implicit def readerForCatsHashSet[T: JsonReader: Hash]
: JsonReader[HashSet[T]] =
JsonReader[Seq[T]].map(HashSet.fromSeq(_))

implicit def readerForCatsHeap[T: JsonReader: Order]: JsonReader[Heap[T]] =
JsonReader[Seq[T]].map(Heap.fromIterable(_))

implicit def readerForPairingHeap[T: JsonReader: Order]
: JsonReader[PairingHeap[T]] =
JsonReader[Seq[T]].map(PairingHeap.fromIterable(_))

implicit def readerForTreeList[T: JsonReader]: JsonReader[TreeList[T]] =
JsonReader[List[T]].map(TreeList.fromList)

implicit def readerForAvlSet[T: JsonReader: Order]: JsonReader[AvlSet[T]] =
JsonReader[List[T]].map(AvlSet.fromList(_))

}
39 changes: 39 additions & 0 deletions modules/cats/src/main/scala/tethys/cats/writers/CatsWriters.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
package tethys.cats.writers

import cats.Order
import cats.collections.{
AvlSet,
BitSet,
Dequeue,
HashMap,
HashSet,
Heap,
PairingHeap,
TreeList
}
import cats.data._
import tethys.JsonWriter
import tethys.writers.KeyWriter

trait CatsWriters {
implicit def writerForNev[T: JsonWriter]: JsonWriter[NonEmptyVector[T]] =
Expand All @@ -18,4 +30,31 @@ trait CatsWriters {

implicit def writerForNec[T: JsonWriter]: JsonWriter[NonEmptyChain[T]] =
JsonWriter[Chain[T]].contramap(_.toChain)

implicit val writerForBitSet: JsonWriter[BitSet] =
JsonWriter[Set[Int]].contramap(_.toSet)

implicit def writerForCatsDequeue[T: JsonWriter]: JsonWriter[Dequeue[T]] =
JsonWriter[List[T]].contramap(_.toList)

implicit def writerForCatsHashMap[K: KeyWriter, V: JsonWriter]
: JsonWriter[HashMap[K, V]] =
JsonWriter[Map[K, V]].contramap(_.toMap)

implicit def writerForCatsHashSet[T: JsonWriter]: JsonWriter[HashSet[T]] =
JsonWriter[Set[T]].contramap(_.toSet)

implicit def writerForCatsHeap[T: JsonWriter: Order]: JsonWriter[Heap[T]] =
JsonWriter[Seq[T]].contramap(_.toList)

implicit def writerForPairingHeap[T: JsonWriter: Order]
: JsonWriter[PairingHeap[T]] =
JsonWriter[Seq[T]].contramap(_.toList)

implicit def writerForTreeList[T: JsonWriter]: JsonWriter[TreeList[T]] =
JsonWriter[List[T]].contramap(_.toList)

implicit def writerForAvlSet[T: JsonWriter]: JsonWriter[AvlSet[T]] =
JsonWriter[Seq[T]].contramap(_.toList)

}
41 changes: 41 additions & 0 deletions modules/cats/src/test/scala/tethys/cats/CatsSupportTests.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
package tethys.cats

import cats.collections.{
AvlSet,
BitSet,
Dequeue,
HashMap,
HashSet,
Heap,
PairingHeap,
TreeList
}
import cats.data._
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
Expand All @@ -15,6 +25,15 @@ class CatsSupportTests extends AnyFlatSpec with Matchers {
val chain: Chain[Int] = Chain.fromIterableOnce(Seq(1, 2, 3))
val nec: NonEmptyChain[String] = NonEmptyChain.of("a", "b", "c")

val bitSet: BitSet = BitSet.apply(5, 1, 5, 4, 2, 3)
val dequeue: Dequeue[String] = Dequeue("a", "b", "c")
val hashMap: HashMap[String, Int] = HashMap("a" -> 1, "b" -> 2)
val hasSet: HashSet[Int] = HashSet(1, 2, 3)
val heap: Heap[Int] = Heap.fromIterable(Seq(1, 2, 3, 4))
val pairingHeap: PairingHeap[Int] = PairingHeap.fromIterable(Seq(1, 2, 3))
val treeList: TreeList[Int] = TreeList.fromList(List(1, 2, 3, 4))
val avlSet: AvlSet[Int] = AvlSet.fromList(List(1, 2, 3))

behavior of "CatsWriters"
it should "write non-empty" in {
nev.asTokenList shouldBe arr("a", "b")
Expand All @@ -24,6 +43,17 @@ class CatsSupportTests extends AnyFlatSpec with Matchers {
nec.asTokenList shouldBe arr("a", "b", "c")
}

it should "write cats-collection" in {
bitSet.asTokenList shouldBe arr(1, 2, 3, 4, 5)
dequeue.asTokenList shouldBe arr("a", "b", "c")
hashMap.asTokenList shouldBe obj("a" -> 1, "b" -> 2)
hasSet.asTokenList shouldBe arr(1, 2, 3)
heap.asTokenList shouldBe arr(1, 2, 3, 4)
pairingHeap.asTokenList shouldBe arr(1, 2, 3)
treeList.asTokenList shouldBe arr(1, 2, 3, 4)
avlSet.asTokenList shouldBe arr(1, 2, 3)
}

behavior of "CatsReaders"
it should "read non-empty" in {
nev shouldBe arr("a", "b").tokensAs[NonEmptyVector[String]]
Expand All @@ -41,4 +71,15 @@ class CatsSupportTests extends AnyFlatSpec with Matchers {
nec shouldBe arr("a", "b", "c").tokensAs[NonEmptyChain[String]]
assertThrows[ReaderError](Nil.tokensAs[NonEmptyChain[String]])
}

it should "read cats-collection" in {
bitSet shouldBe arr(1, 2, 3, 4, 5).tokensAs[BitSet]
dequeue shouldBe arr("a", "b", "c").tokensAs[Dequeue[String]]
hashMap shouldBe obj("a" -> 1, "b" -> 2).tokensAs[HashMap[String, Int]]
hasSet shouldBe arr(1, 2, 3).tokensAs[HashSet[Int]]
heap shouldBe arr(1, 2, 3, 4).tokensAs[Heap[Int]]
pairingHeap shouldBe arr(1, 2, 3).tokensAs[PairingHeap[Int]]
treeList shouldBe arr(1, 2, 3, 4).tokensAs[TreeList[Int]]
avlSet shouldBe arr(1, 2, 3).tokensAs[AvlSet[Int]]
}
}

0 comments on commit b4092af

Please sign in to comment.