silk.io.byte_duplex.
The ByteDuplex effect: a two-way byte stream, such as a TCP connection, with partial reads and
writes and deadlines.
When to use#
Require &mut ByteDuplex in protocol code that must know exactly how many bytes each read and
write moved, such as HTTP or TLS. Most code uses it through silk.io.buffered_duplex. Use
silk.io.writer.Writer when each write must complete or fail as a whole.
Details#
ByteDuplex.readSome, ByteDuplex.writeSome, and ByteDuplex.writeSomeVectored can move
fewer bytes than the caller offers. A successful read or write of a non-empty slice moves at
least one byte. The bytes after that count stay with the caller. ReadTransfer.End means that
the peer ended the stream. It is not a message of the protocol.
Each operation takes a deadline: an absolute time on the active MonotonicClock, or none.
A provider implements the unsafe ...Raw operations. The safe operations check the counts
that the provider reports, so callers use only the safe operations.
Errors#
ByteIoErrorfor each failure.Timeoutwhen the deadline passes,Closedafter a close,Providerfor a failure of the transport.
Gotchas#
If a provider reports a count that is not possible, the safe operation closes the transport and
fails with InvalidTransferCount. Do not try again with the same buffer. If an operation is
canceled during a transfer, it is not known how many bytes moved. Close the transport.
See also#
silk.io.buffered_duplexfor buffered reads and writes over aByteDuplex.silk.io.memory_byte_duplexfor a scripted transport to use in tests.
Import as ByteDuplex with import silk.io.byte_duplex { ByteDuplex }.
Public declarations: 4.
ByteIoOperation#
pub enum ByteIoOperationThe operation that failed, as recorded in a ByteIoError.
Read#
ReadA read.
Write#
WriteA write.
Flush#
FlushA flush.
ShutdownWrite#
ShutdownWriteA close of the write direction.
Close#
CloseA close of the whole transport.
Implementation Debug for ByteIoOperation#
impl Debug for ByteIoOperationOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as Read.
ByteIoError#
pub union ByteIoErrorThe error from a ByteDuplex operation.
Details#
Timeout means that the deadline passed, Closed that the transport or its write direction is
closed, and Provider that the transport failed for its own reason. InvalidTransferCount
means that the provider reported a count that is not possible. The safe operation then closes
the transport.
Gotchas#
After InvalidTransferCount, do not try again with the same buffer. If an operation is canceled
during a transfer, it is not known how many bytes moved. Close the transport.
Timeout#
TimeoutThe deadline passed before the operation completed.
Field operation#
pub operation: ByteIoOperationThe operation that failed.
InvalidTransferCount#
InvalidTransferCountThe provider reported a count that is not possible: 0, or more than the slice length. The transport is closed.
Field operation#
pub operation: ByteIoOperationThe operation that failed.
Field count#
pub count: usizeThe count that the provider reported.
Field limit#
pub limit: usizeThe length of the slice that the caller offered.
Closed#
ClosedThe transport, or its write direction, is closed.
Field operation#
pub operation: ByteIoOperationThe operation that failed.
Provider#
ProviderThe transport failed for its own reason, such as a connection reset.
Field operation#
pub operation: ByteIoOperationThe operation that failed.
Field code#
pub code: i32A code that the provider defines, such as an errno value.
Implementation Debug for ByteIoError#
impl Debug for ByteIoErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant and its fields, such as Timeout { ... }.
ReadTransfer#
pub union ReadTransferThe result of a read.
Data#
DataThe read put bytes at the start of the output slice.
Field count#
pub count: usizeThe number of bytes that the read put in the output slice. It is at least 1 for a non-empty slice.
End#
EndThe peer ended the stream. Later reads also return End.
ByteDuplex#
pub service ByteDuplexThe effect for one two-way byte stream that the code uses alone, such as a TCP connection, with partial reads and writes and deadlines.
When to use#
Require &mut ByteDuplex in protocol code that must know exactly how many bytes each read and
write moved, such as HTTP or TLS. Most code uses it through silk.io.buffered_duplex. Use
silk.io.writer.Writer when each write must complete or fail as a whole.
Details#
A read or write can move fewer bytes than the caller offers. A successful read or write of a
non-empty slice moves at least one byte. ReadTransfer.End means that the peer ended the
stream. Each operation takes a deadline: an absolute time on the active MonotonicClock, or
none.
A provider implements the ...Raw operations. Callers use the safe operations with the same
names without Raw: ByteDuplex.readSome, ByteDuplex.writeSome,
ByteDuplex.writeSomeVectored, ByteDuplex.flush, ByteDuplex.shutdownWrite, and
ByteDuplex.close. A direct call to a ...Raw operation is unsafe, because its count is
not checked.
Gotchas#
If a provider reports a count that is not possible, the safe operation closes the transport and
fails with InvalidTransferCount. If an operation is canceled during a transfer, it is not
known how many bytes moved. Close the transport.
Operation readSomeRaw#
unsafe effect fn readSomeRaw(
output: &mut [u8],
deadline: Option<Instant>
) -> ReadTransfer ! ByteIoError ? &mut ByteDuplex | &mut MonotonicClockThe provider read. It puts bytes at the start of output and returns their count, or End.
Operation writeSomeRaw#
unsafe effect fn writeSomeRaw(
input: &[u8],
deadline: Option<Instant>
) -> usize ! ByteIoError ? &mut ByteDuplex | &mut MonotonicClockThe provider write. It sends bytes from the start of input and returns their count.
Operation writeSomeVectoredRaw#
unsafe effect fn writeSomeVectoredRaw(
inputs: &[&[u8]],
deadline: Option<Instant>
) -> usize ! ByteIoError ? &mut ByteDuplex | &mut MonotonicClockThe provider vectored write. It sends bytes from the slices of inputs, in order, as if they
were one slice, and returns their count. The safe wrapper calls it only when the slices hold
at least one byte.
Details#
A provider can send several slices in one operation, such as one writev system call. A
provider with no such operation writes ByteDuplex.firstNonEmpty with its own write.
Operation flushRaw#
unsafe effect fn flushRaw(
deadline: Option<Instant>
) -> () ! ByteIoError ? &mut ByteDuplex | &mut MonotonicClockThe provider flush. It sends any bytes that the provider holds in a buffer.
Operation shutdownWriteRaw#
unsafe effect fn shutdownWriteRaw(
deadline: Option<Instant>
) -> () ! ByteIoError ? &mut ByteDuplex | &mut MonotonicClockThe provider close of the write direction. The safe wrapper flushes before it calls this.
Operation closeRaw#
unsafe effect fn closeRaw() -> () ! ByteIoError ? &mut ByteDuplexThe provider close of the whole transport. After the first call, the provider stays closed, and a later call must succeed and do nothing.
Implementation ByteDuplex#
impl ByteDuplexAssociated function readSome#
pub effect fn readSome(
output: &mut [u8],
deadline: Option<Instant>
) -> ReadTransfer ! ByteIoError ? &mut ByteDuplex | &mut MonotonicClockReads at least one byte into the start of output, or returns ReadTransfer.End if the peer
ended the stream.
Details#
An empty output returns a count of 0 and does not use the provider. deadline is an
absolute time on the active MonotonicClock. Option.none() means no time limit.
Errors#
ByteIoError.Timeoutif the deadline passes.ByteIoError.InvalidTransferCountif the provider reports 0 or more thanoutput.length. The transport is closed, also if the close fails.ByteIoError.ClosedorByteIoError.Providerfrom the provider.
Associated function writeSome#
pub effect fn writeSome(
input: &[u8],
deadline: Option<Instant>
) -> usize ! ByteIoError ? &mut ByteDuplex | &mut MonotonicClockWrites at least one byte from the start of input and returns how many bytes it wrote.
Details#
An empty input returns 0 and does not use the provider. The bytes after the returned count
are not written. Call writeSome again with the rest. deadline is an absolute time on the
active MonotonicClock. Option.none() means no time limit.
Errors#
ByteIoError.Timeoutif the deadline passes.ByteIoError.InvalidTransferCountif the provider reports 0 or more thaninput.length. The transport is closed, also if the close fails.ByteIoError.ClosedorByteIoError.Providerfrom the provider.
Associated function writeSomeVectored#
pub effect fn writeSomeVectored(
inputs: &[&[u8]],
deadline: Option<Instant>
) -> usize ! ByteIoError ? &mut ByteDuplex | &mut MonotonicClockWrites at least one byte from the slices of inputs, in order, as if they were one slice, and
returns how many bytes it wrote.
When to use#
Use it for a message that is in several parts, such as buffered bytes and a large body, so that a provider such as a socket can send the parts in one operation without a copy.
Details#
The count can end inside any slice. The bytes after it are not written. When the slices hold
no bytes, it returns 0 and does not use the provider. deadline is an absolute time on the
active MonotonicClock. Option.none() means no time limit.
Errors#
ByteIoError.Timeoutif the deadline passes.ByteIoError.InvalidTransferCountif the provider reports 0 or more than the sum of the slice lengths. The transport is closed, also if the close fails.ByteIoError.ClosedorByteIoError.Providerfrom the provider.
Associated function firstNonEmpty#
pub fn firstNonEmpty<'a>(inputs: &[&'a [u8]]) -> &'a [u8]Returns the first slice of inputs that is not empty, or an empty slice.
When to use#
Use it to implement writeSomeVectoredRaw in a provider that has no faster way to write
several slices: write the returned slice with the provider's own write. A partial write of
the first part is a valid vectored write.
Associated function flush#
pub effect fn flush(
deadline: Option<Instant>
) -> () ! ByteIoError ? &mut ByteDuplex | &mut MonotonicClockSends any bytes that the provider holds in a buffer.
Errors#
ByteIoErrorfrom the provider, orTimeoutif the deadline passes.
Associated function shutdownWrite#
pub effect fn shutdownWrite(
deadline: Option<Instant>
) -> () ! ByteIoError ? &mut ByteDuplex | &mut MonotonicClockFlushes and then closes the write direction. Reads still work.
When to use#
Use it to tell the peer that no more data comes, while you still read its answer.
Errors#
ByteIoErrorfrom the flush or the shutdown, orTimeoutif the deadline passes.
Associated function close#
pub effect fn close() -> () ! ByteIoError ? &mut ByteDuplexCloses the whole transport. A later call does nothing.
Errors#
ByteIoErrorfrom the provider. The transport is closed also when the close reports an error.
Associated function timeout#
pub fn timeout(operation: ByteIoOperation) -> ByteIoErrorReturns ByteIoError.Timeout for operation. Providers use it.
Associated function invalidTransferCount#
pub fn invalidTransferCount(
operation: ByteIoOperation,
count: usize,
limit: usize,
) -> ByteIoErrorReturns ByteIoError.InvalidTransferCount with the reported count and the slice length
limit.
Associated function closed#
pub fn closed(operation: ByteIoOperation) -> ByteIoErrorReturns ByteIoError.Closed for operation. Providers use it.
Associated function provider#
pub fn provider(operation: ByteIoOperation, code: i32) -> ByteIoErrorReturns ByteIoError.Provider for operation with a provider-defined code.
Category: Input and output.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.