-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add readers and writers instances for cats non-empty collections
- Loading branch information
1 parent
0fc4b10
commit 5800cbd
Showing
5 changed files
with
158 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
modules/integrations/cats/src/main/scala/tethys/integration/cats/instances.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package tethys.integration.cats | ||
|
||
import tethys.integration.cats.readers.CatsReaders | ||
import tethys.integration.cats.writers.CatsWriters | ||
|
||
object instances extends CatsReaders with CatsWriters |
73 changes: 73 additions & 0 deletions
73
modules/integrations/cats/src/main/scala/tethys/integration/cats/readers/CatsReaders.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package tethys.integration.cats.readers | ||
|
||
import cats.data._ | ||
import tethys.readers.tokens.TokenIterator | ||
import tethys.readers.{FieldName, ReaderError} | ||
import tethys.JsonReader | ||
import tethys.JsonReader.iterableReader | ||
|
||
import scala.collection.immutable.SortedSet | ||
|
||
trait CatsReaders { | ||
|
||
implicit def readerForNel[T: JsonReader]: JsonReader[NonEmptyList[T]] = | ||
new JsonReader[NonEmptyList[T]] { | ||
override def read( | ||
it: TokenIterator | ||
)(implicit fieldName: FieldName): NonEmptyList[T] = | ||
NonEmptyList.fromList(JsonReader[List[T]].read(it)) match { | ||
case Some(value) => value | ||
case None => | ||
ReaderError.wrongJson( | ||
s"List is empty and can't be converted to NonEmptyList" | ||
) | ||
} | ||
} | ||
|
||
implicit def readerForNev[T: JsonReader]: JsonReader[NonEmptyVector[T]] = | ||
new JsonReader[NonEmptyVector[T]] { | ||
override def read( | ||
it: TokenIterator | ||
)(implicit fieldName: FieldName): NonEmptyVector[T] = | ||
NonEmptyVector.fromVector(JsonReader[Vector[T]].read(it)) match { | ||
case Some(value) => value | ||
case None => | ||
ReaderError.wrongJson( | ||
s"Vector is empty and can't be converted to NonEmptyVector" | ||
) | ||
} | ||
} | ||
|
||
implicit def readerForNes[T: JsonReader: Ordering] | ||
: JsonReader[NonEmptySet[T]] = | ||
new JsonReader[NonEmptySet[T]] { | ||
override def read( | ||
it: TokenIterator | ||
)(implicit fieldName: FieldName): NonEmptySet[T] = | ||
NonEmptySet.fromSet(SortedSet.from(JsonReader[Set[T]].read(it))) match { | ||
case Some(value) => value | ||
case None => | ||
ReaderError.wrongJson( | ||
s"Set is empty and can't be converted to NonEmptySet" | ||
) | ||
} | ||
} | ||
|
||
implicit def readerForChain[T: JsonReader]: JsonReader[Chain[T]] = | ||
JsonReader[Seq[T]].map(Chain.fromSeq) | ||
|
||
implicit def readerForNec[T: JsonReader]: JsonReader[NonEmptyChain[T]] = | ||
new JsonReader[NonEmptyChain[T]] { | ||
override def read( | ||
it: TokenIterator | ||
)(implicit fieldName: FieldName): NonEmptyChain[T] = | ||
NonEmptyChain.fromChain(JsonReader[Chain[T]].read(it)) match { | ||
case Some(value) => value | ||
case None => | ||
ReaderError.wrongJson( | ||
s"Chain is empty and can't be converted to NonEmptyChain" | ||
) | ||
} | ||
} | ||
|
||
} |
21 changes: 21 additions & 0 deletions
21
modules/integrations/cats/src/main/scala/tethys/integration/cats/writers/CatsWriters.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package tethys.integration.cats.writers | ||
|
||
import cats.data._ | ||
import tethys.JsonWriter | ||
|
||
trait CatsWriters { | ||
implicit def writerForNev[T: JsonWriter]: JsonWriter[NonEmptyVector[T]] = | ||
JsonWriter[Vector[T]].contramap(_.toVector) | ||
|
||
implicit def writerForNel[T: JsonWriter]: JsonWriter[NonEmptyList[T]] = | ||
JsonWriter[List[T]].contramap(_.toList) | ||
|
||
implicit def writerForNes[T: JsonWriter]: JsonWriter[NonEmptySet[T]] = | ||
JsonWriter[Set[T]].contramap(_.toSortedSet) | ||
|
||
implicit def writerForChain[T: JsonWriter]: JsonWriter[Chain[T]] = | ||
JsonWriter[List[T]].contramap(_.toList) | ||
|
||
implicit def writerForNec[T: JsonWriter]: JsonWriter[NonEmptyChain[T]] = | ||
JsonWriter[Chain[T]].contramap(_.toChain) | ||
} |
44 changes: 44 additions & 0 deletions
44
modules/integrations/cats/src/test/scala/tethys/integration/cats/CatsSupportTests.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package tethys.integration.cats | ||
|
||
import cats.data._ | ||
import org.scalatest.flatspec.AnyFlatSpec | ||
import org.scalatest.matchers.should.Matchers | ||
import tethys.commons.TokenNode._ | ||
import tethys.integration.cats.instances._ | ||
import tethys.readers.ReaderError | ||
import tethys.writers.tokens.SimpleTokenWriter._ | ||
|
||
class CatsSupportTests extends AnyFlatSpec with Matchers { | ||
val nev: NonEmptyVector[String] = NonEmptyVector.of("a", "b") | ||
val nel: NonEmptyList[Int] = NonEmptyList.of(1, 2) | ||
val nes: NonEmptySet[String] = NonEmptySet.of("a", "b") | ||
val chain: Chain[Int] = Chain.fromSeq(Seq(1, 2, 3)) | ||
val nec: NonEmptyChain[String] = NonEmptyChain.of("a", "b", "c") | ||
|
||
behavior of "CatsWriters" | ||
it should "work with non empty" in { | ||
nev.asTokenList shouldBe arr("a", "b") | ||
nel.asTokenList shouldBe arr(1, 2) | ||
nes.asTokenList shouldBe arr("a", "b") | ||
chain.asTokenList shouldBe arr(1, 2, 3) | ||
nec.asTokenList shouldBe arr("a", "b", "c") | ||
} | ||
|
||
behavior of "CatsReaders" | ||
it should "work with non empty" in { | ||
nev shouldBe arr("a", "b").tokensAs[NonEmptyVector[String]] | ||
assertThrows[ReaderError](Nil.tokensAs[NonEmptyVector[String]]) | ||
|
||
nel shouldBe arr(1, 2).tokensAs[NonEmptyList[Int]] | ||
assertThrows[ReaderError](Nil.tokensAs[NonEmptyList[Int]]) | ||
|
||
nes shouldBe arr("a", "b").tokensAs[NonEmptySet[String]] | ||
assertThrows[ReaderError](Nil.tokensAs[NonEmptySet[String]]) | ||
|
||
chain shouldBe arr(1, 2, 3).tokensAs[Chain[Int]] | ||
|
||
nec shouldBe arr("a", "b", "c").tokensAs[NonEmptyChain[String]] | ||
assertThrows[ReaderError](Nil.tokensAs[NonEmptyChain[String]]) | ||
|
||
} | ||
} |