Transforming the data after it comes out of the parser can be cumbersome with complex data structures though, it would be nice to have a way for the parser to return the data in the desired format.
I updated clojure.contrib.json with the ability to add custom deserializers: (def *deserializers* (atom {})) (defn add-deserializer [k deserializer] (swap! *deserializers* #(assoc % k deserializer))) (defn remove-deserializer [k] (swap! *deserializers* #(dissoc % k))) (defn- read-json-object [#^PushbackReader stream keywordize?] ;; Expects to be called with the head of the stream AFTER the ;; opening bracket. (loop [i (.read stream), key nil, result (transient {})] (let [c (char i)] (cond (= i -1) (throw (EOFException. "JSON error (end-of-file inside object)")) (Character/isWhitespace c) (recur (.read stream) key result) (= c \,) (recur (.read stream) nil result) (= c \:) (recur (.read stream) key result) (= c \}) (if (nil? key) (persistent! result) (throw (Exception. "JSON error (key missing value in object)"))) :else (do (.unread stream i) (let [element (read-json-reader stream keywordize? true nil)] (if (nil? key) (if (string? element) (recur (.read stream) element result) (throw (Exception. "JSON error (non-string key in object)"))) (let [elm-key (if keywordize? (keyword key) key) deserializer (get @*deserializers* elm- key)] (recur (.read stream) nil (assoc! result elm-key (if deserializer (deserializer element) element))))))))))) all I had to change was the part where the key and value are put in the map to first check if there is a deserializer registered and use it instead of storing the data directly, then I can use it as follows (defn write-date [date #^PrintWriter out] (.print out (str "\"" (.format (new java.text.SimpleDateFormat "MMM dd, yyyy hh:mm:ss a") date) "\""))) (extend Date Write-JSON {:write-json write-date}) (add-deserializer :age #(.parse (new java.text.SimpleDateFormat "MMM dd, yyyy hh:mm:ss a") %)) (let [data {:name "John" :age (new java.util.Date) :address [:street "1 Bay" :city "Toronto"]} encoded (json-str data)] (println encoded) (println "decoded" (read-json encoded))) Would there be an issue with adding something like that to the contrib? On Aug 21, 1:52 pm, Stuart Sierra <the.stuart.sie...@gmail.com> wrote: > I suppose one could override the (private) read-json-object function > to transform maps after they are read, based on the presence of > certain keys. But that would seriously complicate the reader. It's > probably easier to transform the data after it comes back from the > JSON parser. > > -S > > On Aug 20, 5:06 pm, Dmitri <dmitri.sotni...@gmail.com> wrote: > > > > > > > > > My concern is more to do with the reader, I think extending writer > > works quite well, it would be nice if it was possible to do the same > > thing with the reader, so you could specify how to deserialize > > specific types of data. Right now it seems to be baked into read-json- > > reader and there's no easy way to extend it. > > > Maybe it could be possible to specify how to deserialize data based on > > the key names, then if the reader hits a key with the given name it > > would try to deserialize it with the given function or something? > > > On Aug 20, 3:32 pm, Stuart Sierra <the.stuart.sie...@gmail.com> wrote: > > > > Since there is no standard for how to represent dates in JSON, it is > > > unlikely to be built in. But you can extend the writer with > > > application-specific date formats. > > > -S > > > > On Aug 20, 2:15 pm, Dmitri <dmitri.sotni...@gmail.com> wrote: > > > > > I'm currently using Dan Larkin's clojure-json, and it provides a way > > > > to serialize and deserialize dates, it also provides the option to > > > > specify custom serializers, eg: > > > > > (defn date-encoder > > > > [date writer pad current-indent start-token-indent indent- > > > > size] > > > > (.append writer (str start-token-indent \" date \"))) > > > > > I was looking at switching to using the json implementation in clojure- > > > > contrib, but noticed that it doesn't handle dates nor does it provide > > > > a way to register custom serializers, is there a plan to implement > > > > that in the future, or is the proper approach to simply extend Write- > > > > JSON whenever a custom serializer/deserializer is needed. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en