ScalaJSON library, currently provides two minimal implementations of JSON AST, one that is designed for typical use and another that is designed for performance/corner cases.
Built for Scala 2.10.x, 2.11.x, 2.12.x, and 2.13.x milestones.
"org.scala-lang.platform" %% "scalajson" % "1.0.0-M4"
If you are using Scala.js, you need to do
"org.scala-lang.platform" %%% "scalajson" % "1.0.0-M4"
Implementation is in scalajson.ast.JValue
constant
/effective constant
lookup time for scalajson.ast.JArray
/scalajson.ast.JObject
scalajson.ast.JNumber
is a String
which checks if its a valid JSON representation
of a number (http://stackoverflow.com/a/13502497/1519631)
scalajson.ast.JNumber("34.00") == scalajson.ast.JNumber("34")
Float.NaN
/Float.PositiveInfinity
/Float.NegativeInfinity
/Double.NaN
/Double.PositiveInfinity
/Double.NegativeInfinity
it will return a JNull
JNumber("34324")
. Returns an Option[JNumber]
(will return None
if String
isn't a valid number)JNumber.fromString
method is provided which compiles on all platforms and scala versionsscalajson.ast.JObject
is an actual Map[String,JValue]
. This means that it doesn't handle duplicate keys for a scalajson.ast.JObject
,
nor does it handle key ordering.scalajson.ast.JArray
is an Vector
.scalajson.ast.JValue
will
always contain a valid structure that can be serialized/rendered into JSON.
scalajson.ast.JNumber
in Scala.js
(see Scala.js
section for more info)..copy
method of scalajson.ast.JNumber
has been overridden to make sure you can't replace the internal String
with an incorrect numberNumberFormatException
if you use .copy
with an invalid JSON numberscalajson.ast.JValue
Implementation is in scalajson.unsafe.JValue
unsafe.JValue
scalajson.ast.unsafe.JArray
stored as an Array
for JVM and js.Array
for Scala.jsscalajson.ast.unsafe.JObject
stored as an Array
for JVM and js.Array
for Scala.jsscalajson.ast.unsafe.JNumber
stored as a String
Scala
's stdlib
collection's libraryscalajson.ast.unsafe.JObject
.scalajson.ast.unsafe.JNumber
since its represented as a String
String
equality, not number equality.scalajson.ast.unsafe.JNumber("34.00")
is not equal to scalajson.ast.unsafe.JNumber("34")
scalajson.ast.unsafe.JValue
can represent everything that can
can be considered valid under the official JSON spec, even if its not considered sane (i.e.
duplicate keys for a scalajson.ast.unsafe.JObject
).
String
-> scalajson.ast.unsafe.JValue
-> String
since scalajson.ast.unsafe.JObject
preserves ordering/duplicate keyshashCode
and equals
. If you need reference equality
you can use eq
and if you need reference hashCode
you can use .value.hashCode
. Also note that for
deep comparison is used both hashCode
and equals
.Any scalajson.ast.JValue
implements a conversion to scalajson.ast.unsafe.JValue
with a toUnsafe
method and vice versa with a
toStandard
method. These conversion methods have been written to be as fast as possible.
There are some peculiarities when converting between the two AST's. When converting a scalajson.ast.unsafe.JNumber
to a
scalajson.ast.JNumber
, it is possible for this to fail at runtime (since the internal representation of
scalajson.ast.unsafe.JNumber
is a String
and it doesn't have a runtime check). It is up to the caller on how to handle this error (and when),
a runtime check is deliberately avoided on our end for performance reasons.
Converting from a scalajson.ast.JObject
to a scalajson.ast.unsafe.JObject
will produce
an scalajson.ast.unsafe.JObject
with an undefined ordering for its internal Array
/js.Array
representation.
This is because a Map
has no predefined ordering. If you wish to provide ordering, you will either need
to write your own custom conversion to handle this case. Duplicate keys will also be removed for the same reason
in an undefined manner.
Do note that according to the JSON spec, whether to order keys for a JObject
is not specified. Also note that Map
disregards ordering for equality, however Array
/js.Array
equality takes ordering into account.
ScalaJSON JNumber
provides conversions to various number types with the following conventions
toInt
: Safe conversion to Int
which accounts for values such as 1.0
and 100.00e-2
(which both evaluate to 1
).
Also safely detects over/underflow.toLong
: Safe conversion to Long
which accounts for values such as 1.0
and 100.00e-2
(which both evaluate to 1
).
Also safely detects over/underflow.toDouble
: Converts to a Double
assuming the same semantics of Double
(i.e. precision loss is expected).toFloat
: Converts to a Float
assuming the same semantics of Float
(i.e. precision loss is expected).toBigInt
: Converts to a BigInt
which accounts for values such as 1.0
and 100.00e-2
(which evaluates to 1
).
Can construct a BigInt
for as much as memory as the system has (if your system runs out of memory this is considered
undefined behaviour).toBigDecimal
: Converts to a BigDecimal
with all of the caveats of BigDecimal
construction. The BigDecimal
is
constructed with MathContext.UNLIMITED
precision.With the .toFloat
and .toDouble
methods, if you don't want any loss in precision, its advisable to convert to
BigDecimal
first and then work from there, i.e. when working with Decimal
/Float
, its implied that you will
have loss of precision.
Remember that in all cases if these methods are not applicable, you can always use the .value
field to get the
original string representation of the number.
ScalaJSON also provides support for Scala.js.
The usage of Scala.js mirrors the usage of Scala on the JVM however Scala.js also implements
a .toJsAny
method which allows you to convert any
scalajson.ast.JValue
/scalajson.ast.unsafe.JValue
to a Javascript value in Scala.js
.
Note that, since a scalajson.ast.JNumber
/scalajson.ast.unsafe.JNumber
is unlimited
precision (represented internally as a String
), calls to .toJsAny
can lose precision on the
underlying number (numbers in Javascript are represented as double precision floating point number).
You can use the .value
method on a scalajson.ast.JNumber
/scalajson.ast.unsafe.JNumber
to
get the raw string value as a solution to this problem.
Further, toFloat
on JNumber
(see Number Conversions ) can have different semantics on Scala.js, depending on whether you have
strict-floats enabled in your application. Please see the Scala.js semantics page
for more information.
scalajson.JNumber
uses jNumberRegex
to validate whether a number is a valid
JSON number. One can use jNumberRegex
explicitly if you want to use the validation that
is used by scalajson.JNumber
(for example, you may want to validate proper numbers
before creating a scalajson.unsafe.JNumber
).
import scalajson.jNumberRegex
"3535353" match {
case jNumberRegex(_ *) => true
case _ => false
}
ScalaJSON uses the Scala Code of Conduct for all communication and discussion. This includes both GitHub, Gitter chat and other more direct lines of communication such as email.
The project is formatted using scalafmt. Please run scalafmt
in SBT before committing any changes