-
Notifications
You must be signed in to change notification settings - Fork 636
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
IO Streams #1901
IO Streams #1901
Conversation
9947c13
to
8930701
Compare
formats/json-okio/commonMain/src/kotlinx/serialization/json/OkioStreams.kt
Outdated
Show resolved
Hide resolved
formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt
Show resolved
Hide resolved
This implementation is not suitable for release: since |
I see that currently there's an issue with targets that we do support but okio doesn't: I think we should simply ignore them in our tests too. Here are my thoughts:
The only alternative way I see is to move tests to a separate source set instead of a module. To avoid confusion with IDEA, such source set would be included only in -json module for local development, but into both -json and -json-okio modules during the build. WDYT? |
Targets |
formats/json-okio/commonMain/src/kotlinx/serialization/json/okio/OkioStreams.kt
Outdated
Show resolved
Hide resolved
formats/json/jsMain/src/kotlinx/serialization/json/internal/DynamicDecoders.kt
Outdated
Show resolved
Hide resolved
formats/json/jvmMain/src/kotlinx/serialization/json/internal/JvmJsonStreams.kt
Outdated
Show resolved
Hide resolved
formats/json/jvmMain/src/kotlinx/serialization/json/internal/JvmJsonStreams.kt
Outdated
Show resolved
Hide resolved
formats/json/jvmMain/src/kotlinx/serialization/json/internal/JvmJsonStreams.kt
Outdated
Show resolved
Hide resolved
…io/OkioStreams.kt Co-authored-by: Leonid Startsev <[email protected]>
formats/json-okio/commonMain/src/kotlinx/serialization/json/okio/OkioStreams.kt
Outdated
Show resolved
Hide resolved
formats/json/commonMain/src/kotlinx/serialization/json/internal/StreamingJsonDecoder.kt
Outdated
Show resolved
Hide resolved
formats/json/commonMain/src/kotlinx/serialization/json/internal/StringOps.kt
Outdated
Show resolved
Hide resolved
Benchmark comparison for implementation from PR and dev
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
/** | ||
* Serializes the [value] with [serializer] into a [target] using JSON format and UTF-8 encoding. | ||
* | ||
* If [target] is not a [BufferedSink] then called [Sink.buffer] for it to create buffered wrapper. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I'm late to the party! Why not making the "buffer" requirement in the API itself?
public fun <T> Json.encodeToSink(
serializer: SerializationStrategy<T>,
value: T,
target: BufferedSink
)
The current API fails if someone expects to be able to resume reading the stream after decoding an element.
See #1789 (comment) for a related discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For encoding this isn't a problem. You are always free to call buffer()
and then emit()
as implementation details.
The problem you are referring to, however, is for decoding. Decoding absolutely should take a BufferedSource
and not a Source
. This is what Moshi and Wire do as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right! Sorry for the confusion, I never realised how asymmetric this was 👍 . Maybe it's worth removing the "BufferSink" mention from the kdoc then? Since it's an implementation detail, the caller doesn't really need to know about it?
And in all cases, make the BufferedSource
mandatory for decodeFromSource
:
public fun <T> Json.decodeFromSource(
deserializer: DeserializationStrategy<T>,
source: BufferedSource
): T
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree on both points!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your suggestions! Looks like we probably need to change existing functions working with Java streams applying the same logic.
However, this may lead to some asymmetry in the API. What do you think would be better — change both encodeToSink/decodeFromSource
so they accept buffered versions or leave encodeToSink
intact?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change both encodeToSink/decodeFromSource so they accept buffered versions or leave encodeToSink intact?
No strong opinion from me. Both Moshi and Wire use BufferedSink
so I'd lean towards BufferedSink
here as well for consistency/aesthetics reasons.
Since the sink is ending up being buffered in all cases, it's pretty easy to let the caller call .buffer()
if required. Plus it might even save an emit()
when writing multiple Json to the same BufferedSink
(So tiny performance gain maybe...). But if there's a use case for passing a raw Sink
, that works with me too.
} | ||
|
||
override fun release() { | ||
target.flush() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tempted to say that this should be a call to emit()
which only pushes buffered data into the wrapped Sink
allowing it to choose whether to write further down the chain. flush()
, however, forces all of the bytes through the whole stack.
More here: https://jakewharton.com/forcing-bytes-downward-in-okio/
No description provided.