h2ts_client/transport.rs
1//! The byte-duplex a connection runs over — the Rust analogue of the TS
2//! `Transport` (`{ readable, writable }`). Anything expressible as a pair of byte
3//! streams works: a browser `WebSocket` (behind the `web` feature), an in-memory
4//! channel pair for tests, etc.
5//!
6//! It is deliberately I/O-model-agnostic: a [`Stream`] of inbound chunks and a
7//! [`Sink`] of outbound chunks, both boxed so the connection is not generic. This
8//! uses only `futures` — no tokio, no hyper — so it compiles for `wasm32`.
9
10use std::pin::Pin;
11
12use futures::{Sink, Stream};
13
14/// An error from the underlying transport (socket closed, send failed, …).
15#[derive(Debug, Clone)]
16pub struct TransportError(pub String);
17
18impl core::fmt::Display for TransportError {
19 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
20 f.write_str(&self.0)
21 }
22}
23
24impl std::error::Error for TransportError {}
25
26/// Inbound byte chunks from the peer. The stream ending signals EOF.
27pub type ByteStream = Pin<Box<dyn Stream<Item = Vec<u8>>>>;
28
29/// Outbound byte chunks to the peer.
30pub type ByteSink = Pin<Box<dyn Sink<Vec<u8>, Error = TransportError>>>;
31
32/// A bidirectional byte transport: a reader (inbound) and a writer (outbound).
33pub struct Transport {
34 pub reader: ByteStream,
35 pub writer: ByteSink,
36}
37
38impl Transport {
39 pub fn new(reader: ByteStream, writer: ByteSink) -> Self {
40 Self { reader, writer }
41 }
42}