-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Streaming #55
Streaming #55
Conversation
Hi @Deraen, any update on this? |
Trying to find my notes about this... hmm. I think I was a bit unhappy The parser object already has reference to Jsonista ObjectMapper, so calling |
Hi @Deraen, been a while since we've both looked at it :)
Via reader:
Unless you want to expose the type for the parser as an argument. |
@bsless The last test cases shows the use case for the parser. To read and array lazily from a JSON stream, which is not an top level array, user needs to use parser to navigate to specific element and then the array can be read. In #53 we already discussed difference to I think the API we'll provide should cover both cases: top level arrays, reading e.g. large GeoJSON file feature arrays, and also read log files without top level array start, separator and end elements. Though I think the last case is already covered by reading the file using Reader, readLine and then parsing each line with |
Piping in that this last one is common enough that it's called ndjson :) |
Thank you for helping me get back into context :) |
@bsless If you have idea how to clean up the implementation, go ahead. Maybe the problem I had was that parser I wonder if there is something on Jackson API to handle these cases better.
Makes sense. |
@Deraen digging through Jackson's API, it should be possible to get the parser from the (seq (read-values "{\"a\":1}\n{\"b\":2}"))
;; => ({"a" 1} {"b" 2}) Another opportunity I found was making the read-values kv-reducible as well. (iterator-seq (.readValuesAs (doto (create-parser (write-value-as-string [1 2]) default-object-mapper) .nextToken) Object))
;; => ([1 2]) At this point I think we'll need a good reason to connect the parser and read values. If we want to clean the implementation up, maybe a macro would be in place to reduce some boilerplate, but otherwise they can stand on their own. I managed to come up with a macro like: (defmacro extend-types
{:style/indent [1 :defn]}
[types & args]
`(do
~@(for [[[p] impls] (partition 2 (partition-by symbol? args))
t types]
`(extend-type ~t ~p ~@impls))))
(extend-types [File URL String Reader InputStream]
ReadValue
(-read-value [this ^ObjectMapper mapper]
(.readValue mapper this ^Class Object))
CreateParser
(-create-parser [this ^ObjectMapper mapper]
(.createParser (.getFactory mapper) this))
ReadValues
(-read-values [this ^ObjectMapper mapper]
(.readValues (.readerFor mapper ^Class Object) this))) Which reduces the boilerplate significantly |
Boilerplate on the library code isn't a problem. Macros can make namespace load times much worse and make it harder to understand the code. |
Alright, where does it leave us with regards to everything else? What do you think about the relation between |
I think this can be closed since #82 is merged |
Continued from #53
I've added create-parser function for accessing low-level parser & extended ReadValues for parser.
This allows finding array inside Json objects etc. and then reading and array of values from that.
Probably there could be similar functions for writer.