-
Notifications
You must be signed in to change notification settings - Fork 108
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added JsonLong and JsonDouble cases for JsonNumber #116
- Loading branch information
1 parent
fe3c6bf
commit b405f23
Showing
14 changed files
with
212 additions
and
45 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,5 @@ target | |
/project/boot | ||
*.swp | ||
repl-port | ||
*~ | ||
tags |
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
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
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
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,87 @@ | ||
package argonaut | ||
|
||
import scalaz.Equal | ||
import scalaz.Scalaz._ | ||
import monocle.function._ | ||
import monocle.std._ | ||
|
||
/** | ||
* JSON numbers with optimization by cases. | ||
* Note: Javascript numbers are 64-bit decimals. | ||
*/ | ||
sealed abstract class JsonNumber { | ||
import Json._ | ||
|
||
def toDouble: Double | ||
def toFloat: Float | ||
def toInt: Int | ||
def toLong: Long | ||
def toShort: Short | ||
|
||
/** Safely coerce to an `Int` if this number fits in an `Int`, otherwise `None` */ | ||
def safeInt: Option[Int] = safeCast[Double, Int].getOption(toDouble) | ||
|
||
/** Safely coerce to a `Long` if this number fits in a `Long`, otherwise `None` */ | ||
def safeLong: Option[Long] = { | ||
val n = toDouble | ||
(n.floor == n) option toLong | ||
} | ||
|
||
def isNaN: Boolean = false | ||
def isInfinity: Boolean = false | ||
|
||
/** | ||
* Construct a JSON value that is a number. | ||
* | ||
* Note: NaN, +Infinity and -Infinity are not valid json. | ||
*/ | ||
def asJson: Option[Json] = | ||
(!isNaN && !isInfinity).option(JNumber(this)) | ||
|
||
/** | ||
* Construct a JSON value that is a number. Transforming | ||
* NaN, +Infinity and -Infinity to jNull. This matches | ||
* the behaviour of most browsers, but is a lossy operation | ||
* as you can no longer distinguish between NaN and Infinity. | ||
*/ | ||
def asJsonOrNull: Json = | ||
asJson.getOrElse(jNull) | ||
|
||
/** | ||
* Construct a JSON value that is a number. Transforming | ||
* NaN, +Infinity and -Infinity to their string implementations. | ||
* | ||
* This is an argonaut specific transformation that allows all | ||
* doubles to be encoded without losing information, but aware | ||
* interoperability is unlikely without custom handling of | ||
* these values. See also `jNumber` and `jNumberOrNull`. | ||
*/ | ||
def asJsonOrString: Json = | ||
asJson.getOrElse(jString(toString)) | ||
} | ||
|
||
case class JsonLong(value: Long) extends JsonNumber { | ||
def toDouble = value.toDouble | ||
def toFloat = value.toFloat | ||
def toInt = value.toInt | ||
def toLong = value | ||
def toShort = value.toShort | ||
} | ||
case class JsonDouble(value: Double) extends JsonNumber { | ||
def toDouble = value | ||
def toFloat = value.toFloat | ||
def toInt = value.toInt | ||
def toLong = value.toLong | ||
def toShort = value.toShort | ||
override def isNaN = value.isNaN | ||
override def isInfinity = value.isInfinity | ||
} | ||
|
||
object JsonNumber { | ||
implicit val JsonNumberEqual: Equal[JsonNumber] = new Equal[JsonNumber] { | ||
def equal(a: JsonNumber, b: JsonNumber) = a match { | ||
case JsonLong(n) => n == b.toLong | ||
case JsonDouble(n) => n == b.toDouble | ||
} | ||
} | ||
} |
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
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
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
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
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
Oops, something went wrong.