Skip to content

feat!: switch RPIT to more TAIT-like interface#138

Merged
nyonson merged 1 commit intorust-bitcoin:mainfrom
nyonson:try-tait
Jul 16, 2025
Merged

feat!: switch RPIT to more TAIT-like interface#138
nyonson merged 1 commit intorust-bitcoin:mainfrom
nyonson:try-tait

Conversation

@nyonson
Copy link
Collaborator

@nyonson nyonson commented Jul 16, 2025

Got a little too excited with that RPIT stuff, rolling back to the newtype pattern.

The Protocol type is generic over Read/AsyncRead, but after the handshake completes, we need to store a different reader type that accounts for any leftover bytes read during handshake processing when searching for the garbage terminator.

This creates a type mismatch: Protocol performs a handshake with reader type R, but afterwards needs to store a chained reader that first drains leftover bytes. The actual reader type becomes Chain<Cursor<Vec>, R>, (for the blocking implementation) not the original R.

This implemenation detail was initially hidden from the caller using a RPIT (impl Read/AsyncRead) for the Protocol. However, this isn't a great use case for RPIT because the Protocol is generally long-lived and callers want to store it in structs/enums. But RPITs currently can't be named, so callers can't store and reference them.

The ideal language feature for this woult be a TAIT. It keeps the implementation details hidden, but allows for the callers to store and reference the returned Protocol. But TAITs are still only supported on the nightly toolchain. So in the mean time, a ProtocolSessionReader type is used to give the caller a concrete type to name. It matches the interface of a TAIT, so hopefully can be easily swapped out when that feature is stablized.

The Protocol type is generic over Read/AsyncRead, but after the handshake
completes, we need to store a different reader type that accounts for any
leftover bytes read during handshake processing when searching for the
garbage terminator.

This creates a type mismatch: Protocol<R> performs a handshake with reader
type R, but afterwards needs to store a chained reader that first drains
leftover bytes. The actual reader type becomes Chain<Cursor<Vec<u8>>, R>,
(for the blocking implementation) not the original R.

This implemenation detail was initially hidden from the caller using a
RPIT (impl Read/AsyncRead) for the Protocol. However, this isn't a great
use case for RPIT because the Protocol is generally long-lived and
callers want to store it in structs/enums. But RPITs currently can't be
named, so callers can't store and reference them.

The ideal language feature for this woult be a TAIT. It keeps the
implementation details hidden, but allows for the callers to store and
reference the returned Protocol. But TAITs are still only supported on
the nightly toolchain. So in the mean time, a ProtocolSessionReader
type is used to give the caller a concrete type to name. It matches the
interface of a TAIT, so hopefully can be easily swapped out when that
feature is stablized.
@nyonson nyonson merged commit 19dce40 into rust-bitcoin:main Jul 16, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant