Closed jeaye closed 3 years ago
Ok, I've reworked this a bit.
writeRawValue
, so now it will work with pretty printingThis is about all the time I have for this, so, if you're interested, please do merge. Otherwise, we'll just run with the fork.
Thanks for the help with this!
These were timed using some chunk of production data and criterium's quick-bench
.
Did a quick spike on making this more generic. What do you think of this:
(def mapper
(j/object-mapper
{:decode-key-fn true
:modules [(jt/module
{:handlers {Keyword {:tag "!kw"
:encode jt/encode-keyword
:decode keyword}
PersistentHashSet {:tag "!set"
:encode jt/encode-collection
:decode set}}})]}))
(-> {:kikka #{:kukka :kakka}}
(j/write-value-as-string mapper)
(doto prn)
(j/read-value mapper))
; prints "{\"kikka\":[\"!set\",[[\"!kw\",\"kukka\"],[\"!kw\",\"kakka\"]]]}"
; => {:kikka #{:kukka :kakka}}
Yeah, I dig it. We ended up also adding set support, but I don't think I force pushed it yet, since there didn't seem to be any interest in this PR. Your proposal is much more general, so I think it's a good way forward. In terms of the tagged values working, we've seen no issues running this in production since October.
Thanks for the PR and the perf report! will modify a bit to be generic.
given data:
{:results [{:tags [:jsonista.json-perf-test/kikka :jsonista.json-perf-test/kukka],
:email "morris.lambert@example.com",
:phone "08-2274-7839",
:name {:title "mr", :first "morris", :last "lambert"},
:nat "AU",
:created #inst"2020-12-26T11:01:29.531-00:00",
:login {:username "smallbird414",
:password "carole",
:salt "yO9OBSsk",
:md5 "658323a603522238fb32a86b82eafd55",
:sha1 "289f6e9a8ccd42b539e0c43283e788aeb8cd0f6e",
:sha256 "57bca99b2b4e78aa2171eda4db3f35e7631ca3b30f157bdc7ea089a855c66668"},
:dob "1950-07-13 09:18:34",
:id {:name "TFN", :value "740213762"},
:picture {:large "https://randomuser.me/api/portraits/men/95.jpg",
:medium "https://randomuser.me/api/portraits/med/men/95.jpg",
:thumbnail "https://randomuser.me/api/portraits/thumb/men/95.jpg"},
:gender "male",
:registered "2012-04-07 00:05:32",
:cell "0452-558-702",
:location {:street "7239 hillcrest rd",
:city "nowra",
:state "australian capital territory",
:postcode 7541}}],
:info {:seed "fb0c2b3c7cedc7af", :results 1, :page 1, :version "1.1"}}
some numbers:
;; 28µs
(title "jsonista-tagged")
(cc/quick-bench
(j/read-value (j/write-value-as-bytes data mapper) mapper))
;; 190µs
(title "edn")
(cc/quick-bench
(edn/read-string (pr-str data)))
;; 82µs
(title "transit")
(cc/quick-bench
(<-transit (->transit data)))
;; 53µs
(title "nippy")
(cc/quick-bench
(nippy/thaw (nippy/freeze data)))
This aims to open the doors for jsonista to become a viable alternative for people currently using EDN with transit by providing a way to encode EDN types using a tagged JSON list. Currently, only keywords are supported.
Regarding
TaggedValueOrPersistentVectorDeserializer
, it's worth noting that it doesn't just peek for a tag and then fall back on the defaultPersistentVectorDeserializer
, since peeking seemed to require a call tonextValue()
and I found no way to backtack. So it seems I need to try building the transient and then just special-case the zeroth element to check for the tag.Right now, it doesn't do anything special with mapping tags to different types in the Java code, since there's only one and I figure that change can be made when it's needed. The Clojure API, however, remains more general, since the tag needs to come in as a key. This will make adding new keys to the API trivial, if more types are supported in the future.
This closes #35.