Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
0.2.0 Preview 1 · Frozen documentation

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. Reference extracted from this release’s bundled standard library. Public API examples are not an exhaustive compatibility test. Read the matching release guide for tested workflows and limitations. 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