cheshire
cheshire copied to clipboard
Extended encoding support for proxy / Superclasses
Hi
And thanks for a fine library!
I'm missing one little piece of functionality. Sometimes I'd like to proxy an object and add some info, but then the correct encoding method is not called. More concretely I'd like to format some instances of java.util.Date
differently than others.
Example setup and usage:
(defn wrap-date
([^Date d] (wrap-date d {}))
([^Date d _meta]
(proxy [Date IObj] [(.getTime d)]
(meta [] _meta)
(withMeta [m] (wrap-date d m)))))
(wrap-date (Date.) {:format-string "yyyy-MM-dd"})
=> #inst"2019-04-05T18:38:13.985-00:00" ; looks like a regular Date, but has metadata
Problem:
; (class (wrap-date (Date.) {:format-string "yyyy-MM-dd"}))
; => cheshire.generate.proxy$java.util.Date$IObj$82d48561
(defn generate [^JsonGenerator jg obj ^String date-format ^Exception ex key-fn]
(get (:impls JSONable) (class obj)) (#'to-json obj jg)
; This will not match
(i? Date obj) (let [sdf (doto (SimpleDateFormat. date-format)
(.setTimeZone (SimpleTimeZone. 0 "UTC")))]
(write-string ^JsonGenerator jg (.format sdf obj)))
; This will match however
Possible solution:
; Given that (.getSuperclass (class (wrap-date (Date.))))
; => java.util.Date
(defn generate [^JsonGenerator jg obj ^String date-format ^Exception ex key-fn]
(get (:impls JSONable) (class obj)) (#'to-json obj jg)
(get (:impls JSONable) (.getSuperclass (class obj))) (#'to-json obj jg)
Not sure if this is a good solution, but it should work, and does not break existing tests. What do you think?
Thanks and kind regards.
I ended up creating a small project for extending java.util.Date
and implementing clojure.lang.IObj
for this task: https://github.com/ivarref/datewrapper
That solves my problem (but not the general case) ...
Thinking about this, something that concerns me about:
(get (:impls JSONable) (.getSuperclass (class obj))) (#'to-json obj jg)
Is what happens when the superclass of an object implements to-json
differently than the subclass? I think I need a concrete test to know for sure (more playing around with it on my end)