traits
import std::io::traits; · source
Types
Read
type trait Read {
read(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>;
read_all(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>;
read_byte(mut &this) -> Result<Option<u8>, IoError>;
read_char(mut &this) -> Result<Option<u32>, IoError>;
read_until(mut &this, delimiter: u8, out: mut &Array<u8>) -> Result<u64, IoError>;
read_exact(mut &this, buffer: u8*, length: u64) -> Result<(), IoError>;
read_to_end(mut &this, out: mut &Array<u8>) -> Result<u64, IoError>;
read_to_string(mut &this, out: mut &String) -> Result<u64, IoError>;
read_line(mut &this, out: mut &String) -> Result<u64, IoError>;
}
read is the only required method. It fills up to length bytes and returns how many it actually got. Zero means EOF. A value less than length means the source had nothing more available at this moment — not necessarily EOF, and it is the caller's decision whether to retry.
Everything else is a default built on that one method.
read_all fills the buffer or hits EOF, retrying on Interrupted; read_exact treats a short read at EOF as UnexpectedEof. read_byte returns None at EOF. read_until and read_line include the delimiter in out; read_to_end and read_to_string take every remaining byte.
read_char fails with UnexpectedEof on a partial scalar and InvalidData on a malformed leading byte, a malformed continuation, or a surrogate — surrogates are not valid Unicode scalars.
Two things worth knowing. read_to_end is unbounded: a pathological source like /dev/zero will exhaust memory, so cap it yourself if the input is untrusted. And read_to_string does not validate UTF-8 — you are certifying that the source is well-formed, or accepting invalid continuation bytes inside a String.
read_until and read_line are byte-level, running read(..., 1) so the stop point is exact. On a source where a one-byte read is expensive — a socket, a file — wrap it in a BufReader, whose read_line override is the fast path.
Methods
read(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>;
read(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>;Fill up to length bytes starting at buffer. Returns the number of bytes actually read. Zero means EOF; a value less than length means the underlying source had no more bytes available at this moment (not necessarily EOF; callers decide whether to retry).
read_all(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>;
read_all(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>;Read until the buffer is full or the source returns 0 (EOF). Returns the total bytes read; short returns mean EOF reached. Retries on Interrupted.
read_byte(mut &this) -> Result<Option<u8>, IoError>;
read_byte(mut &this) -> Result<Option<u8>, IoError>;Read a single byte. None means EOF: the source is empty and no more reads will yield data. Retries on Interrupted.
read_char(mut &this) -> Result<Option<u32>, IoError>;
read_char(mut &this) -> Result<Option<u32>, IoError>;Read a single UTF-8 Unicode scalar and return its codepoint. None is EOF before the first byte of the scalar. A partial scalar (first byte read, continuation missing) fails with UnexpectedEof; a malformed leading byte or continuation fails with InvalidData. Surrogates (0xD800..=0xDFFF) likewise fail with InvalidData; they are not valid Unicode scalars.
read_until(mut &this, delimiter: u8, out: mut &Array<u8>) -> Result<u64, IoError>;
read_until(mut &this, delimiter: u8, out: mut &Array<u8>) -> Result<u64, IoError>;Read bytes into out until delimiter is seen or EOF. The delimiter byte is included in out. Returns the number of bytes appended.
read_exact(mut &this, buffer: u8*, length: u64) -> Result<(), IoError>;
read_exact(mut &this, buffer: u8*, length: u64) -> Result<(), IoError>;Read exactly length bytes. A short read at EOF is a failure, reported as UnexpectedEof. Use this when the caller knows the precise number of bytes that must be present.
read_to_end(mut &this, out: mut &Array<u8>) -> Result<u64, IoError>;
read_to_end(mut &this, out: mut &Array<u8>) -> Result<u64, IoError>;Read every remaining byte into out, growing the array as needed. Returns the number of bytes appended. EOF terminates the loop; other errors abort and surface.
read_to_string(mut &this, out: mut &String) -> Result<u64, IoError>;
read_to_string(mut &this, out: mut &String) -> Result<u64, IoError>;Read every remaining byte into out as UTF-8. Convenience wrapper around read_to_end for the common "slurp text from this source" case. The bytes are not validated; the caller certifies the source is UTF-8 (or accepts the consequences of invalid continuation bytes in a String).
read_line(mut &this, out: mut &String) -> Result<u64, IoError>;
read_line(mut &this, out: mut &String) -> Result<u64, IoError>;Read bytes into out until a \n or EOF. The newline byte is included in out. Returns the number of bytes appended (0 only if the very first read hit EOF).
Implementors
implement trait Read for struct File
std::fs::file
implement<R> trait Read for struct BufReader<R> where R: Read
std::io::buf
implement trait Read for struct Cursor
std::io::cursor
implement trait Read for struct Stdin
std::io::stdio
implement trait Read for struct StdinLock
std::io::stdio
implement trait Read for struct ChildStdout
std::process::child
implement trait Read for struct ChildStderr
std::process::child
Write
type trait Write {
write_some(mut &this, bytes: Slice<u8>) -> Result<u64, IoError>;
flush(mut &this) -> Result<(), IoError>;
write<T>(mut &this, data: T) -> Result<(), IoError>;
}
write_some is the low-level primitive: write up to bytes.length() bytes and report how many actually landed, which may be fewer on a slow sink. Unbuffered writers override flush with a no-op.
write<T>(data) is the one you normally call. It delivers every byte, retrying short writes and Interrupted, and dispatches on the payload at compile time: a raw Slice<u8>, a Str, a NUL-terminated string, or a single u8. If the sink repeatedly refuses to make progress it fails with WriteZero rather than spinning.
Methods
write_some(mut &this, bytes: Slice<u8>) -> Result<u64, IoError>;
write_some(mut &this, bytes: Slice<u8>) -> Result<u64, IoError>;Low-level primitive: write up to bytes.length() bytes, returning the number actually written (may be less than requested on a slow sink). Every implementor provides this; the generic write loops over it to deliver every byte.
flush(mut &this) -> Result<(), IoError>;
flush(mut &this) -> Result<(), IoError>;Push any buffered bytes to the underlying sink. Unbuffered writers override with a no-op.
write<T>(mut &this, data: T) -> Result<(), IoError>;
write<T>(mut &this, data: T) -> Result<(), IoError>;Write data in full, retrying short writes and Interrupted errors. Generic over the payload, dispatched at compile time via static match: a raw byte Slice<u8>, a Str view, a NUL-terminated C string, or a single u8. Fails with WriteZero if the sink repeatedly refuses progress; better to surface that than spin.
Implementors
implement trait Write for struct File
std::fs::file
implement<W> trait Write for struct BufWriter<W> where W: Write
std::io::buf
implement<W> trait Write for struct LineWriter<W> where W: Write
std::io::buf
implement trait Write for struct Cursor
std::io::cursor
implement trait Write for struct Stdout
std::io::stdio
implement trait Write for struct Stderr
std::io::stdio
implement trait Write for struct StdoutLock
std::io::stdio
implement trait Write for struct StderrLock
std::io::stdio
implement trait Write for struct ChildStdin
std::process::child
Seek
type trait Seek {
seek(mut &this, from: SeekFrom) -> Result<u64, IoError>;
stream_position(mut &this) -> Result<u64, IoError>;
rewind(mut &this) -> Result<(), IoError>;
}
seek repositions the cursor and returns the resulting absolute offset. stream_position() reports the current offset without moving, defaulting to seek(Current(0)); rewind() is seek(Start(0)).
Seeking past the end is permitted, and what happens next is sink-specific: a File leaves a sparse gap the OS zero-fills, while a Cursor zero-fills on the next write. Seeking to a negative absolute offset fails with InvalidInput.
Methods
seek(mut &this, from: SeekFrom) -> Result<u64, IoError>;
seek(mut &this, from: SeekFrom) -> Result<u64, IoError>;Reposition the cursor and return the new absolute offset from the start of the stream. Seeking past the end is permitted; the effect of a later read/write there is sink-specific (a File leaves a sparse gap the OS zero-fills; an in-memory Cursor zero-fills on the next write). Seeking to a negative absolute offset fails with InvalidInput.
stream_position(mut &this) -> Result<u64, IoError>;
stream_position(mut &this) -> Result<u64, IoError>;Current absolute offset, without moving. Default: seek(Current(0)).
rewind(mut &this) -> Result<(), IoError>;
rewind(mut &this) -> Result<(), IoError>;Reposition to the start of the stream. Default: seek(Start(0)).
SeekFrom
type enum SeekFrom {
Start(u64);
Current(i64);
End(i64);
}
Variants
| Variant |
|---|
Start(u64) |
Current(i64) |
End(i64) |
Implementors
implement trait Seek for struct File
std::fs::file
implement trait Seek for struct Cursor
std::io::cursor
The async traits
The non-blocking counterparts of Read and Write, shaped for a buffered connection rather than a bare byte stream.
AsyncRead
type trait AsyncRead {
async fill(mut &this) -> Result<u64, IoError>;
buffered(&this) -> Slice<u8>;
consume(mut &this, count: u64) -> void;
scan_for(&this, delimiter: u8, from: u64) -> u64;
take_front(mut &this, count: u64) -> Result<Array<u8>, IoError>;
async ensure(mut &this, count: u64) -> Result<(), IoError>;
async read_exact(mut &this, count: u64) -> Result<Array<u8>, IoError>;
async read_some(mut &this, limit: u64) -> Result<Array<u8>, IoError>;
async read_until(mut &this, delimiter: u8, limit: u64) -> Result<Array<u8>, IoError>;
async read_line(mut &this, limit: u64) -> Result<String, IoError>;
async skip(mut &this, count: u64) -> Result<(), IoError>;
}
Where Read hands you bytes, AsyncRead hands you a view into its own buffer: fill pulls more from the transport (suspending rather than blocking; zero means the peer closed), buffered() is what has arrived and not yet been consumed, and consume(n) releases the front of it. Every default — read_until, read_line, ensure, read_exact — is a scan over that buffer. The slice from buffered() is valid only until the next fill or consume; do not hold it across an await.
read_until and read_line take a limit so a peer that never sends the delimiter cannot drive the buffer to exhaust memory — exceeding it is InvalidData. read_line strips the terminator, and a \r before it, so CRLF and LF framing read alike.
Methods
async fill(mut &this) -> Result<u64, IoError>;
async fill(mut &this) -> Result<u64, IoError>;Pull more bytes from the transport into the connection's buffer and return how many arrived. Zero means the peer closed its end: no later fill will produce anything either.
buffered(&this) -> Slice<u8>;
buffered(&this) -> Slice<u8>;The bytes that have been read but not yet consumed.
consume(mut &this, count: u64) -> void;
consume(mut &this, count: u64) -> void;Discard the first count buffered bytes, which the caller has finished with. count must not exceed buffered().length().
scan_for(&this, delimiter: u8, from: u64) -> u64;
scan_for(&this, delimiter: u8, from: u64) -> u64;Index just past the first delimiter at or after from, or 0 when it is not in the buffer yet.
take_front(mut &this, count: u64) -> Result<Array<u8>, IoError>;
take_front(mut &this, count: u64) -> Result<Array<u8>, IoError>;Copy the first count buffered bytes out and consume them. Callers that can parse in place should read buffered() directly and call consume themselves; this is for the cases that need to keep the bytes past the next fill.
async ensure(mut &this, count: u64) -> Result<(), IoError>;
async ensure(mut &this, count: u64) -> Result<(), IoError>;Fill until at least count bytes are buffered. EOF before that is UnexpectedEof: the caller asked for bytes the peer will never send.
async read_exact(mut &this, count: u64) -> Result<Array<u8>, IoError>;
async read_exact(mut &this, count: u64) -> Result<Array<u8>, IoError>;Read exactly count bytes and hand them back. A short stream is UnexpectedEof.
async read_some(mut &this, limit: u64) -> Result<Array<u8>, IoError>;
async read_some(mut &this, limit: u64) -> Result<Array<u8>, IoError>;Read whatever is available, up to limit bytes, suspending only if nothing is buffered yet. An empty result means EOF — it is the terminating condition for a streaming copy, not an error.
async read_until(mut &this, delimiter: u8, limit: u64) -> Result<Array<u8>, IoError>;
async read_until(mut &this, delimiter: u8, limit: u64) -> Result<Array<u8>, IoError>;Read up to and including the first delimiter. The delimiter is part of the returned bytes.
async read_line(mut &this, limit: u64) -> Result<String, IoError>;
async read_line(mut &this, limit: u64) -> Result<String, IoError>;Read one \n-terminated line, without the terminator. A \r immediately before it is stripped too, so this reads CRLF and LF framing alike. limit caps the line length as in read_until.
async skip(mut &this, count: u64) -> Result<(), IoError>;
async skip(mut &this, count: u64) -> Result<(), IoError>;Discard exactly count bytes. Cheaper than read_exact for payload a caller is required to consume but does not want, such as frame padding.
AsyncWrite
type trait AsyncWrite {
pending(mut &this) -> Array<u8>*;
async flush(mut &this) -> Result<(), IoError>;
queue<T>(mut &this, data: T) -> Result<(), IoError>;
async send<T>(mut &this, data: T) -> Result<(), IoError>;
}
AsyncWrite exposes its outgoing buffer through pending() so an encoder can build a frame in place. queue appends without sending; flush puts everything on the wire, leaving the unsent bytes queued on failure so a retry still has them; send is queue then flush.
Methods
pending(mut &this) -> Array<u8>*;
pending(mut &this) -> Array<u8>*;The connection's outgoing buffer, for queue to append to and flush to drain. Exposed rather than wrapped so an encoder can build a frame directly in place instead of into a scratch array that is then copied.
async flush(mut &this) -> Result<(), IoError>;
async flush(mut &this) -> Result<(), IoError>;Put every queued byte on the wire, suspending as often as the transport needs, and clear the buffer. A failure leaves the unsent bytes queued, so a caller that can retry still has them.
queue<T>(mut &this, data: T) -> Result<(), IoError>;
queue<T>(mut &this, data: T) -> Result<(), IoError>;Append data to the outgoing buffer without sending anything. Generic over the payload and dispatched at compile time: a raw Slice<u8>, a Str view, a NUL-terminated C string, or a single u8.
async send<T>(mut &this, data: T) -> Result<(), IoError>;
async send<T>(mut &this, data: T) -> Result<(), IoError>;Queue data and send it immediately. The one-shot convenience for a caller with nothing else to add; a caller with several pieces should queue each and flush once.
AsyncTransport
type trait AsyncTransport {
async read_into(mut &this, buf: Array<u8>) -> Transfer;
async write_from(mut &this, buf: Array<u8>) -> Transfer;
}
type struct Transfer {
buf: Array<u8>;
result: Result<u64, IoError>;
take_buf(mut &this) -> Array<u8>;
outcome(&this) -> Result<u64, IoError>;
}
AsyncTransport is the seam underneath both: two operations that move an owned buffer to the transport and back through a Transfer. This is what lets a plaintext TcpStream and a TlsStream share one BufStream implementation — everything above the seam is written once.
AsyncTransport
Methods
####### async read_into(mut &this, buf: Array<u8>) -> Transfer;
async read_into(mut &this, buf: Array<u8>) -> Transfer;Read into buf, completing with the bytes that arrived. Zero means the peer closed its end.
####### async write_from(mut &this, buf: Array<u8>) -> Transfer;
async write_from(mut &this, buf: Array<u8>) -> Transfer;Write from buf, completing with the bytes accepted, which may be fewer than offered — the caller sends the remainder in another operation.
Transfer
Properties
| Property | Type |
|---|---|
buf | Array<u8> |
result | Result<u64, IoError> |
Methods
####### take_buf(mut &this) -> Array<u8>;
take_buf(mut &this) -> Array<u8>;Take the buffer back. Calling it twice yields an empty array the second time — the transfer holds the buffer exactly once.
####### outcome(&this) -> Result<u64, IoError>;
outcome(&this) -> Result<u64, IoError>;How many bytes moved, or why none did.
Implementors
implement<S> trait AsyncRead for struct BufStream<S>
std::io::buf
implement<S> trait AsyncWrite for struct BufStream<S>
std::io::buf
implement trait AsyncTransport for struct TcpStream
std::net::socket::tcp
implement trait AsyncTransport for struct TlsStream
std::net::tls::future
Constants
const READ_TO_END_CHUNK: u64 = 4096;
const BYTE_LF: u8 = 0x0A;
const BYTE_CR: u8 = 0x0D;type struct Name { ... }
type enum Name { ... }
type trait Name { ... }
type union Name { ... }Begins a type declaration; the keyword that follows says which kind. On its own, type Name = Existing; declares an alias.
type trait Name : Base {
method(&this, other: &This) -> Ret;
}Names a set of methods a type may implement. Inside the body This is the implementing type; methods may carry default bodies, and a trait may require a base trait (type trait Ord : Eq). Generic code asks for a trait with where T: Name.
type trait Read {
read(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>;
read_all(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>;
read_byte(mut &this) -> Result<Option<u8>, IoError>;
read_char(mut &this) -> Result<Option<u32>, IoError>;
read_until(mut &this, delimiter: u8, out: mut &Array<u8>) -> Result<u64, IoError>;
read_exact(mut &this, buffer: u8*, length: u64) -> Result<(), IoError>;
read_to_end(mut &this, out: mut &Array<u8>) -> Result<u64, IoError>;
read_to_string(mut &this, out: mut &String) -> Result<u64, IoError>;
read_line(mut &this, out: mut &String) -> Result<u64, IoError>;
}Read::read(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>Fill up to length bytes starting at buffer. Returns the number of bytes actually read. Zero means EOF; a value less than length means the underlying source had no more bytes available at this moment (not necessarily EOF; callers decide whether to retry).
mut &this
mut &TypeAn exclusive, mutating borrow. As a receiver, mut &this lets the method modify the fields - and callers can see that from the signature alone. As a parameter type, mut &T lets the callee mutate through the reference while the caller keeps ownership.
&this
mut &this
thisThe receiver of a method. Its first parameter declares how the method takes it: &this borrows read-only, mut &this borrows exclusively, and this / mut this move the value in and consume it. In the body, this.field reaches the members.
(parameter) buffer: u8*(parameter) length: u64type struct IoError {
kind: IoErrorKind;
os_code: i32;
}Read::read_all(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>Read until the buffer is full or the source returns 0 (EOF). Returns the total bytes read; short returns mean EOF reached. Retries on Interrupted.
Read::read_byte(mut &this) -> Result<Option<u8>, IoError>Read a single byte. None means EOF: the source is empty and no more reads will yield data. Retries on Interrupted.
Read::read_char(mut &this) -> Result<Option<u32>, IoError>Read a single UTF-8 Unicode scalar and return its codepoint. None is EOF before the first byte of the scalar. A partial scalar (first byte read, continuation missing) fails with UnexpectedEof; a malformed leading byte or continuation fails with InvalidData.
Read::read_until(mut &this, delimiter: u8, out: mut &Array<u8>) -> Result<u64, IoError>Read bytes into out until delimiter is seen or EOF. The delimiter byte is included in out. Returns the number of bytes appended.
(parameter) delimiter: u8(parameter) out: mut &Array<u8>type struct Array<T, A = GlobalAlloc> where A: Allocator {
ptr: T*;
length: i64;
capacity: i64;
alloc: A;
}Array<T, A>: growable, heap-backed, contiguous sequence.
std::collections::arrayRead::read_exact(mut &this, buffer: u8*, length: u64) -> Result<(), IoError>Read exactly length bytes. A short read at EOF is a failure, reported as UnexpectedEof. Use this when the caller knows the precise number of bytes that must be present.
primitive ()The unit type: a value that carries no information, and the empty tuple. Distinct from void, which is the absence of a value - Result<(), E> succeeds with nothing to return. 0 bytes.
Read::read_to_end(mut &this, out: mut &Array<u8>) -> Result<u64, IoError>Read every remaining byte into out, growing the array as needed. Returns the number of bytes appended. EOF terminates the loop; other errors abort and surface.
Read::read_to_string(mut &this, out: mut &String) -> Result<u64, IoError>Read every remaining byte into out as UTF-8. Convenience wrapper around read_to_end for the common "slurp text from this source" case. The bytes are **not** validated; the caller certifies the source is UTF-8 (or accepts the consequences of invalid continuation bytes in a String).
(parameter) out: mut &Stringtype struct String<A = GlobalAlloc> {
buffer: RawBuffer<u8, A>;
length: u64;
}String: owned, heap-allocated, length-typed UTF-8.
std::collections::stringRead::read_line(mut &this, out: mut &String) -> Result<u64, IoError>Read bytes into out until a \n or EOF. The newline byte is included in out. Returns the number of bytes appended (0 only if the very first read hit EOF).
type trait Write {
write_some(mut &this, bytes: Slice<u8>) -> Result<u64, IoError>;
flush(mut &this) -> Result<(), IoError>;
write<T>(mut &this, data: T) -> Result<(), IoError>;
}Write::write_some(mut &this, bytes: Slice<u8>) -> Result<u64, IoError>Low-level primitive: write up to bytes.length() bytes, returning the number actually written (may be less than requested on a slow sink). Every implementor provides this; the generic write loops over it to deliver every byte.
(parameter) bytes: Slice<u8>type struct Slice<T> {
ptr: T*;
length: u64;
}Slice<T>: a borrowed view into a contiguous sequence.
std::core::sliceWrite::flush(mut &this) -> Result<(), IoError>Push any buffered bytes to the underlying sink. Unbuffered writers override with a no-op.
Write::write<T>(mut &this, data: T) -> Result<(), IoError>Write data in full, retrying short writes and Interrupted errors. Generic over the payload, dispatched at compile time via static match: a raw byte Slice<u8>, a Str view, a NUL-terminated C string, or a single u8.
type parameter T(parameter) data: Ttype parameter Ttype trait Seek {
seek(mut &this, from: SeekFrom) -> Result<u64, IoError>;
stream_position(mut &this) -> Result<u64, IoError>;
rewind(mut &this) -> Result<(), IoError>;
}A byte stream whose read/write cursor can be repositioned. Absolute positions are u64 offsets from the start; every seek returns the resulting absolute position.
Seek::seek(mut &this, from: SeekFrom) -> Result<u64, IoError>Reposition the cursor and return the new absolute offset from the start of the stream. Seeking past the end is permitted; the effect of a later read/write there is sink-specific (a File leaves a sparse gap the OS zero-fills; an in-memory Cursor zero-fills on the next write).
(parameter) from: SeekFromtype enum SeekFrom {
Start(u64);
Current(i64);
End(i64);
}Anchor for a Seek::seek. The seek target is one of: an absolute byte offset from the start (Start, always non-negative), a signed delta from the current position (Current), or a signed delta from the end (End). Current/End deltas may be negative; seeking to a negative absolute offset is an error.
Seek::stream_position(mut &this) -> Result<u64, IoError>Current absolute offset, without moving. Default: seek(Current(0)).
Seek::rewind(mut &this) -> Result<(), IoError>Reposition to the start of the stream. Default: seek(Start(0)).
type enum Name {
Unit,
Payload(T),
Named { x: i32 },
}An algebraic data type. Variants may be bare or carry a tuple or struct payload, and a match on an enum must cover every variant. Name::Variant names a variant; methods are added with implement enum Name { ... }.
type enum SeekFrom {
Start(u64);
Current(i64);
End(i64);
}Anchor for a Seek::seek. The seek target is one of: an absolute byte offset from the start (Start, always non-negative), a signed delta from the current position (Current), or a signed delta from the end (End). Current/End deltas may be negative; seeking to a negative absolute offset is an error.
SeekFrom::Start(u64)SeekFrom::Current(i64)SeekFrom::End(i64)type trait AsyncRead {
async fill(mut &this) -> Result<u64, IoError>;
buffered(&this) -> Slice<u8>;
consume(mut &this, count: u64) -> void;
scan_for(&this, delimiter: u8, from: u64) -> u64;
take_front(mut &this, count: u64) -> Result<Array<u8>, IoError>;
async ensure(mut &this, count: u64) -> Result<(), IoError>;
async read_exact(mut &this, count: u64) -> Result<Array<u8>, IoError>;
async read_some(mut &this, limit: u64) -> Result<Array<u8>, IoError>;
async read_until(mut &this, delimiter: u8, limit: u64) -> Result<Array<u8>, IoError>;
async read_line(mut &this, limit: u64) -> Result<String, IoError>;
// … 1 more
}A byte source that buffers what it reads inside itself.
async function name(param: Type) -> T { ... }Compiles the function into a stackless state machine. Calling it builds a future whose output is the declared return type; nothing runs until that future is polled. Allowed on free functions, methods, and trait methods.
language referenceasync AsyncRead::fill(mut &this) -> Result<u64, IoError>Pull more bytes from the transport into the connection's buffer and return how many arrived. Zero means the peer closed its end: no later fill will produce anything either.
AsyncRead::buffered(&this) -> Slice<u8>The bytes that have been read but not yet consumed.
AsyncRead::consume(mut &this, count: u64) -> voidDiscard the first count buffered bytes, which the caller has finished with. count must not exceed buffered().length().
(parameter) count: u64AsyncRead::scan_for(&this, delimiter: u8, from: u64) -> u64Index just past the first delimiter at or after from, or 0 when it is not in the buffer yet.
(parameter) from: u64AsyncRead::take_front(mut &this, count: u64) -> Result<Array<u8>, IoError>Copy the first count buffered bytes out and consume them. Callers that can parse in place should read buffered() directly and call consume themselves; this is for the cases that need to keep the bytes past the next fill.
async AsyncRead::ensure(mut &this, count: u64) -> Result<(), IoError>Fill until at least count bytes are buffered. EOF before that is UnexpectedEof: the caller asked for bytes the peer will never send.
async AsyncRead::read_exact(mut &this, count: u64) -> Result<Array<u8>, IoError>Read exactly count bytes and hand them back. A short stream is UnexpectedEof.
async AsyncRead::read_some(mut &this, limit: u64) -> Result<Array<u8>, IoError>Read whatever is available, up to limit bytes, suspending only if nothing is buffered yet. An empty result means EOF — it is the terminating condition for a streaming copy, not an error.
(parameter) limit: u64async AsyncRead::read_until(mut &this, delimiter: u8, limit: u64) -> Result<Array<u8>, IoError>Read up to and including the first delimiter. The delimiter is part of the returned bytes.
async AsyncRead::read_line(mut &this, limit: u64) -> Result<String, IoError>Read one \n-terminated line, without the terminator. A \r immediately before it is stripped too, so this reads CRLF and LF framing alike. limit caps the line length as in read_until.
async AsyncRead::skip(mut &this, count: u64) -> Result<(), IoError>Discard exactly count bytes. Cheaper than read_exact for payload a caller is required to consume but does not want, such as frame padding.
type trait AsyncWrite {
pending(mut &this) -> Array<u8>*;
async flush(mut &this) -> Result<(), IoError>;
queue<T>(mut &this, data: T) -> Result<(), IoError>;
async send<T>(mut &this, data: T) -> Result<(), IoError>;
}A byte sink that buffers what it is given until told to send it.
AsyncWrite::pending(mut &this) -> Array<u8>*The connection's outgoing buffer, for queue to append to and flush to drain. Exposed rather than wrapped so an encoder can build a frame directly in place instead of into a scratch array that is then copied.
async AsyncWrite::flush(mut &this) -> Result<(), IoError>Put every queued byte on the wire, suspending as often as the transport needs, and clear the buffer. A failure leaves the unsent bytes queued, so a caller that can retry still has them.
AsyncWrite::queue<T>(mut &this, data: T) -> Result<(), IoError>Append data to the outgoing buffer without sending anything. Generic over the payload and dispatched at compile time: a raw Slice<u8>, a Str view, a NUL-terminated C string, or a single u8.
type parameter Tasync AsyncWrite::send<T>(mut &this, data: T) -> Result<(), IoError>Queue data and send it immediately. The one-shot convenience for a caller with nothing else to add; a caller with several pieces should queue each and flush once.
type parameter Ttype trait AsyncTransport {
async read_into(mut &this, buf: Array<u8>) -> Transfer;
async write_from(mut &this, buf: Array<u8>) -> Transfer;
}One raw, unbuffered async byte channel: what BufStream<S> needs of a transport, and nothing more.
async AsyncTransport::read_into(mut &this, buf: Array<u8>) -> TransferRead into buf, completing with the bytes that arrived. Zero means the peer closed its end.
(parameter) buf: Array<u8>type struct Transfer {
buf: Array<u8>;
result: Result<u64, IoError>;
}What a transport hands back from one operation: the buffer it was lent, plus how many bytes moved.
std::io::traitsasync AsyncTransport::write_from(mut &this, buf: Array<u8>) -> TransferWrite from buf, completing with the bytes accepted, which may be fewer than offered — the caller sends the remainder in another operation.
type struct Name {
field: Type;
method(&this) -> Ret { ... }
}A value type with named fields and optional methods. Structs live on the stack and are passed by value. Fields are public by default and may carry = default values; methods take their receiver as &this, mut &this, or this.
type struct Transfer {
buf: Array<u8>;
result: Result<u64, IoError>;
}What a transport hands back from one operation: the buffer it was lent, plus how many bytes moved.
Transfer.buf: Array<u8>Transfer.result: Result<u64, IoError>Transfer::take_buf(mut &this) -> Array<u8>Take the buffer back. Calling it twice yields an empty array the second time — the transfer holds the buffer exactly once.
Transfer::outcome(&this) -> Result<u64, IoError>How many bytes moved, or why none did.
const NAME: Type = value;At module level, a true compile-time constant, conventionally SCREAMING_SNAKE_CASE. (mut at module level declares mutable global state instead.)
const READ_TO_END_CHUNK: u64 = 4096;const BYTE_LF: u8 = 0x0A;const BYTE_CR: u8 = 0x0D;import a::b;
import a::b::{ X, Y };
import a::b as c;
import a::b::*;Brings a module, or selected items from it, into scope. One path per declaration: use the brace form for several items, as to alias, and * for everything public (prefer the brace form; wildcards invite name collisions).
namespace std::io::traits;The byte-source and byte-sink traits, blocking and non-blocking.
module pageRead::read(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>Fill up to length bytes starting at buffer. Returns the number of bytes actually read. Zero means EOF; a value less than length means the underlying source had no more bytes available at this moment (not necessarily EOF; callers decide whether to retry).
Read::read_all(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>Read until the buffer is full or the source returns 0 (EOF). Returns the total bytes read; short returns mean EOF reached. Retries on Interrupted.
IoErrorKind::InterruptedRead::read_exact(mut &this, buffer: u8*, length: u64) -> Result<(), IoError>Read exactly length bytes. A short read at EOF is a failure, reported as UnexpectedEof. Use this when the caller knows the precise number of bytes that must be present.
IoErrorKind::UnexpectedEofRead::read_byte(mut &this) -> Result<Option<u8>, IoError>Read a single byte. None means EOF: the source is empty and no more reads will yield data. Retries on Interrupted.
Option::NoneRead::read_until(mut &this, delimiter: u8, out: mut &Array<u8>) -> Result<u64, IoError>Read bytes into out until delimiter is seen or EOF. The delimiter byte is included in out. Returns the number of bytes appended.
Read::read_line(mut &this, out: mut &String) -> Result<u64, IoError>Read bytes into out until a \n or EOF. The newline byte is included in out. Returns the number of bytes appended (0 only if the very first read hit EOF).
Read::read_to_end(mut &this, out: mut &Array<u8>) -> Result<u64, IoError>Read every remaining byte into out, growing the array as needed. Returns the number of bytes appended. EOF terminates the loop; other errors abort and surface.
Read::read_to_string(mut &this, out: mut &String) -> Result<u64, IoError>Read every remaining byte into out as UTF-8. Convenience wrapper around read_to_end for the common "slurp text from this source" case. The bytes are **not** validated; the caller certifies the source is UTF-8 (or accepts the consequences of invalid continuation bytes in a String).
Read::read_char(mut &this) -> Result<Option<u32>, IoError>Read a single UTF-8 Unicode scalar and return its codepoint. None is EOF before the first byte of the scalar. A partial scalar (first byte read, continuation missing) fails with UnexpectedEof; a malformed leading byte or continuation fails with InvalidData.
IoErrorKind::InvalidDatafunction name(count: i32, args...)A variadic parameter: the trailing bucket receives any number of further arguments with C's calling convention, so the function stays ABI-compatible with the printf family. Wrap the bucket in VaArgs to read typed values from it.
type struct BufReader<R> where R: Read {
reader: R*;
buffer: u8*;
capacity: u64;
position: u64;
filled: u64;
}Pulls from R in buffer-sized chunks and serves reads from the buffer. Transforms a stream of small reads into a few large ones and makes read_line fast: no per-byte syscall.
implement struct Name { ... }
implement trait Trait for Type { ... }
implement u64 { ... }Adds methods to a type outside its declaration. implement struct T (or enum, or a bare primitive) opens an inherent block; implement trait Tr for T supplies a trait's methods for one type. Resolution is at compile time - no dynamic dispatch.
implement trait Trait for Type { ... }Introduces a trait implementation: the block supplies, for one concrete type, the method bodies the trait requires.
language referencetype trait Read {
read(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>;
read_all(mut &this, buffer: u8*, length: u64) -> Result<u64, IoError>;
read_byte(mut &this) -> Result<Option<u8>, IoError>;
read_char(mut &this) -> Result<Option<u32>, IoError>;
read_until(mut &this, delimiter: u8, out: mut &Array<u8>) -> Result<u64, IoError>;
read_exact(mut &this, buffer: u8*, length: u64) -> Result<(), IoError>;
read_to_end(mut &this, out: mut &Array<u8>) -> Result<u64, IoError>;
read_to_string(mut &this, out: mut &String) -> Result<u64, IoError>;
read_line(mut &this, out: mut &String) -> Result<u64, IoError>;
}implement trait Trait for Type { ... }Names the type a trait implementation is for. The block that follows supplies the bodies the trait requires.
language referencetype parameter Rwhere R: Read
where T: Ord + Clone, U: HashConstrains generic parameters to types that implement the listed traits, which is what makes those traits' methods callable on T. Bounds on one parameter join with +; parameters separate with ,. A where on a single method narrows the type's parameter for that method only.
type struct Cursor {
buffer: Array<u8>;
pos: u64;
}An in-memory Read + Write + Seek byte buffer. Owns its Array<u8>; drop releases it (or move it out with into_inner first).
type struct Stdin {}Handle to process standard input. Construction is free; all instances dispatch to file descriptor 0. Unbuffered: a line read that needs minimum syscalls should wrap this in a BufReader<Stdin> from io::buf.
type struct StdinLock {}RAII guard over the stdin lock; reads through fd 0. Get one from stdin().lock(). Inherits the Read trait defaults (read_line, read_to_string, ...).
type struct ChildStdout {
fd: i32;
}Read end of a pipe whose write end is the child's stdout.
std::process::childtype struct ChildStderr {
fd: i32;
}Read end of a pipe whose write end is the child's stderr.
std::process::childWrite::write_some(mut &this, bytes: Slice<u8>) -> Result<u64, IoError>Low-level primitive: write up to bytes.length() bytes, returning the number actually written (may be less than requested on a slow sink). Every implementor provides this; the generic write loops over it to deliver every byte.
Write::flush(mut &this) -> Result<(), IoError>Push any buffered bytes to the underlying sink. Unbuffered writers override with a no-op.
std::io::traitsWrite::write<T>(mut &this, data: T) -> Result<(), IoError>Write data in full, retrying short writes and Interrupted errors. Generic over the payload, dispatched at compile time via static match: a raw byte Slice<u8>, a Str view, a NUL-terminated C string, or a single u8.
type struct Str {
bytes: u8*;
length: u64;
}Str: a borrowed UTF-8 string slice.
std::collections::strprimitive stringNUL-terminated raw string (u8*), matching the C ABI. Length-typed text is Str / String.
IoErrorKind::WriteZerostatic match (T) { ... }Opens a compile-time match on a type parameter: the one arm whose type matches is kept during monomorphisation and the rest are discarded.
static match (T) {
u8 | u16 => { ... }
_ => { ... }
}Selects a body by inspecting a type parameter at compile time. The subject is a type and each arm is a type (| groups several; _ takes the rest). During monomorphisation the one matching arm is kept and the others discarded, so there is no runtime branch.
type trait Write {
write_some(mut &this, bytes: Slice<u8>) -> Result<u64, IoError>;
flush(mut &this) -> Result<(), IoError>;
write<T>(mut &this, data: T) -> Result<(), IoError>;
}type parameter Wwhere W: Write
type struct BufWriter<W> where W: Write {
writer: W*;
buffer: u8*;
capacity: u64;
length: u64;
}Coalesces writes destined for W into larger flushes. The inner writer is borrowed via pointer; the caller owns it and drops it.
type struct LineWriter<W> {
inner: BufWriter<W>;
}A BufWriter that flushes after any write containing a \n. Appropriate for interactive stdout on a TTY, where "the user saw the line as soon as it was emitted" matters more than coalescing.
type struct Stdout {}Handle to process standard output. Unbuffered; wrap in LineWriter<Stdout> or BufWriter<Stdout> from io::buf for the common "coalesce many small writes" case.
type struct Stderr {}Handle to process standard error. Unbuffered by convention so diagnostics appear immediately; do **not** wrap in BufWriter unless you also guarantee a flush on every path that might panic or exit.
type struct StdoutLock {}RAII guard over the stdout lock; writes through fd 1. Get one from stdout().lock(). Inherits the Write trait default write (generic over the payload).
type struct StderrLock {}RAII guard over the stderr lock; writes through fd 2. Get one from stderr().lock().
type struct ChildStdin {
fd: i32;
}Write end of a pipe whose read end is the child's stdin.
std::process::childSeek::seek(mut &this, from: SeekFrom) -> Result<u64, IoError>Reposition the cursor and return the new absolute offset from the start of the stream. Seeking past the end is permitted; the effect of a later read/write there is sink-specific (a File leaves a sparse gap the OS zero-fills; an in-memory Cursor zero-fills on the next write).
Seek::stream_position(mut &this) -> Result<u64, IoError>Current absolute offset, without moving. Default: seek(Current(0)).
SeekFrom::Current(i64)Seek::rewind(mut &this) -> Result<(), IoError>Reposition to the start of the stream. Default: seek(Start(0)).
SeekFrom::Start(u64)IoErrorKind::InvalidInputSeekFrom::End(i64)type trait Seek {
seek(mut &this, from: SeekFrom) -> Result<u64, IoError>;
stream_position(mut &this) -> Result<u64, IoError>;
rewind(mut &this) -> Result<(), IoError>;
}A byte stream whose read/write cursor can be repositioned. Absolute positions are u64 offsets from the start; every seek returns the resulting absolute position.
type trait AsyncRead {
async fill(mut &this) -> Result<u64, IoError>;
buffered(&this) -> Slice<u8>;
consume(mut &this, count: u64) -> void;
scan_for(&this, delimiter: u8, from: u64) -> u64;
take_front(mut &this, count: u64) -> Result<Array<u8>, IoError>;
async ensure(mut &this, count: u64) -> Result<(), IoError>;
async read_exact(mut &this, count: u64) -> Result<Array<u8>, IoError>;
async read_some(mut &this, limit: u64) -> Result<Array<u8>, IoError>;
async read_until(mut &this, delimiter: u8, limit: u64) -> Result<Array<u8>, IoError>;
async read_line(mut &this, limit: u64) -> Result<String, IoError>;
// … 1 more
}A byte source that buffers what it reads inside itself.
std::io::traitsasync AsyncRead::fill(mut &this) -> Result<u64, IoError>Pull more bytes from the transport into the connection's buffer and return how many arrived. Zero means the peer closed its end: no later fill will produce anything either.
AsyncRead::buffered(&this) -> Slice<u8>The bytes that have been read but not yet consumed.
std::io::traitsAsyncRead::consume(mut &this, count: u64) -> voidDiscard the first count buffered bytes, which the caller has finished with. count must not exceed buffered().length().
async AsyncRead::ensure(mut &this, count: u64) -> Result<(), IoError>Fill until at least count bytes are buffered. EOF before that is UnexpectedEof: the caller asked for bytes the peer will never send.
await futureSuspends the enclosing async body until the operand - which must implement Future - completes, and evaluates to its output. A prefix operator allowed anywhere an expression is (conditions, arms, guards), but only inside async code.
Slice::length(&this) -> u64AsyncRead::scan_for(&this, delimiter: u8, from: u64) -> u64Index just past the first delimiter at or after from, or 0 when it is not in the buffer yet.
// reservedA reserved keyword with no syntax of its own in the current grammar. The standard library uses it freely as a method and parameter name (Str::from, from: u64).
AsyncRead::take_front(mut &this, count: u64) -> Result<Array<u8>, IoError>Copy the first count buffered bytes out and consume them. Callers that can parse in place should read buffered() directly and call consume themselves; this is for the cases that need to keep the bytes past the next fill.
async AsyncRead::read_some(mut &this, limit: u64) -> Result<Array<u8>, IoError>Read whatever is available, up to limit bytes, suspending only if nothing is buffered yet. An empty result means EOF — it is the terminating condition for a streaming copy, not an error.
async AsyncRead::skip(mut &this, count: u64) -> Result<(), IoError>Discard exactly count bytes. Cheaper than read_exact for payload a caller is required to consume but does not want, such as frame padding.
type trait AsyncWrite {
pending(mut &this) -> Array<u8>*;
async flush(mut &this) -> Result<(), IoError>;
queue<T>(mut &this, data: T) -> Result<(), IoError>;
async send<T>(mut &this, data: T) -> Result<(), IoError>;
}A byte sink that buffers what it is given until told to send it.
std::io::traitsAsyncWrite::pending(mut &this) -> Array<u8>*The connection's outgoing buffer, for queue to append to and flush to drain. Exposed rather than wrapped so an encoder can build a frame directly in place instead of into a scratch array that is then copied.
AsyncWrite::queue<T>(mut &this, data: T) -> Result<(), IoError>Append data to the outgoing buffer without sending anything. Generic over the payload and dispatched at compile time: a raw Slice<u8>, a Str view, a NUL-terminated C string, or a single u8.
async AsyncWrite::send<T>(mut &this, data: T) -> Result<(), IoError>Queue data and send it immediately. The one-shot convenience for a caller with nothing else to add; a caller with several pieces should queue each and flush once.
type trait AsyncTransport {
async read_into(mut &this, buf: Array<u8>) -> Transfer;
async write_from(mut &this, buf: Array<u8>) -> Transfer;
}One raw, unbuffered async byte channel: what BufStream<S> needs of a transport, and nothing more.
type struct TcpStream {
fd: i32;
}type struct TlsStream {
ssl: void*;
inner: TcpStream;
}type struct BufStream<S> {
inner: S;
rbuf: Array<u8>;
rpos: u64;
scratch: Array<u8>;
wbuf: Array<u8>;
}async AsyncTransport::read_into(mut &this, buf: Array<u8>) -> TransferRead into buf, completing with the bytes that arrived. Zero means the peer closed its end.
Transfer.buf: Array<u8>async AsyncTransport::write_from(mut &this, buf: Array<u8>) -> TransferWrite from buf, completing with the bytes accepted, which may be fewer than offered — the caller sends the remainder in another operation.
Transfer.result: Result<u64, IoError>Transfer::take_buf(mut &this) -> Array<u8>Take the buffer back. Calling it twice yields an empty array the second time — the transfer holds the buffer exactly once.
std::io::traitsTransfer::outcome(&this) -> Result<u64, IoError>How many bytes moved, or why none did.
std::io::traitstype parameter S