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.
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, MovableOwns 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.