Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
Development · Evolving reference

ReadExactlyAsync

Completes an incremental byte transfer by awaiting one short operation at a time. Preserves exact partial error identity/counts, validates reported lengths and adds no intermediate byte buffer or implicit flush. Zero length makes no source operation. Source and byte backing loans remain live until task completion.

Sn is under heavy development. This reference includes the intended 1.0 design; features may be incomplete in the current compiler. Read the status →

Module std.io

import std.io;

Public declaration contracts and authored examples. A page can document several related symbols. Implementation bodies are excluded.

ReadExactlyAsync

pub async fn ReadExactlyAsync<S>(Source: mut S&, Output: mut byte[], mut Token: CancellationToken) -> Task<Result<void, IoError>>
    where S: AsyncReader

Completes an incremental byte transfer by awaiting one short operation at a time. Preserves exact partial error identity/counts, validates reported lengths and adds no intermediate byte buffer or implicit flush. Zero length makes no source operation. Source and byte backing loans remain live until task completion. S: Concrete mutable AsyncReader stream. Source: Borrowed mutable stream retained by ordinary origin rules. Output: Borrowed mut bytes retained through completion. Token: Owned cancellation observation copied into each awaited step. Return: Task yielding complete success or exact proven transferred-prefix error. Warning: Do not mutate/move borrowed backing or source while work is pending.

Example

module example.exact_async_io;
from std.io import ReadExactlyAsync, WriteAllAsync, IoError;
from std.prelude import Result;
from std.task import Task, CancellationToken, YieldAsync;
struct Stream {
    pub ReadCount: usize; pub WriteCount: usize;
    pub init() { this.ReadCount = 0; this.WriteCount = 0; }
    pub async fn ReadAsync(Output: mut byte[], mut Token: CancellationToken) -> Task<Result<usize, IoError>> {
        if Output.Length == 0 || this.ReadCount == 3 { return .Ok { Value = 0 }; }
        switch await YieldAsync(move(Token)) { case .Ok => {} case .Err => return .Err { Error = .Failure { Reason = .Cancelled, Transferred = 0 } }; }
        Output[0] = 0x61_byte; this.ReadCount += 1; return .Ok { Value = 1 };
    }
    pub async fn WriteAsync(Input: readonly byte[], mut Token: CancellationToken) -> Task<Result<usize, IoError>> {
        if Input.Length == 0 { return .Ok { Value = 0 }; }
        switch await YieldAsync(move(Token)) { case .Ok => {} case .Err => return .Err { Error = .Failure { Reason = .Cancelled, Transferred = 0 } }; }
        this.WriteCount += 1; return .Ok { Value = 1 };
    }
    pub async fn FlushAsync(mut Token: CancellationToken) -> Task<Result<void, IoError>> {
        if Token.IsCancellationRequested { return .Err { Error = .Failure { Reason = .Cancelled, Transferred = 0 } }; }
        return .Ok;
    }
}
async fn Main() -> Task<i32> {
    var Source = Stream();
    var Bytes: byte[3] = [0_byte, 0_byte, 0_byte];
    if await ReadExactlyAsync(Source, Bytes) is .Err { Error = _ } { return 1; }
    if await WriteAllAsync(Source, Bytes) is .Err { Error = _ } { return 2; }
    if await Source.FlushAsync(CancellationToken()) is .Err { Error = _ } { return 3; }
    if Source.ReadCount != 3 || Source.WriteCount != 3 || Bytes[2] != 0x61_byte { return 4; }
    return 0;
}

ReadExactlyAsync

pub fn ReadExactlyAsync<S>(Source: mut S&, Output: mut byte[]) -> Task<Result<void, IoError>>
    where S: AsyncReader

Supplies the omitted arguments to ReadExactlyAsync. Note: Defaults: Token = CancellationToken(). S: Same generic argument and constraints as the full operation. Source: Same input, ownership and lifetime contract as the full operation. Output: Same input, ownership and lifetime contract as the full operation. Return: Exact full-operation result; no additional async frame is created.

Documentation snapshot: October 24, 2026 About versions ↗
Searching Development · language & standard library