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 reader and writer for Byte #288

Merged
merged 1 commit into from
May 17, 2024
Merged
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
6 changes: 6 additions & 0 deletions modules/core/src/main/scala/tethys/commons/TokenNode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ object TokenNode {
override val token: Token = NumberValueToken
}

case class ByteValueNode(value: Byte) extends TokenNode {
override def token: Token = NumberValueToken
}
case class ShortValueNode(value: Short) extends TokenNode {
override val token: Token = NumberValueToken
}
Expand Down Expand Up @@ -71,6 +74,7 @@ object TokenNode {

def value(v: String): List[TokenNode] = StringValueNode(v) :: Nil
def value(v: Boolean): List[TokenNode] = BooleanValueNode(v) :: Nil
def value(v: Byte): List[TokenNode] = ByteValueNode(v) :: Nil
def value(v: Short): List[TokenNode] = ShortValueNode(v) :: Nil
def value(v: Int): List[TokenNode] = IntValueNode(v) :: Nil
def value(v: Long): List[TokenNode] = LongValueNode(v) :: Nil
Expand All @@ -85,6 +89,7 @@ object TokenNode {
case v: TokenNode => v :: Nil
case nodes: List[_] => nodes.flatMap(anyToTokens)
case v: String => value(v)
case v: Byte => value(v)
case v: Short => value(v)
case v: Int => value(v)
case v: Long => value(v)
Expand Down Expand Up @@ -115,6 +120,7 @@ object TokenNode {
else if (token.isFieldName) FieldNameNode(iterator.fieldName())
else if (token.isStringValue) StringValueNode(iterator.string())
else if (token.isNumberValue) iterator.number() match {
case v: java.lang.Byte => ByteValueNode(v)
case v: java.lang.Short => ShortValueNode(v)
case v: java.lang.Integer => IntValueNode(v)
case v: java.lang.Long => LongValueNode(v)
Expand Down
2 changes: 1 addition & 1 deletion modules/core/src/main/scala/tethys/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import scala.Specializable.Group

package object tethys {

final val specializations = new Group((Short, Int, Long, Float, Double, Boolean))
final val specializations = new Group((Byte, Short, Int, Long, Float, Double, Boolean))

// given

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ trait AllJsonReaders extends OptionReaders {
}
}

implicit lazy val byteReader: JsonReader[Byte] = new JsonReader[Byte] {
override def read(it: TokenIterator)(implicit fieldName: FieldName): Byte = {
if(it.currentToken().isNumberValue) {
val res = it.byte()
it.next()
res
} else {
ReaderError.wrongJson(s"Expected byte value but found: ${it.currentToken()}")
}
}
}

implicit lazy val shortReader: JsonReader[Short] = new JsonReader[Short] {
override def read(it: TokenIterator)(implicit fieldName: FieldName): Short = {
if(it.currentToken().isNumberValue) {
Expand Down Expand Up @@ -106,6 +118,7 @@ trait AllJsonReaders extends OptionReaders {
case bi: BigInt => BigDecimal(bi)
case jbd: java.math.BigDecimal => BigDecimal(jbd)
case jint: java.lang.Integer => BigDecimal(jint)
case jbyte: java.lang.Byte => BigDecimal(jbyte.longValue())
case jshort: java.lang.Short => BigDecimal(jshort.longValue())
case jlong: java.lang.Long => BigDecimal(jlong)
case jbi: java.math.BigInteger => BigDecimal(jbi)
Expand All @@ -120,13 +133,15 @@ trait AllJsonReaders extends OptionReaders {
case bd: BigDecimal => bd.toBigInt
case jbd: java.math.BigDecimal => jbd.toBigInteger
case jint: java.lang.Integer => BigInt(jint)
case jbyte: java.lang.Byte => BigInt(jbyte.longValue())
case jshort: java.lang.Short => BigInt(jshort.longValue())
case jlong: java.lang.Long => BigInt(jlong)
case num => BigInt(num.longValue())
}


implicit lazy val javaBooleanReader: JsonReader[java.lang.Boolean] = booleanReader.map(a => a)
implicit lazy val javaByteReader: JsonReader[java.lang.Byte] = byteReader.map(a => a)
implicit lazy val javaShortReader: JsonReader[java.lang.Short] = shortReader.map(a => a)
implicit lazy val javaIntReader: JsonReader[java.lang.Integer] = intReader.map(a => a)
implicit lazy val javaLongReader: JsonReader[java.lang.Long] = longReader.map(a => a)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ import scala.language.higherKinds

private[tethys] trait IterableReaders extends LowPriorityIterableReaders {

implicit def byteIterableReader[C[X] <: Iterable[X]](implicit
cb: CollectionBuilder[Byte, C[Byte]]): JsonReader[C[Byte]] = new TraversableReader[Byte, C] {
override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[Byte, C[Byte]])(implicit fieldName: FieldName): Unit = {
builder += PrimitiveReaders.ByteJsonReader.read(it)
}
}

implicit def shortIterableReader[C[X] <: Iterable[X]](implicit
cb: CollectionBuilder[Short, C[Short]]): JsonReader[C[Short]] = new TraversableReader[Short, C] {
override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[Short, C[Short]])(implicit fieldName: FieldName): Unit = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ import scala.collection.mutable
import scala.language.higherKinds

private[tethys] trait MapReaders extends LowPriorityMapReaders {
implicit def byteMapReader[K, M[X, Y] <: scala.collection.Map[X, Y]](implicit
keyReader: KeyReader[K],
cb: CollectionBuilder[(K, Byte), M[K, Byte]]
): JsonReader[M[K, Byte]] = {
new MapReader[K, Byte, M] {
override protected def appendBuilder(it: TokenIterator, builder: mutable.Builder[(K, Byte), M[K, Byte]], key: K)(implicit fieldName: FieldName): Unit = {
builder += key -> PrimitiveReaders.ByteJsonReader.read(it)
}
}
}

implicit def shortMapReader[K, M[X, Y] <: scala.collection.Map[X, Y]](implicit
keyReader: KeyReader[K],
cb: CollectionBuilder[(K, Short), M[K, Short]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import tethys.readers.FieldName
import tethys.readers.tokens.TokenIterator

private[tethys] trait OptionReaders extends LowPriorityOptionReaders {
implicit lazy val byteOptionReader: JsonReader[Option[Byte]] = new OptionJsonReader[Byte] {
override protected def readSomeValue(it: TokenIterator)(implicit fieldName: FieldName): Option[Byte] = {
Some(PrimitiveReaders.ByteJsonReader.read(it))
}
}

implicit lazy val shortOptionReader: JsonReader[Option[Short]] = new OptionJsonReader[Short] {
override protected def readSomeValue(it: TokenIterator)(implicit fieldName: FieldName): Option[Short] = {
Some(PrimitiveReaders.ShortJsonReader.read(it))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ import tethys.readers.tokens.TokenIterator
import tethys.readers.{FieldName, ReaderError}

object PrimitiveReaders {
object ByteJsonReader {
def read(it: TokenIterator)(implicit fieldName: FieldName): Byte = {
if(it.currentToken().isNumberValue) {
val res = it.byte()
it.nextToken()
res
} else {
ReaderError.wrongJson(s"Expected byte value but found: ${it.currentToken()}")
}
}
}

object ShortJsonReader {
def read(it: TokenIterator)(implicit fieldName: FieldName): Short = {
if(it.currentToken().isNumberValue) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ trait BaseTokenIterator extends TokenIterator {
else if(token.isFieldName) FieldNameNode(fieldName()) -> 0
else if(token.isStringValue) StringValueNode(string()) -> 0
else if(token.isNumberValue) number() match {
case v: java.lang.Byte => ByteValueNode(v) -> 0
case v: java.lang.Short => ShortValueNode(v) -> 0
case v: java.lang.Integer => IntValueNode(v) -> 0
case v: java.lang.Long => LongValueNode(v) -> 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class QueueIterator(private var nodes: immutable.Queue[TokenNode]) extends BaseT

override def number(): Number = nodes.front match {
case NumberValueNode(value) => value
case ByteValueNode(value) => value
case ShortValueNode(value) => value
case IntValueNode(value) => value
case LongValueNode(value) => value
Expand All @@ -46,9 +47,21 @@ class QueueIterator(private var nodes: immutable.Queue[TokenNode]) extends BaseT
case node => fail[NumberValueNode](node)
}

override def byte(): Byte = nodes.front match {
case ByteValueNode(value) => value
case NumberValueNode(value) => value.byteValue()
case ShortValueNode(value) => value.toByte
case IntValueNode(value) => value.toByte
case LongValueNode(value) => value.toByte
case FloatValueNode(value) => value.toByte
case DoubleValueNode(value) => value.toByte
case node => fail[ByteValueNode](node)
}

override def short(): Short = nodes.front match {
case ShortValueNode(value) => value
case NumberValueNode(value) => value.shortValue()
case ByteValueNode(value) => value.toShort
case IntValueNode(value) => value.toShort
case LongValueNode(value) => value.toShort
case FloatValueNode(value) => value.toShort
Expand All @@ -59,6 +72,7 @@ class QueueIterator(private var nodes: immutable.Queue[TokenNode]) extends BaseT
override def int(): Int = nodes.front match {
case IntValueNode(value) => value
case NumberValueNode(value) => value.intValue()
case ByteValueNode(value) => value.toInt
case ShortValueNode(value) => value.toInt
case LongValueNode(value) => value.toInt
case FloatValueNode(value) => value.toInt
Expand All @@ -69,6 +83,7 @@ class QueueIterator(private var nodes: immutable.Queue[TokenNode]) extends BaseT
override def long(): Long = nodes.front match {
case LongValueNode(value) => value
case NumberValueNode(value) => value.longValue()
case ByteValueNode(value) => value.toLong
case ShortValueNode(value) => value.toLong
case IntValueNode(value) => value.toLong
case FloatValueNode(value) => value.toLong
Expand All @@ -79,6 +94,7 @@ class QueueIterator(private var nodes: immutable.Queue[TokenNode]) extends BaseT
override def float(): Float = nodes.front match {
case FloatValueNode(value) => value
case NumberValueNode(value) => value.floatValue()
case ByteValueNode(value) => value.toFloat
case ShortValueNode(value) => value.toFloat
case IntValueNode(value) => value.toFloat
case LongValueNode(value) => value.toFloat
Expand All @@ -89,6 +105,7 @@ class QueueIterator(private var nodes: immutable.Queue[TokenNode]) extends BaseT
override def double(): Double = nodes.front match {
case DoubleValueNode(value) => value
case NumberValueNode(value) => value.doubleValue()
case ByteValueNode(value) => value.toDouble
case ShortValueNode(value) => value.toDouble
case IntValueNode(value) => value.toDouble
case LongValueNode(value) => value.toDouble
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ trait TokenIterator {

def number(): Number

def byte(): Byte

def short(): Short

def int(): Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ trait AllJsonWriters extends OptionWriters with EitherWriters {
override def write(value: Long, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value)
}

implicit lazy val byteWriter: JsonWriter[Byte] = new JsonWriter[Byte] {
override def write(value: Byte, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value)
}

implicit lazy val shortWriter: JsonWriter[Short] = new JsonWriter[Short] {
override def write(value: Short, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value)
}
Expand Down Expand Up @@ -48,6 +52,10 @@ trait AllJsonWriters extends OptionWriters with EitherWriters {
override def write(value: java.lang.Long, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value)
}

implicit lazy val javaByteWriter: JsonWriter[java.lang.Byte] = new JsonWriter[java.lang.Byte] {
override def write(value: java.lang.Byte, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value)
}

implicit lazy val javaShortWriter: JsonWriter[java.lang.Short] = new JsonWriter[java.lang.Short] {
override def write(value: java.lang.Short, tokenWriter: TokenWriter): Unit = tokenWriter.writeNumber(value)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class SimpleTokenWriter extends TokenWriter {

override def writeString(v: String): SimpleTokenWriter.this.type = append(StringValueNode(v))

override def writeNumber(v: Byte): SimpleTokenWriter.this.type = append(ByteValueNode(v))

override def writeNumber(v: Short): SimpleTokenWriter.this.type = append(ShortValueNode(v))

override def writeNumber(v: Int): SimpleTokenWriter.this.type = append(IntValueNode(v))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ trait TokenWriter {

def writeString(v: String): this.type

def writeNumber(v: Byte): this.type

def writeNumber(v: Short): this.type

def writeNumber(v: Int): this.type
Expand All @@ -30,6 +32,7 @@ trait TokenWriter {
def writeRawNumber(n: Number): this.type = n match {
case jbd: java.math.BigDecimal => writeNumber(BigDecimal(jbd))
case jint: java.lang.Integer => writeNumber(jint.intValue())
case jbyte: java.lang.Byte => writeNumber(jbyte.longValue())
case jshort: java.lang.Short => writeNumber(jshort.longValue())
case jlong: java.lang.Long => writeNumber(jlong.longValue())
case jbi: java.math.BigInteger => writeNumber(BigInt(jbi))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class DefaultReadersTest extends AnyFlatSpec {
private val cases: List[(TestDefinition[_], List[TokenNode])] = List[(TestDefinition[_], List[TokenNode])](
test("1") -> value("1"),
test(1) -> value(1),
test(1: Byte) -> value(1: Byte),
test(1: Short) -> value(1: Short),
test(1L) -> value(1L),
test(1f) -> value(1f),
Expand All @@ -41,6 +42,7 @@ class DefaultReadersTest extends AnyFlatSpec {
test(Option(1), "Option.nonEmpty") -> value(1),
test(Option.empty[Int], "Option.empty") -> List(NullValueNode) ,
test(1: java.lang.Integer) -> value(1),
test(java.lang.Byte.valueOf(1: Byte)) -> value(1: Byte),
test(java.lang.Short.valueOf(1: Short)) -> value(1: Short),
test(1L: java.lang.Long) -> value(1L),
test(1f: java.lang.Float) -> value(1f),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class DefaultWritersTest extends AnyFlatSpec {
private val cases: List[(TestDefinition[_], List[TokenNode])] = List[(TestDefinition[_], List[TokenNode])](
test("1") -> value("1"),
test(1) -> value(1),
test(1: Byte) -> value(1: Byte),
test(1: Short) -> value(1: Short),
test(1L) -> value(1L),
test(1f) -> value(1f),
Expand All @@ -43,6 +44,7 @@ class DefaultWritersTest extends AnyFlatSpec {
test(Right(1): Either[String, Int], "Either.right") -> value(1),
test(Left("Not an Int"): Either[String, Int], "Either.left") -> value("Not an Int"),
test(1: java.lang.Integer) -> value(1),
test(java.lang.Byte.valueOf(1: Byte)) -> value(1: Byte),
test(java.lang.Short.valueOf(1: Short)) -> value(1: Short),
test(1L: java.lang.Long) -> value(1L),
test(1f: java.lang.Float) -> value(1f),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ final class JacksonTokenIterator(jsonParser: JsonParser) extends BaseTokenIterat

override def number(): Number = jsonParser.getNumberValue

override def byte(): Byte = jsonParser.getByteValue

override def short(): Short = jsonParser.getShortValue

override def int(): Int = jsonParser.getIntValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ class JacksonTokenWriter(jsonGenerator: JsonGenerator) extends TokenWriter {
this
}

override def writeNumber(v: Byte): JacksonTokenWriter.this.type = {
jsonGenerator.writeNumber(v)
this
}

override def writeNumber(v: Short): JacksonTokenWriter.this.type = {
jsonGenerator.writeNumber(v)
this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class JacksonTokenWriterTest extends AnyFlatSpec with Matchers {
iterate(_.writeString("string")) shouldBe """"string""""
}

it should "write Byte value" in {
iterate(_.writeNumber(1: Byte)) shouldBe """1"""
}

it should "write Short value" in {
iterate(_.writeNumber(1: Short)) shouldBe """1"""
}
Expand Down
Loading