Skip to content

Question and API proposal regarding DotNext.IO #181

Description

@thenameless314159

Hello, first of all I would first like to express my sincere appreciation for this amazing library !

Question

For the sake of my personal understanding, I am curious about the motivations behind your choice to design a non-generic SequenceReader, rather than enhancing the existing System.Buffers.SequenceReader (aside from the async method overloads).

API proposal

Furthermore, I would like to make a proposal for new APIs and changes to existing ones for pipe-related scenarios which could be beneficial for users willing to directly read from a sequence that was obtained from a PipeReader via a SequenceReader<byte>.

I have largely completed the necessary work and testing within a private repository of my own, achieving close to 90% coverage. If required, I can ensure this coverage reaches 100%. It would be my pleasure to introduce these modifications to DotNext via a pull request.

Background and motivation

The IBinaryFormattable<TSelf>, from my perspective, is somewhat lacking in terms of extensibility. It could be beneficial to divide it into separate read-only and write-only interfaces. Additionally, new interfaces could be introduced for binary readable types that expose settable members, which would not necessarily require the implementation of a static abstract interface method.

In relation to pipe-related scenarios, users might desire to implement an IBinaryFormattable<TSelf>, and as such, may not be inclined to implement parsing logic based on a SpanReader<byte> to process input data from a ReadOnlySequence<byte>. Instead, they could directly depend on a SequenceReader<byte>, which would eliminate the need to copy the input data into a single stack-allocated or rented span.

I believe that implementing these modifications would pave the way for APIs that are prepared for source-generator integration which is a feature I intend to develop in the future.

Proposal

Consequently, my proposal could take several directions depending on the scenarios we aim to address:

If we primarily want to address pipe-related scenarios:

  • Divide IBinaryFormattable<TSelf> into three interfaces:
    • IBinaryWritable with a public void Serialize(ref SpanWriter<T> output) and potentially an instance int GetSizeOf() method, or another interface enabling the addition of extension methods to write into an IBufferWriter<byte> or various memory owners.
    • IBinaryReadable with a public void Deserialize(ref SpanReader<T> input) for objects with settable members.
    • IBinaryReadable<TSelf> with a static abstract Read method for objects with init-only members.
  • Introduce IBinaryFormattable : IBinaryWritable, IBinaryReadable for objects exposing setting members.
  • Refactor IBinaryFormattable<TSelf> to IBinaryFormattable<TSelf> : IBinaryReadable<TSelf>, IBinaryWritable.
  • Introduce IBufferReadable and IBufferReadable<TSelf> that mirror the IBinaryReadable interfaces but use a SequenceReader<byte> instead.
  • Provide IBinaryFormattable-like interfaces for the sequence-based IBufferReadable interfaces.

If we aim to cover a broader range of scenarios (e.g., spans of chars):

  • We would include all of the above, except the new interfaces would then inherit from additional ISpanReadable<T>, ISpanReadable<TSelf, T> and ISpanWritable<T> interfaces, where T represents the span element type.

Source code

I have made some of the suggested APIs available in a gist, which can be found here: https://gist.github.com/thenameless314159/a2a6487ce19c0da24d08a1cf328ddc8e

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions