Skip to content
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

Add readers and writers instances for cats-collections #286

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,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]]
}
}
Loading