circe 0.7.0-M1
Pre-releaseThis milestone release is intended as a preview of changes that will be introduced in 0.7.0 and should not be used in production or any other situation where you need things to be correct! The tests pass but there are fairly major internal changes here, and there may be more before 0.7.0 is released (which I'm hoping will happen by the end of next week). So please try out this milestone, but stick with 0.6.1 where it matters for now.
Upgrading
The biggest change in this release is to the representation of cursor and cursor operations (see #459 for the details). Both have been flattened: Cursor
and HistoryOp
are gone entirely, and HCursor
now extends ACursor
instead of being wrapped by it.
Many users are likely to be completely unaffected by these rearrangements. The two most common changes that will be necessary are related to the focus
and acursor
methods on HCursor
. The focus
method on HCursor
now returns an Option[Json]
instead of simply Json
. If you have a cursor that's statically typed as an HCursor
, you can now call value
to get access to the Json
value at the focus directly. If you're calling c.acursor
on a c: HCursor
, you can just remove the method call, since the HCursor
is already an ACursor
.
Vector
also now replaces List
in all API methods related to JSON arrays. You can simply call toVector
or toList
as necessary to fit your existing code, or you can rework your existing code to use vectors instead of lists.
If you're currently working with HistoryOp
or Cursor
values directly, the upgrade will be a little more work. As always, please ask a question on Gitter or Stack Overflow if you run into problems.
Why are you doing this to us?
These are big changes, but I think they're worthwhile. For one thing, the pull request introducing the cursor rewrite nets 397 deletions, and the API is a couple of unnecessary types lighter. These changes also significantly improve decoding performance. Here are before-and-after results, with Argonaut and Spray included for comparison:
Benchmark Mode Cnt Score Error Units
DecodingBenchmark.decodeFoosC (0.6.0) thrpt 20 4507.107 ± 34.709 ops/s
DecodingBenchmark.decodeFoosC (new) thrpt 20 8905.988 ± 135.244 ops/s
DecodingBenchmark.decodeFoosA thrpt 20 1493.519 ± 35.113 ops/s
DecodingBenchmark.decodeFoosS thrpt 20 9573.566 ± 43.642 ops/s
DecodingBenchmark.decodeIntsC (0.6.0) thrpt 20 21813.721 ± 202.030 ops/s
DecodingBenchmark.decodeIntsC (new) thrpt 20 49015.320 ± 3502.542 ops/s
DecodingBenchmark.decodeIntsA thrpt 20 9097.675 ± 57.517 ops/s
DecodingBenchmark.decodeIntsS thrpt 20 37520.796 ± 1154.570 ops/s
Most applications won't suddenly be twice as fast, of course (in the city lots tutorial project this only translates into about a 15% improvement in speed, for example), but it's still a pretty big boost, and together with the simplifications I think it's worth it.
Other changes
There are a few other changes since 0.6.1:
- Bazillions of negative numbers that nobody cares about can now be decoded as
BigInt
s (#482). ObjectEncoder
now has aContravariant
instance (thanks to @backuitist in #472).arrFilter
andobjFilter
in circe-optics have now been renamed (tofilterByIndex
andfilterByField
), and newfilter
andunsafeFilter
methods have been introduced (thanks @julien-truffaut, #473).truncateToLong
now returns correct results for large values (#480).- JSON string values are now parsed as JSON numbers during decoding to integral types, instead of using Scala's
toInt
, etc. (#485).
The project has also moved from my personal GitHub account to a brand new circe organization—thanks to @github for helping to make this happen.
Lastly, special thanks go to @jonas for simplifying the build (#474), moving us to @47deg's sbt-microsites (#462), and making many other much-needed documentation improvements.