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

AsyncBufferedWriter

Owns a fixed-capacity byte cache and its concrete AsyncWriter source. Construction allocates; subsequent cache operations do not grow storage. Mutable receiver loans remain live across suspension; external synchronization is required. Movement transfers the source and cache, leaving the old adapter closed. Destruction never performs hidden I/O.

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.

AsyncBufferedWriter

pub final class AsyncBufferedWriter<S> where S: AsyncWriter, Movable

Owns a fixed-capacity byte cache and its concrete AsyncWriter source. Construction allocates; subsequent cache operations do not grow storage. Mutable receiver loans remain live across suspension; external synchronization is required. Movement transfers the source and cache, leaving the old adapter closed. Destruction never performs hidden I/O. S: Movable structural AsyncWriter implementation.

Example

module example.async_buffered_streams;
from std.io import AsyncBufferedReader, AsyncBufferedWriter, IoError;
from std.prelude import Result;
from std.task import Task, CancellationToken, CancellationSource, YieldAsync;
struct Source {
    pub Written: usize;
    pub ReadCount: usize;
    pub FailNext: bool;
    pub init() { this.Written = 0; this.ReadCount = 0; this.FailNext = true; }
    pub async fn WriteAsync(Input: readonly byte[], mut Token: CancellationToken) -> Task<Result<usize, IoError>> {
        switch await YieldAsync(move(Token)) { case .Ok => {} case .Err => return .Err { Error = .Failure { Reason = .Cancelled, Transferred = 0 } }; }
        if this.FailNext { this.FailNext = false; return .Err { Error = .Failure { Reason = .Interrupted, Transferred = 0 } }; }
        if Input.Length == 0 { return .Ok { Value = 0 }; }
        this.Written += 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; }
    pub async fn ReadAsync(Output: mut byte[], mut Token: CancellationToken) -> Task<Result<usize, IoError>> {
        switch await YieldAsync(move(Token)) { case .Ok => {} case .Err => return .Err { Error = .Failure { Reason = .Cancelled, Transferred = 0 } }; }
        if this.ReadCount != 0 || Output.Length == 0 { return .Ok { Value = 0 }; }
        Output[0] = 0x61_byte; this.ReadCount += 1; return .Ok { Value = 1 };
    }
}
async fn Main() -> Task<i32> {
    var Writer = {
        // Scoped writable carriers end immediately after explicit payload transfer.
        var WriterCreation = AsyncBufferedWriter<Source>.TryCreate(Source(), 2);
        switch WriterCreation {
            case .Ok { Value = Value: mut AsyncBufferedWriter<Source>& } => break move(Value);
            case .Err => return 1;
        }
    };
    let Input: byte[2] = [0x61_byte, 0x62_byte];
    if await Writer.WriteAsync(Input) is .Err { Error = _ } { return 2; }
    if Writer.BufferedLength != 2 || Writer.Capacity != 2 || Writer.IsClosed { return 3; }
    switch await Writer.FlushAsync() {
        case .Err { Error = PatternPayload5003 } => {
            switch PatternPayload5003 {
                case .Failure { Reason = PatternPayload5004, Transferred = Count } if (PatternPayload5004 is .Interrupted) => { if Count != 0 { return 4; } }
                default => return 5;
            }
        }
        default => return 5;
    }
    if Writer.BufferedLength != 2 { return 6; }
    var Finished = switch await Writer.TryFinishAsync() { case .Ok { Value = Value } => break Value; case .Err => return 7; };
    if Finished.Written != 2 || !Writer.IsClosed { return 8; }
    var Reader = {
        var ReaderCreation = AsyncBufferedReader<Source>.TryCreate(Source(), 2);
        switch ReaderCreation {
            case .Ok { Value = Value: mut AsyncBufferedReader<Source>& } => break move(Value);
            case .Err => return 9;
        }
    };
    var Moved = move(Reader);
    if !Reader.IsClosed { return 10; }
    var Output: byte[1] = [0_byte];
    switch await Moved.ReadAsync(Output) { case .Ok { Value = Count } => { if Count != 1 || Output[0] != 0x61_byte { return 11; } } case .Err => return 12; }
    switch await Moved.ReadAsync(Output) { case .Ok { Value = Count } => { if Count != 0 { return 13; } } case .Err => return 14; }
    var Original = Moved.DiscardBufferedBytesAndTakeSource();
    if !Moved.IsClosed || Original.ReadCount != 1 { return 15; }
    switch AsyncBufferedWriter<Source>.TryCreate(Source(), 0) {
        case .Err { Error = Error } => { if !Error.Source.FailNext { return 16; } switch Error.Reason {
            case .Failure { Reason = PatternPayload5005 } if (PatternPayload5005 is .InvalidInput) => {}
            default => return 17;
        } }
        case .Ok => return 18;
    }
    var Cancellation = {
        var CancellationCreation = CancellationSource.TryCreate();
        switch CancellationCreation {
            case .Ok { Value = Value: mut CancellationSource& } => break move(Value);
            case .Err => return 19;
        }
    };
    if !Cancellation.RequestCancellation() { return 20; }
    var CancelledWriter = {
        var CancelledWriterCreation = AsyncBufferedWriter<Source>.TryCreate(Source(), 2);
        switch CancelledWriterCreation {
            case .Ok { Value = Value: mut AsyncBufferedWriter<Source>& } => break move(Value);
            case .Err => return 21;
        }
    };
    switch await CancelledWriter.WriteAsync(Input, Cancellation.Token) {
        case .Err { Error = PatternPayload5006 } => {
            switch PatternPayload5006 {
                case .Failure { Reason = PatternPayload5007, Transferred = Count } if (PatternPayload5007 is .Cancelled) => { if Count != 0 || CancelledWriter.BufferedLength != 0 { return 22; } }
                default => return 23;
            }
        }
        default => return 23;
    }
    if await CancelledWriter.WriteAsync(Input) is .Err { Error = _ } { return 24; }
    switch await CancelledWriter.FlushAsync(Cancellation.Token) {
        case .Err { Error = PatternPayload5008 } => {
            switch PatternPayload5008 {
                case .Failure { Reason = PatternPayload5009, Transferred = Count } if (PatternPayload5009 is .Cancelled) => { if Count != 0 || CancelledWriter.BufferedLength != 2 { return 25; } }
                default => return 26;
            }
        }
        default => return 26;
    }
    var CancelledReader = {
        var CancelledReaderCreation = AsyncBufferedReader<Source>.TryCreate(Source(), 2);
        switch CancelledReaderCreation {
            case .Ok { Value = Value: mut AsyncBufferedReader<Source>& } => break move(Value);
            case .Err => return 27;
        }
    };
    switch await CancelledReader.ReadAsync(Output, Cancellation.Token) {
        case .Err { Error = PatternPayload5010 } => {
            switch PatternPayload5010 {
                case .Failure { Reason = PatternPayload5011, Transferred = Count } if (PatternPayload5011 is .Cancelled) => { if Count != 0 { return 28; } }
                default => return 29;
            }
        }
        default => return 29;
    }
    var UnreadSource = CancelledReader.DiscardBufferedBytesAndTakeSource();
    if UnreadSource.ReadCount != 0 { return 30; }
    return 0;
}

AsyncBufferedWriter.init

pub init(Source: readonly Self&) = delete;

Rejects implicit source/cache copying. Source: Existing adapter.

AsyncBufferedWriter.operator

pub fn operator =(Source: readonly Self&) -> void = delete;

Rejects replacement that could silently discard pending bytes. Source: Existing adapter. Return: No runtime result; this assignment is deleted and cannot be invoked.

AsyncBufferedWriter.operator

pub fn operator =(Source: mut Self&&) -> void = delete;

Requires explicit finishing/extraction before replacing an adapter. Source: Existing adapter. Return: No runtime result; this assignment is deleted and cannot be invoked.

AsyncBufferedWriter.Capacity

pub Capacity: usize;

Observes initialized cache capacity in bytes.

AsyncBufferedWriter.IsClosed

pub IsClosed: bool;

Observes extraction/movement closure without I/O.

AsyncBufferedWriter.TryCreate

pub static fn TryCreate(mut Source: S, Capacity: usize) -> Result<Self, BufferedStreamCreationError<S>>

Allocates initialized cache slots and transfers a concrete source. Source: Owned source; returned in the error on failure. Capacity: Positive cache capacity in bytes; default is 8192. Return: Adapter or error retaining the source; no stream I/O occurs. Warning: May allocate.

AsyncBufferedWriter.TryCreate

pub static fn TryCreate(mut Source: S) -> Result<Self, BufferedStreamCreationError<S>>

Supplies the omitted arguments to TryCreate. Note: Defaults: Capacity = DefaultBufferCapacity. Source: Same input, ownership and lifetime contract as the full operation. Return: The full synchronous operation's owned success value or typed failure.

AsyncBufferedWriter.init

pub init(Source: mut Self&&)

Transfers pending bytes without flushing. Source: Adapter left closed.

AsyncBufferedWriter.BufferedLength

pub BufferedLength: usize;

Counts accepted bytes not yet submitted to the source.

AsyncBufferedWriter.WriteAsync

pub async fn WriteAsync(Input: readonly byte[], mut Token: CancellationToken) -> Task<Result<usize, IoError>>

Accepts input into owned cache, draining full cache when necessary. Input: Borrowed bytes retained through completion, copied into owned cache. Token: Cancellation observation copied into sequential source writes. Return: Task yielding accepted input count or failure counting only this call's accepted prefix. Warning: May suspend in source writes; never implicitly calls source Flush.

AsyncBufferedWriter.WriteAsync

pub fn WriteAsync(Input: readonly byte[]) -> Task<Result<usize, IoError>>

Supplies the omitted arguments to WriteAsync. Note: Defaults: Token = CancellationToken(). Input: Same input, ownership and lifetime contract as the full operation. Return: Exact full-operation result; no additional async frame is created.

AsyncBufferedWriter.FlushAsync

pub async fn FlushAsync(mut Token: CancellationToken) -> Task<Result<void, IoError>>

Submits pending bytes and then flushes downstream layers. Token: Cancellation observation copied into source writes and flush. Return: Task yielding success or failure counting bytes submitted from this cache in this call. Warning: May suspend; never promises durable storage. Unwritten tail survives failure.

AsyncBufferedWriter.FlushAsync

pub fn FlushAsync() -> Task<Result<void, IoError>>

Supplies the omitted arguments to FlushAsync. Note: Defaults: Token = CancellationToken(). Return: Exact full-operation result; no additional async frame is created.

AsyncBufferedWriter.TryFinishAsync

pub async fn TryFinishAsync(mut Token: CancellationToken) -> Task<Result<S, IoError>>

Flushes successfully before transferring the source. Token: Cancellation observation for the flush operation. Return: Task yielding owned source, or failure leaving this adapter available for retry. Warning: May suspend; do not move the adapter while pending. Destruction alone discards pending bytes without flushing.

AsyncBufferedWriter.TryFinishAsync

pub fn TryFinishAsync() -> Task<Result<S, IoError>>

Supplies the omitted arguments to TryFinishAsync. Note: Defaults: Token = CancellationToken(). Return: Exact full-operation result; no additional async frame is created.

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