Skip to content

Improve RequestStreams ergonomics #57

@stammw

Description

@stammw

As discussed in #56, it is not possible to name the full RequestStream type without frame::FrameStream being externally accessible. Namely, the return value of:

   // h3/src/client.rs
    pub async fn send_request(
        &mut self,
        req: http::Request<()>,
    ) -> Result<RequestStream<FrameStream<C::BidiStream>>, Error> {

Cannot be stored in a struct or passed around in functions params without FrameStream being public.

I see multiple solutions to this:

  • The best one in my opinion: extract a trait and return an impl RequestStream.
    • Pros:
      • Makes the type opaque, so future proof in case of API changes.
    • Cons:
      • That's not possible until async traits are a thing.
      • Users will have to Box it if they need to store this in a struct.
  • Make frame public or reexport FrameStream in the crate's scope.
    • Pros:
      • It's easy to implement
    • Cons:
      • The type is still quite long to write in downstream code
      • FrameStream is externally available but will never be used directly
  • Create type aliases like type RequestStream = RequestStreamImpl<FrameStream<C::BidiStream>>
    • Pros:
      • It's easy to implement
    • Cons:
      • It would introduce another type if we want to split the streams into a reader and a writer: type SendStream = RequestStreamImpl<C::SendStream<B>>

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-refactorCategory: refactor. This would improve the clarity of internal code.E-mediumEffort: medium. Some knowledge of how the internals work would be useful.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions