ReadTextAsync
Collects and strictly decodes a complete UTF-8 stream. Validation occurs after EOF, so a Unicode sequence may span short reads. Invalid encoding and allocation/provider failures retain consumed bytes; no replacement decoding, newline conversion or locale behavior is introduced.
Module std.io
import std.io;Public declaration contracts and authored examples. A page can document several related symbols. Implementation bodies are excluded.
ReadTextAsync
pub async fn ReadTextAsync<S>(Source: mut S&, mut Token: CancellationToken) -> Task<Result<String, StreamReadError>> where S: AsyncReaderCollects and strictly decodes a complete UTF-8 stream. Validation occurs after EOF, so a Unicode sequence may span short reads. Invalid encoding and allocation/provider failures retain consumed bytes; no replacement decoding, newline conversion or locale behavior is introduced. S: Structural AsyncReader source type. Source: Borrowed mutable stream, retained through completion. Token: Cancellation observation passed into byte collection. Return: Task yielding owned immutable text or failure owning the consumed byte prefix. Warning: May allocate and suspend until EOF; text construction copies collected bytes.
Example
module example.async_stream_text;
from std.io import ReadBytesAsync, ReadTextAsync, WriteTextAsync, IoError;
from std.prelude import Result;
from std.task import Task, CancellationToken, YieldAsync;
class Stream {
pub Input: readonly byte[];
pub Offset: usize;
pub Written: usize;
pub FailAfterTwo: bool;
pub init(Input: readonly byte[], FailAfterTwo: bool) { this.Input = Input; this.Offset = 0; this.Written = 0; this.FailAfterTwo = FailAfterTwo; }
pub async fn ReadAsync(Output: mut byte[], mut Token: CancellationToken) -> Task<Result<usize, IoError>> {
// Match one enum layer at a time while preserving each original fallback.
switch await YieldAsync(move(Token)) { case .Ok => {} case .Err => return .Err { Error = .Failure { Reason = .Cancelled, Transferred = 0 } }; }
if Output.Length == 0 || this.Offset == this.Input.Length { return .Ok { Value = 0 }; }
if this.FailAfterTwo && this.Offset == 2 { Output[0] = this.Input[this.Offset]; this.Offset += 1; return .Err { Error = .Failure { Reason = .Interrupted, Transferred = 1 } }; }
Output[0] = this.Input[this.Offset]; this.Offset += 1; return .Ok { Value = 1 };
}
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 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>> { return .Ok; }
}
async fn Main() -> Task<i32> {
// U+03BB spans two one-byte provider reads; NUL is valid text content.
let Input: byte[4] = [0xCE_byte, 0xBB_byte, 0_byte, 0x61_byte];
var Source = Stream(Input, false);
var Text = switch await ReadTextAsync(Source) { case .Ok { Value = Value } => break Value; case .Err => return 1; };
if Text.View != "λ\0a" { return 2; }
if await WriteTextAsync(Source, Text.View) is .Err { Error = _ } { return 3; }
if Source.Written != 4 { return 4; }
let Invalid: byte[1] = [0xFF_byte];
var InvalidSource = Stream(Invalid, false);
switch await ReadTextAsync(InvalidSource) {
case .Err { Error = Error } => {
if Error.Bytes.Length != 1 || Error.Bytes.At(0) != 0xFF_byte { return 5; }
switch Error.Reason {
case .Failure { Reason = PatternPayload5014, Transferred = Count } if (PatternPayload5014 is .InvalidUtf8) => { if Count != 1 { return 6; } }
default => return 7;
}
}
case .Ok => return 8;
}
var FailingSource = Stream(Input, true);
switch await ReadBytesAsync(FailingSource) {
case .Err { Error = Error } => {
if Error.Bytes.Length != 3 || Error.Bytes.At(2) != 0_byte || FailingSource.Offset != 3 { return 9; }
switch Error.Reason {
case .Failure { Reason = PatternPayload5015, Transferred = Count } if (PatternPayload5015 is .Interrupted) => { if Count != 3 { return 10; } }
default => return 11;
}
}
case .Ok => return 12;
}
return 0;
}ReadTextAsync
pub fn ReadTextAsync<S>(Source: mut S&) -> Task<Result<String, StreamReadError>> where S: AsyncReaderSupplies the omitted arguments to ReadTextAsync. 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. Return: Exact full-operation result; no additional async frame is created.