hanki

stream

stdlib/core/stream.hk: byte-transport capability traits.

ReadStream and WriteStream let one-direction framing accept split socket halves. They retain the concrete sys.NetError and [net] contracts shared by every directional face. Stream is the duplex contract with eager close. Its implementation error is Error, and its effect row travels through a bound variable. TCP and Unix bind NetError; TLS binds TlsFailure; an in-memory implementation may bind its own error and perform no effects.

close! returns () and no Result, that being what the transport does - sys.socket_close! cannot fail. Declaring it fallible here would invent an error TcpStream never produces and make every caller handle it.

No hermetic test block: every implementation bottoms out in a real OS socket, with no pure result to assert. The framing built on this trait is unit-tested over in-memory buffers in extra/http.

ReadStream

trait ReadStream

read!

def read!(self, max: u32) -> Result<bytes, sys.NetError> [net]

Read once, returning up to max bytes. An empty bytes is EOF. @no-doctest: reads a real transport; needs a peer

WriteStream

trait WriteStream

write!

def write!(self, data: bytes) -> Result<i64, sys.NetError> [net]

Write once, returning the count written, which may be less than data.length. @no-doctest: writes a real transport; needs a peer

Stream

trait Stream

Error

type Error

The failure returned by read! and write! for this implementation.

read!

def read!(self, max: u32) -> Result<bytes, Error> [e]

Read once, returning up to max bytes. An empty bytes is EOF (the peer closed). Err on an I/O error or a closed transport. @no-doctest: reads a real transport; needs a peer, cannot assert in a doctest

write!

def write!(self, data: bytes) -> Result<i64, Error> [e]

Write once, returning the count written, which may be less than data.length. Writing the whole buffer is the caller's loop. @no-doctest: writes a real transport; needs a peer, cannot assert in a doctest

close!

def close!(self) -> () [e]

Release the transport. An implementor must make this idempotent, and must also release on drop; reclamation is per-actor reference counting (HANKI.md §4), and a TcpStream therefore closes when its last handle goes and an explicit close! is the eager form. Nothing enforces either for a transport defined outside this module; both are the contract. @no-doctest: side-effecting close; no return value to assert

DeadlineStream

trait DeadlineStream

A connected transport whose whole-operation wall-clock deadline can be reset. Separate from Stream: in-memory streams and custom framing transports remain valid Stream implementations without inventing a clock.

set_deadline!

def set_deadline!(self, timeout_ms: i32) -> () [net]

Replace the absolute deadline, beginning now. Negative values clamp to zero. The deadline covers every later blocking read/write until reset. @no-doctest: mutates a live transport resource