Skip to content

Question and API proposal regarding DotNext.IO #181

@thenameless314159

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions