typelevel / jawn Goto Github PK
View Code? Open in Web Editor NEWJawn is for parsing jay-sawn (JSON)
Jawn is for parsing jay-sawn (JSON)
i tried to run the benchmarks after a clean checkout of the project, but compilation fails.
[error] /Users/tlossen/Code/jawn/benchmark/src/main/scala/jawn/ParseLongBench.scala:98: value += is not a member of Long
[error] Expression does not convert to assignment because:
[error] not found: value Util
[error] expansion: sum = sum.+(<Util: error>.<parseLong: error>(css(i)))
[error] sum += Util.parseLong(css(i))
[error] ^
[error] /Users/tlossen/Code/jawn/benchmark/src/main/scala/jawn/ParseLongBench.scala:108: value += is not a member of Long
[error] Expression does not convert to assignment because:
[error] not found: value Util
[error] expansion: sum = sum.+(<Util: error>.<parseLongUnsafe: error>(css(i)))
[error] sum += Util.parseLongUnsafe(css(i))
[error] ^
[error] /Users/tlossen/Code/jawn/benchmark/src/main/scala/jawn/ParseLongBench.scala:126: not found: value Util
[error] @Benchmark def stringValueSafe(): Long = Util.parseLong(str)
[error] ^
[error] /Users/tlossen/Code/jawn/benchmark/src/main/scala/jawn/ParseLongBench.scala:127: not found: value Util
[error] @Benchmark def seqValueSafe(): Long = Util.parseLong(seq)
[error] ^
[error] /Users/tlossen/Code/jawn/benchmark/src/main/scala/jawn/ParseLongBench.scala:131: not found: value Util
[error] @Benchmark def stringValueUnsafe(): Long = Util.parseLongUnsafe(str)
[error] ^
[error] /Users/tlossen/Code/jawn/benchmark/src/main/scala/jawn/ParseLongBench.scala:132: not found: value Util
[error] @Benchmark def seqValueUnsafe(): Long = Util.parseLongUnsafe(seq)
[error] ^
[warn] one warning found
[error] 6 errors found
[error] (benchmark/compile:compileIncremental) Compilation failed
[error] Total time: 11 s, completed Jul 5, 2017 10:40:07 AM
maybe some dependency missing?
(scala version: 2.12.2)
For example:
scala> jawn.ast.JParser.parseFromString("nul!")
res1: scala.util.Try[jawn.ast.JValue] = Failure(jawn.ParseException: expected null got n (line 1, column 1))
scala> jawn.ast.JParser.parseFromString("tru!")
res2: scala.util.Try[jawn.ast.JValue] = Failure(jawn.ParseException: expected true got t (line 1, column 1))
scala> jawn.ast.JParser.parseFromString("fals!")
res3: scala.util.Try[jawn.ast.JValue] = Failure(jawn.ParseException: expected false got f (line 1, column 1))
this is blocking circe at circe/circe#1015
I want to introduce sbt-doge. We will need it to add support for 2.12.0-RC1, and also so we can start dropping 2.10 from our support projects as their respective JSON libraries drop 2.10 support.
However, it doesn't work out-of-the-box with sbt-release.
@eed3si9n pointed me at the play build which seems to use both, but has other structural differences.
I'll try to look at this soon, but if anyone is dying to become a Jawn contributor and knows a bit about SBT this is your chance!
Escalating Twitter discussion discussion beyond 140 characters:
I created jawn-streamz for parsing scalaz-streams of ByteVectors to any Jawn-supported JSON AST. I think it could make a good Jawn module, but I also have the use case of serializing JSON back to ByteVectors. It would be splendid if this could also be done through a facade, and keep streamz support shielded from the Great JSON Framework Holy War.
Open questions:
I am editing my issue as I found the actual problem and it has nothing to do with the previous entry.
The real problem is that Jawn seems unable to parse germanic umlaut, in that case the content is just discarded.
Is it a normal behaviour?
Thx!
Just in case, I have a test case for the problem
https://github.com/agourlay/jawn-umlaut-issue
https://travis-ci.org/agourlay/jawn-umlaut-issue/jobs/41350846
This seems to be incorrect to me.
Should it not be:
def jint(s: String) = JInt(java.lang.Integer.parseInt(s))
I know I can access each indexing e.g. .get(0)
but how do I iterate over it?
val list = jawn.ast.JParser.parseFromString("""{"stuff": [1,2,3]}""").get
val stuff = list.get("stuff")
for (item <- stuff) println(item)
I have tried to use the AsyncParser
but I couldn't figure out how to get anything out other than a single jsobject
as defined by my AST (in this case Play JSON).
Assume I have something like:
{
"name": "thing"
"elements": [{
"key": "a",
"value": "alice"
},{
"key": "b",
"value": "bob"
},
...
]
}
How can I get it so that each call to absorb
will return zero or more elements?
Are there plans to support Play 2.4.x?
Play's JsObject
constructor parameter changed from a Seq
to a Map
(the Seq
version is now on the companion object). jawn
is compiled for the old version, leading to MethodNotFound
exceptions.
Not sure how applicable this is to Jawn, but should we look at using https://github.com/densh/scala-offheap to both improve the performance (but more importantly the latency/memory characteristics) of the parser?
Since the new BlueEyes JSON parser was pulled from Jawn, we should be able to claw these features and fixes back for our own use!
@non when I use jawn lib, some error happens below:
[info] java.lang.NumberFormatException: For input string: "1493016373269"
[info] at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
[info] at java.lang.Integer.parseInt(Integer.java:583)
[info] at java.lang.Integer.parseInt(Integer.java:615)
[info] at jawn.support.json4s.Parser$$anon$1.jint(Parser.scala:15)
[info] at jawn.support.json4s.Parser$$anon$1.jint(Parser.scala:10)
[info] at jawn.Parser.parseNum(Parser.scala:188)
[info] at jawn.Parser.rparse(Parser.scala:392)
[info] at jawn.AsyncParser.churn(AsyncParser.scala:213)
[info] at jawn.AsyncParser.finish(AsyncParser.scala:98)
[info] at jawnstreamz.package$$anonfun$parseJson$1$$anonfun$apply$2.apply(package.scala:31)
How to fix it ?
When we update to 0.11.0 we should bump the following library versions:
(I will add to this list as new versions are discovered.)
We should also consider dropping Rojoma v2 and standardizing on Rojomva v3.
For extra points, please refer to Reference https://gitter.im/non/jawn?at=55a7ae4de881cbd76356e350 Summary:
InTheNow: Main issues are
ReadableByteChannel
and java.io - File, FileInputStream
sjrd: No, java.io.File cannot be implemented in Scala.js.
sjrd: You could implement in Scala.js-goodies-for-Node.js, but not in general, obviously.
non: we could potentially try to make the I/O parts JVM only
sjrd: Yes, that would probably be the best thing to do, here.
I am exploring the capacity of the async. parser and I think that the current implementation does not properly release its memory.
My current use case requires parsing rather long Stream[String] containing JSON objects and I can see that the Heap usage just keeps on increasing until it eventually blows up.
I have created a project to reproduce the issue https://github.com/agourlay/jawn-heap
Is this a normal behavior and is parsing this kind of long (infinite ) stream a use case for Jawn's async. parser?
Thanks!
This method in jawn.ChannelParser
def fromFile[J](f: File, bufferSize: Int = DefaultBufferSize): SyncParser[J] =
if (f.length < ParseAsStringThreshold) {
val bytes = new Array[Byte](f.length.toInt)
val fis = new FileInputStream(f)
fis.read(bytes)
new StringParser[J](new String(bytes, "UTF-8"))
} else {
new ChannelParser[J](new FileInputStream(f).getChannel, bufferSize)
}
For the string parser case, opens input stream, reads the data but never closes it. That leaves file open and can cause problems (it did cause problems for me on windows).
This is just one line to fix, I will try to submit a PR.
Just making a note of this so I don't forget about it.
Given some invalid JSON like this:
import jawn.{ AsyncParser, NullFacade, Parser }
import java.io.ByteArrayInputStream, java.nio.channels.Channels
val json = "[1, 2,\nx3]"
val ch = Channels.newChannel(new ByteArrayInputStream(json.getBytes))
Different Jawn parser implementations give three different locations for the failure:
scala> println(Parser.parseFromString(json)(NullFacade))
Failure(jawn.ParseException: expected json value got x (line 2, column 8))
scala> println(Parser.parseFromChannel(ch)(NullFacade))
Failure(jawn.ParseException: expected json value got x (line 2, column 2))
scala> println(Parser.async(jawn.AsyncParser.UnwrapArray)(NullFacade).absorb(json)(NullFacade))
Left(jawn.ParseException: expected json value got x (line 2, column 1))
The async parser is the only correct one.
I recently encountered an issue where £
would be stripped away from json string when the string also contains a "
. Here is a relatively small test using argonaut facade:
case class Example(i: Int, s: String)
object Example {
implicit val codec = Argonaut.casecodec2(Example.apply, Example.unapply)("i", "s")
}
val name = "hel£££l \"o £ "
val example = Example(5, name)
val s = Argonaut.nospace.pretty(Example.codec.encode(example)) // {"i":5,"s":"hel£££l \"o £ "}
implicit val facade = jawn.support.argonaut.Parser.facade
val parser = AsyncParser[Json](AsyncParser.SingleValue)
val parsedString = parser.absorb(s)
.fold(_ => None, _.headOption)
.flatMap(_ -| "s")
.flatMap(_.as[String].toOption)
assert(parsedString === Some(name)) // Some("hell "o ") did not equal Some("hel£££l "o £ ")
The lack of a 2.13.0-M5 release for jawn-parser has been blocking a circe release for 2.13.0-M5 for over a month now, and @eed3si9n has a working PR open that's two months old with no feedback from any Jawn maintainers (which as far as I know is just Erik?).
I asked on Gitter last month about things us non-maintainers could do to help speed up PR merges and releases, also with no response.
@non (and @milessabin, @ceedubs, @larsrh, etc.), how would you feel about moving the project to https://github.com/typelevel/jawn and publishing to org.typelevel
? This would spread the maintenance burden and let us avoid blocking everything downstream for weeks or months at a time. If you'd like, @non, we could agree on some kind of arrangement that would require your approval for any non-trivial changes.
/cc @SethTisue
After the results of SLIP-28/scala contributors, the ScalaJSON AST has finally been put into the scala platform (see https://github.com/mdedetrich/scalajson for more details). Currently its a 1.0.0-M1
release however a full release is expected in a few days if there are no major issues).
This ticket is to describe integration with Jawn, and how it would possibly work. A really ideal situation would be to integrate the scalajson.ast.unsafe.JValue
into the core Jawn parser (and I would also be interested to see the results in regards to parsing). Doing so would also automatically expose the standard safe AST to any users and would provide "automatic" interopt once the other frameworks/json libraries adopt scalaJSON.
If this doesn't work out, it can always be added as either a module (least ideal situation) or a first class type that jawn exposes. Let me know if there are any ways that I can help!
Add support for Play 2.5
I will make a pull request for this, as it should be just a single bump of a version
Commenting out line 231 in AdHocBenchmarks.scala lets the other benchmarks run
Currently (and historically) JObject
and JArray
are mutable. They are case classes wrapping mutable data structures.
@ijuma wisely points out that this is maybe not the best for folks who want to use long-lived JObject
instances, and suggests it would be nice to make the types safer.
Here are some possible scenarios (from least to most safe):
(I) Types are constructed with mutable collections, and expose them via getters. This is the status quo.
(II) Types are still constructed with mutable collections, but don't expose them directly. Data is accessed via read-only methods, or by copying the underlying data into a new structure. Mostly safe, although a fiendish user could construct a JObject
, hang onto the mutable map, and change it later. (The parser is guaranteed not to do this.) The downside here is that it becomes more expensive to use JObject
and JArray
as a scratchpad during parse/modify/save cycles. (This is probably not a big deal.)
(III) Provide a public constructor using an immutable map, and a private constructor used internally that uses mutable maps. This way, users can't play games with mutable data, and (assuming the parser doesn't do anything fishy) we are totally safe. The downside here is that the objects become more expensive to construct, or that we have to add different JObject
types for the different backing structures.
(IV) Convert Jawn to use immutable data structures only, possibly using builders in the Parser. This solves the safety issues, but probably increases the memory footprint and might have other performance issues.
Personally I think I prefer (II), but I'm open to hearing other suggestions.
This is relatively slow for some reason. Figure out why!
For example, on my machine:
jawn.ast.JParser.parseFromString((" " * 2000) + "null")
Unfortunately Parser#parser(i: Int)
can't be @tailrec
-ed, but it's pretty straightforward to pull out the whitespace consumption.
does not satisfy the law
".1"
is correctly rejected, but "-.1"
gets parsed successfully:
scala> jawn.Parser.parseFromString("-.1")(jawn.ast.JawnFacade)
res0: scala.util.Try[jawn.ast.JValue] = Success(-.1)
I wanted to confirm that this is a bug and not intentional before I start looking into why it happens.
Could we change JInt
to JLong
at this line ?
jawn is not parsing big integers and crashing with:
java.lang.NumberFormatException: For input string: "1481223311239"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:583)
at java.lang.Integer.parseInt(Integer.java:615)
at jawn.support.json4s.Parser$$anon$1.jint(Parser.scala:15)
at jawn.support.json4s.Parser$$anon$1.jint(Parser.scala:10)
at jawn.Parser.parseNum(Parser.scala:188)
at jawn.Parser.rparse(Parser.scala:392)
There are some smart strategies here:
We should steal some of them.
I'm using jawn in a number of projects, and it's exceedingly difficult to remember to add the custom resolver. This is especially true because once cached in your .ivy/cached
folder, the custom resolver is thereafter unnecessary for your computer but still necessary for other people on other computers without it cached.
As it result, it has come up over and over
Maybe it's my fault I don't regularly clear my ivy cache to make sure I'm not missing a resolver. Maybe it's SBTs fault for not permitting transitive resolvers to intentionally make this error occur over and over for people to "encourage" people to publish things on standard resolvers. Either way, it would be solved if you put jawn on maven central =P
I need this in order to implement a one-pass parse-to-data-type flow in uPickle. Since parsing to a data-type can fail even if the JSON is valid, due to it being the wrong thing (e.g. got-array-expected-dict or got-string-expected-int) I need the current index exposed in the Facade's callback functions in order to throw error messages with the correct position info
http://repo1.maven.org/maven2/org/spire-math/jawn-ast_2.11/0.8.0/jawn-ast_2.11-0.8.0.pom
<?xml version='1.0' encoding='UTF-8'?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>org.spire-math</groupId>
<artifactId>jawn-ast_2.11</artifactId>
<packaging>jar</packaging>
<description>jawn-ast</description>
<url>http://github.com/non/jawn/</url>
<version>0.8.0</version>
<licenses>
<license>
<name>MIT</name>
<url>http://opensource.org/licenses/MIT</url>
<distribution>repo</distribution>
</license>
</licenses>
<name>jawn-ast</name>
<organization>
<name>org.spire-math</name>
<url>http://github.com/non/jawn/</url>
</organization>
<developers>
<developer>
<id>non</id>
<name>Erik Osheim</name>
<url>http://github.com/non</url>
</developer>
</developers>
<scm>
<connection>scm:git:github.com/non/jawn.git</connection>
<developerConnection>scm:git:[email protected]:non/jawn.git</developerConnection>
<url>https://github.com/non/jawn</url>
</scm>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.11.6</version>
</dependency>
<dependency>
<groupId>org.spire-math</groupId>
<artifactId>jawn-parser_2.11</artifactId>
<version>0.8.0</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-bytecode</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-reflection</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_2.11</artifactId>
<version>2.2.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.scalacheck</groupId>
<artifactId>scalacheck_2.11</artifactId>
<version>1.12.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Build.scala
import sbt._
object MyBuild extends Build {
lazy val root = Project("root", file(".")) dependsOn(jawn)
lazy val jawn = RootProject(uri("git://github.com/non/jawn.git"))
}
Error
java.util.NoSuchElementException: None.get
at scala.None$.get(Option.scala:313)
at scala.None$.get(Option.scala:311)
at MyBuild$$anonfun$benchmarkSettings$5$$anonfun$apply$1.apply(Build.scala:81)
at MyBuild$$anonfun$benchmarkSettings$5$$anonfun$apply$1.apply(Build.scala:76)
at sbt.Project$.setProject(Project.scala:226)
at sbt.BuiltinCommands$.doLoadProject(Main.scala:454)
at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:445)
at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:445)
at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:60)
at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:60)
at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:62)
at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:62)
at sbt.Command$.process(Command.scala:95)
at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:100)
at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:100)
at sbt.State$$anon$1.process(State.scala:179)
at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:100)
at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:100)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
at sbt.MainLoop$.next(MainLoop.scala:100)
at sbt.MainLoop$.run(MainLoop.scala:93)
at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:71)
at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:66)
at sbt.Using.apply(Using.scala:25)
at sbt.MainLoop$.runWithNewLog(MainLoop.scala:66)
at sbt.MainLoop$.runAndClearLast(MainLoop.scala:49)
at sbt.MainLoop$.runLoggedLoop(MainLoop.scala:33)
at sbt.MainLoop$.runLogged(MainLoop.scala:25)
at sbt.StandardMain$.runManaged(Main.scala:57)
at sbt.xMain.run(Main.scala:29)
at xsbt.boot.Launch$$anonfun$run$1.apply(Launch.scala:57)
at xsbt.boot.Launch$.withContextLoader(Launch.scala:77)
at xsbt.boot.Launch$.run(Launch.scala:57)
at xsbt.boot.Launch$$anonfun$explicit$1.apply(Launch.scala:45)
at xsbt.boot.Launch$.launch(Launch.scala:65)
at xsbt.boot.Launch$.apply(Launch.scala:16)
at xsbt.boot.Boot$.runImpl(Boot.scala:32)
at xsbt.boot.Boot$.main(Boot.scala:21)
at xsbt.boot.Boot.main(Boot.scala)
scala> jawn.ast.JParser.parseFromString(jawn.ast.JString("\u001e").render(jawn.ast.FastRenderer))
res14: scala.util.Try[jawn.ast.JValue] = Success("\u001e")
scala> jawn.ast.JParser.parseFromString(jawn.ast.JString("\ud8a3").render(jawn.ast.FastRenderer))
res15: scala.util.Try[jawn.ast.JValue] = Success("\ud8a3")
scala> jawn.ast.JParser.parseFromString(jawn.ast.JString("\u001e\ud8a3").render(jawn.ast.FastRenderer))
res13: scala.util.Try[jawn.ast.JValue] = Failure(jawn.IncompleteParseException: exhausted input)
First reported here. I'm not sure if this is a bug or some misunderstanding in how JSON/Unicode works, but presumably anything you stuff into a JSString should be able to survive a round trip right?
I just ran Jawn 0.13.0 through the Parsing JSON is a Minefield tests, and the one failure is for n_string_invalid_unicode_escape.json
, where ["\uqqqq"]
is accepted even though it should not be:
scala> val input = "[\"\\uqqqq\"]"
input: String = ["\uqqqq"]
scala> jawn.ast.JParser.parseFromString(input)
res0: scala.util.Try[jawn.ast.JValue] = Success(["\u0000"])
For example, "1", "1.0" and "1.00" are all considered different values. They should be the same.
There are a couple of $x
s that are just $x
s:
scala> import jawn.ChannelParser
import jawn.ChannelParser
scala> import java.io.ByteArrayInputStream, java.nio.channels.Channels
import java.io.ByteArrayInputStream
import java.nio.channels.Channels
scala> val ch = Channels.newChannel(new ByteArrayInputStream("null".getBytes))
ch: java.nio.channels.ReadableByteChannel = java.nio.channels.Channels$ReadableByteChannelImpl@209ab5df
scala> ChannelParser.fromChannel[Unit](ch, -1)
java.lang.IllegalArgumentException: negative bufferSize ($x)
at jawn.ChannelParser$.computeBufferSize(ChannelParser.scala:37)
at jawn.ChannelParser.<init>(ChannelParser.scala:55)
at jawn.ChannelParser$.fromChannel(ChannelParser.scala:26)
... 38 elided
scala> ChannelParser.fromChannel[Unit](ch, Int.MaxValue / 2 + 2)
java.lang.IllegalArgumentException: bufferSize too large ($x)
at jawn.ChannelParser$.computeBufferSize(ChannelParser.scala:39)
at jawn.ChannelParser.<init>(ChannelParser.scala:55)
at jawn.ChannelParser$.fromChannel(ChannelParser.scala:26)
... 38 elided
These are currently missing
#86 added support for 2.13.0-M1, but it doesn't look like a 2.13 version of jawn was released: http://repo1.maven.org/maven2/org/spire-math/ (also 2.13.0-M2 is out)
Argonaut 6.2-M1 has been released. A facade should be trivial enough, but where does it go?
Jawn is on argonaut-6.0.4, which is Scalaz 7.0. http4s uses argonaut-6.1-M5, which is a necessary upgrade for Scalaz 7.1. Hilarity ensues.
I see three ways out:
At nescala Matthias suggested there was a faster way to check for possible whitespace characters using bitwise logic. We should look into that.
Is there an example of using Jawn with Play Framework 2? For example, obtaining play.api.libs.json.JsValue
from a request body, and doing something with it using Jawn:
def parseJson = Action(parse.json) { implicit request =>
val body: JsValue = request.body
Ok(body)
}
In particular, these cases do not cause jawn to throw an exception:
["Illegal backslash escape: \x15"]
["Illegal backslash escape: \017"]
["tab\ character\ in\ string\ "]
["line\
break"]
[0e]
Whereas they're meant to blow up AFAICT. They blow up correctly in Node.js' JSON.parse
These invalid inputs are taken from http://www.json.org/JSON_checker/. Among those listed, there are others which do not blow up, but these are the ones which blow up in Node.js' and do not blow up in Jawn
It would be handy to have convenience methods for retrieving a number as an Int (quite a common need). This is easily done as an extension method, so I understand if you don't think it should be part of the AST, but I thought I'd bring it up for discussion.
#90 Added support for play 2.6
Unfortunately, my project still has a lot of dependencies available for scala 2.11, thus I'm sticking with the 2.11 version of Play
If I add depdendency to "org.spire-math" %% "jawn-play" % "0.11.0"
the play-json 2.5.15 dep gets evicted (its defined to 2.6.1 in my dependencies)
If I use "org.spire-math" % "jawn-play_2.12" % "0.11.0"
I get a cross version conflict on jawn-play and its dependencies
Do you think theres a possible solution to build a play 2.6 support with scala 2.11 ? I've copied the Parser.scala locally to depende only on jawn-parser
in the meantime
Thanks a lot
Hi Erik,
Very nice piece of work indeed!
Recently i changed from play to your parser for my home brew json operator lib. Because I have quite a lot if "comments" in my json i forked your lib, and wanted to extend it so it can spit out comments or at least skip them. Due to the clarity of your code this is rather easy to do.
I have a question about one design decision you made though. You differentiate between parseStringSimple
and parseStringComplex
, the only difference (from a performance point of view at least) seems to be the inspection of \\
. The price you pay is rescanning the string when it turns out not be simple after all. Was this the sole ground for have two separate methods here, or am I missing something? Would one extra if
statement in the scan make a big difference and not outweigh the disposal of work done?
If not, i would integrate the methods scan regularly until the first \\
and then, if this happens, switch to the collection into the CharBuilder. But, maybe you have already tested this and turned out to be a dead end.
Jawn does not keep the sorting of the json array when parsing it into an JsValue.
Figured it out while parsing https://gist.github.com/breadfan/cbbdbedbeff9046b8d1a
We simply do this in our android app:
val tryJsValue: Try[JsValue] = jawn.support.spray.Parser.parseFromString(jsonString)
val tryObj: Try[RESP] = tryJsValue.map(jsValue => jsValue.convertTo[RESP])
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.