Skip to content

Commit

Permalink
Merge pull request #105 from geirolz/fix_numbers
Browse files Browse the repository at this point in the history
Fix number
  • Loading branch information
geirolz authored Jun 4, 2023
2 parents 3c4b930 + b72e049 commit bd0a694
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 42 deletions.
8 changes: 4 additions & 4 deletions core/src/main/scala/cats/xml/Xml.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ object Xml {
def ofString(value: String): XmlString = XmlString(value)
def ofChar(value: Char): XmlChar = XmlChar(value)
def ofBoolean(value: Boolean): XmlBool = XmlBool(value)
def ofByte(value: Byte): XmlNumber = XmlByte(value)
def ofShort(value: Short): XmlNumber = XmlShort(value)
def ofInt(value: Int): XmlNumber = XmlInt(value)
def ofByte(value: Byte): XmlNumber = XmlLong(value.toLong)
def ofShort(value: Short): XmlNumber = XmlLong(value.toLong)
def ofInt(value: Int): XmlNumber = XmlLong(value.toLong)
def ofLong(value: Long): XmlNumber = XmlLong(value)
def ofFloat(value: Float): XmlNumber = XmlFloat(value)
def ofDouble(value: Double): XmlNumber = XmlDouble(value)
def ofBigInt(value: BigInt): XmlNumber = XmlBigInt(value)
def ofBigInt(value: BigInt): XmlNumber = XmlBigDecimal(BigDecimal(value))
def ofBigDecimal(value: BigDecimal): XmlNumber = XmlBigDecimal(value)
def ofArray[T <: XmlData](value: Array[T]): XmlArray[T] = XmlArray(value)
def ofSeq[T <: XmlData: ClassTag](value: Seq[T]): XmlArray[T] = XmlArray(value.toArray)
Expand Down
35 changes: 2 additions & 33 deletions core/src/main/scala/cats/xml/xmlData.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,14 @@ object XmlData {
sealed trait XmlNumber extends XmlData with Serializable {

final def toBigDecimal: Option[BigDecimal] = this match {
case XmlByte(value) => Some(BigDecimal(value.toInt))
case XmlShort(value) => Some(BigDecimal(value.toInt))
case XmlInt(value) => Some(BigDecimal(value))
case XmlLong(value) => Some(BigDecimal(value))
case XmlFloat(value) => Some(new JavaBigDecimal(java.lang.Float.toString(value)))
case XmlDouble(value) => Some(JavaBigDecimal.valueOf(value))
case XmlBigInt(value) => Some(BigDecimal(value))
case XmlBigDecimal(value) => Some(value)
}

final def toBigInt: Option[BigInt] = this match {
case XmlByte(value) => Some(BigInt(value.toInt))
case XmlShort(value) => Some(BigInt(value.toInt))
case XmlInt(value) => Some(BigInt(value))
case XmlLong(value) => Some(BigInt(value))
case XmlLong(value) => Some(BigInt(value))
case XmlFloat(value) =>
Option(new JavaBigDecimal(java.lang.Float.toString(value)))
.filter(XmlNumber.bigDecimalIsWhole)
Expand All @@ -62,29 +55,20 @@ object XmlData {
Option(JavaBigDecimal.valueOf(value))
.filter(XmlNumber.bigDecimalIsWhole)
.map(bd => new BigInt(bd.toBigInteger))
case XmlBigInt(value) => Some(value)
case XmlBigDecimal(value) => value.toBigIntExact
}

final def toDouble: Double = this match {
case XmlByte(value) => value.toDouble
case XmlShort(value) => value.toDouble
case XmlInt(value) => value.toDouble
case XmlLong(value) => value.toDouble
case XmlFloat(value) => new JavaBigDecimal(java.lang.Float.toString(value)).doubleValue
case XmlDouble(value) => value
case XmlBigInt(value) => value.doubleValue
case XmlBigDecimal(value) => value.doubleValue
}

final def toFloat: Float = this match {
case XmlByte(value) => value.toFloat
case XmlShort(value) => value.toFloat
case XmlInt(value) => value.toFloat
case XmlLong(value) => value.toFloat
case XmlFloat(value) => value
case XmlDouble(value) => value.toFloat
case XmlBigInt(value) => value.floatValue
case XmlBigDecimal(value) => value.floatValue
}

Expand All @@ -110,10 +94,7 @@ object XmlData {
}

final def toLong: Option[Long] = this match {
case XmlByte(value) => Some(value.toLong)
case XmlShort(value) => Some(value.toLong)
case XmlInt(value) => Some(value.toLong)
case XmlLong(value) => Some(value)
case XmlLong(value) => Some(value)
case XmlFloat(value) =>
Option(new JavaBigDecimal(java.lang.Float.toString(value)))
.filter(XmlNumber.bigDecimalIsValidLong)
Expand All @@ -122,7 +103,6 @@ object XmlData {
Option(JavaBigDecimal.valueOf(value))
.filter(XmlNumber.bigDecimalIsValidLong)
.map(_.longValue)
case XmlBigInt(value) => Try(value.toLong).toOption
case XmlBigDecimal(value) => Try(value.toLongExact).toOption
}
}
Expand All @@ -140,13 +120,9 @@ object XmlData {
) <= 0
}

private[xml] final case class XmlByte(value: Byte) extends XmlNumber
private[xml] final case class XmlShort(value: Short) extends XmlNumber
private[xml] final case class XmlInt(value: Int) extends XmlNumber
private[xml] final case class XmlLong(value: Long) extends XmlNumber
private[xml] final case class XmlFloat(value: Float) extends XmlNumber
private[xml] final case class XmlDouble(value: Double) extends XmlNumber
private[xml] final case class XmlBigInt(value: BigInt) extends XmlNumber
private[xml] final case class XmlBigDecimal(value: BigDecimal) extends XmlNumber

// ------------------------------------//
Expand All @@ -156,21 +132,14 @@ object XmlData {
case XmlChar(value) => value.toString
case XmlBool(value) => value.toString
case XmlArray(value) => value.mkString(",")
case XmlByte(value) => value.toString
case XmlShort(value) => value.toString
case XmlInt(value) => value.toString
case XmlLong(value) => value.toString
case XmlFloat(value) => value.toString
case XmlDouble(value) => value.toString
case XmlBigInt(value) => value.toString
case XmlBigDecimal(value) => value.toString
}

implicit val order: Order[XmlNumber] = {
Order.from {
case (XmlByte(x), XmlByte(y)) => x.compareTo(y)
case (XmlShort(x), XmlShort(y)) => x.compareTo(y)
case (XmlInt(x), XmlInt(y)) => x.compareTo(y)
case (XmlLong(x), XmlLong(y)) => x.compareTo(y)
case (XmlDouble(x), XmlDouble(y)) => java.lang.Double.compare(x, y)
case (XmlFloat(x), XmlFloat(y)) => java.lang.Float.compare(x, y)
Expand Down
Empty file.
13 changes: 9 additions & 4 deletions core/src/test/scala/cats/xml/XmlParserSuite.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package cats.xml

import cats.xml.utils.Debug

import scala.util.{Success, Try}

class XmlParserSuite extends munit.FunSuite {

import cats.xml.implicits.*

Debug.enable(
xmlPrinterPrintTypesName = true
)

test("XmlParser.parseString") {
assertEquals(
obtained = XmlParser[Try].parseString(
Expand Down Expand Up @@ -102,15 +108,14 @@ class XmlParserSuite extends munit.FunSuite {
)
}

test("XmlParser.parseString with long number that should be parsed as String") {
val xml: XmlNode =
xml"""<Data value="5340595900475325933418219074917"/>"""
test("XmlParser.parseString with long number that should be parsed as BigDecimal") {
val xml: XmlNode = xml"""<Data value="5340595900475325933418219074917123456789123456789"/>"""

assertEquals(
obtained = xml,
expected = XmlNode("Data")
.withAttributes(
"value" := "5340595900475325933418219074917"
"value" := BigDecimal("5340595900475325933418219074917123456789123456789")
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ object VeryLongNumericString {

implicit val arb: Arbitrary[VeryLongNumericString] =
Arbitrary(
Gen.numStr.suchThat(_.length > 31).map(VeryLongNumericString(_))
Gen.numStr.suchThat(_.length >= 31).map(VeryLongNumericString(_))
)
}

0 comments on commit bd0a694

Please sign in to comment.