README
WASI I/O is an I/O abstraction API which is currently focused on providing stream types.

In the future, the component model is expected to add built-in stream types; when it does, they are expected to subsume this API.

#
InputStream

pub(all) type InputStream Int derive(Eq, Show)

An input bytestream.

input-streams are non-blocking to the extent practical on underlying platforms. I/O operations always return promptly; if fewer bytes are promptly available than requested, they return the number of bytes promptly available, which could even be zero. To wait for data to be available, use the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

#
InputStream::blocking_read

fn InputStream::blocking_read(self : InputStream, len : UInt64) -> Result[FixedArray[Byte], StreamError]

Read bytes from a stream, after blocking until at least one byte can be read. Except for blocking, behavior is identical to read.

#
InputStream::blocking_skip

fn InputStream::blocking_skip(self : InputStream, len : UInt64) -> Result[UInt64, StreamError]

Skip bytes from a stream, after blocking until at least one byte can be skipped. Except for blocking behavior, identical to skip.

#
InputStream::drop

fn InputStream::drop(self : InputStream) -> Unit

Drops a resource handle.

#
InputStream::inner

#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn InputStream::inner(self : InputStream) -> Int
Convert newtype to its underlying type, automatically derived.

#
InputStream::read

fn InputStream::read(self : InputStream, len : UInt64) -> Result[FixedArray[Byte], StreamError]

Perform a non-blocking read from the stream.

When the source of a read is binary data, the bytes from the source are returned verbatim. When the source of a read is known to the implementation to be text, bytes containing the UTF-8 encoding of the text are returned.

This function returns a list of bytes containing the read data, when successful. The returned list will contain up to len bytes; it may return fewer than requested, but not more. The list is empty when no bytes are available for reading at this time. The pollable given by subscribe will be ready when more bytes are available.

This function fails with a stream-error when the operation encounters an error, giving last-operation-failed, or when the stream is closed, giving closed.

When the caller gives a len of 0, it represents a request to read 0 bytes. If the stream is still open, this call should succeed and return an empty list, or otherwise fail with closed.

The len parameter is a u64, which could represent a list of u8 which is not possible to allocate in wasm32, or not desirable to allocate as as a return value by the callee. The callee may return a list of bytes less than len in size while more bytes are available for reading.

#
InputStream::skip

fn InputStream::skip(self : InputStream, len : UInt64) -> Result[UInt64, StreamError]

Skip bytes from a stream. Returns number of bytes skipped.

Behaves identical to read, except instead of returning a list of bytes, returns the number of bytes consumed from the stream.

#
InputStream::subscribe

Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed. The created pollable is a child resource of the input-stream. Implementations may trap if the input-stream is dropped before all derived pollables created with this function are dropped.

#
OutputStream

pub(all) type OutputStream Int derive(Eq, Show)

An output bytestream.

output-streams are non-blocking to the extent practical on underlying platforms. Except where specified otherwise, I/O operations also always return promptly, after the number of bytes that can be written promptly, which could even be zero. To wait for the stream to be ready to accept data, the subscribe function to obtain a pollable which can be polled for using wasi:io/poll.

#
OutputStream::blocking_flush

fn OutputStream::blocking_flush(self : OutputStream) -> Result[Unit, StreamError]

Request to flush buffered output, and block until flush completes and stream is ready for writing again.

#
OutputStream::blocking_splice

fn OutputStream::blocking_splice(self : OutputStream, src : InputStream, len : UInt64) -> Result[UInt64, StreamError]

Read from one stream and write to another, with blocking.

This is similar to splice, except that it blocks until the output-stream is ready for writing, and the input-stream is ready for reading, before performing the splice.

#
OutputStream::blocking_write_and_flush

fn OutputStream::blocking_write_and_flush(self : OutputStream, contents : FixedArray[Byte]) -> Result[Unit, StreamError]

Perform a write of up to 4096 bytes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

This is a convenience wrapper around the use of check-write, subscribe, write, and flush, and is implemented with the following pseudo-code:

let pollable = this.subscribe(); while !contents.is_empty() { // Wait for the stream to become writable pollable.block(); let Ok(n) = this.check-write(); // eliding error handling let len = min(n, contents.len()); let (chunk, rest) = contents.split_at(len); this.write(chunk ); // eliding error handling contents = rest; } this.flush(); // Wait for completion of `flush` pollable.block(); // Check for any errors that arose during `flush` let _ = this.check-write(); // eliding error handling

#
OutputStream::blocking_write_zeroes_and_flush

fn OutputStream::blocking_write_zeroes_and_flush(self : OutputStream, len : UInt64) -> Result[Unit, StreamError]

Perform a write of up to 4096 zeroes, and then flush the stream. Block until all of these operations are complete, or an error occurs.

This is a convenience wrapper around the use of check-write, subscribe, write-zeroes, and flush, and is implemented with the following pseudo-code:

let pollable = this.subscribe(); while num_zeroes != 0 { // Wait for the stream to become writable pollable.block(); let Ok(n) = this.check-write(); // eliding error handling let len = min(n, num_zeroes); this.write-zeroes(len); // eliding error handling num_zeroes -= len; } this.flush(); // Wait for completion of `flush` pollable.block(); // Check for any errors that arose during `flush` let _ = this.check-write(); // eliding error handling

#
OutputStream::check_write

fn OutputStream::check_write(self : OutputStream) -> Result[UInt64, StreamError]

Check readiness for writing. This function never blocks.

Returns the number of bytes permitted for the next call to write, or an error. Calling write with more bytes than this function has permitted will trap.

When this function returns 0 bytes, the subscribe pollable will become ready when this function will report at least 1 byte, or an error.

#
OutputStream::drop

fn OutputStream::drop(self : OutputStream) -> Unit

Drops a resource handle.

#
OutputStream::flush

fn OutputStream::flush(self : OutputStream) -> Result[Unit, StreamError]

Request to flush buffered output. This function never blocks.

This tells the output-stream that the caller intends any buffered output to be flushed. the output which is expected to be flushed is all that has been passed to write prior to this call.

Upon calling this function, the output-stream will not accept any writes (check-write will return ok(0)) until the flush has completed. The subscribe pollable will become ready when the flush has completed and the stream can accept more writes.

#
OutputStream::inner

#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn OutputStream::inner(self : OutputStream) -> Int
Convert newtype to its underlying type, automatically derived.

#
OutputStream::splice

fn OutputStream::splice(self : OutputStream, src : InputStream, len : UInt64) -> Result[UInt64, StreamError]

Read from one stream and write to another.

The behavior of splice is equivelant to:
  1. calling check-write on the output-stream
  2. calling read on the input-stream with the smaller of the check-write permitted length and the len provided to splice
  3. calling write on the output-stream with that read data.

Any error reported by the call to check-write, read, or write ends the splice and reports that error.

This function returns the number of bytes transferred; it may be less than len.

#
OutputStream::subscribe

Create a pollable which will resolve once the output-stream is ready for more writing, or an error has occured. When this pollable is ready, check-write will return ok(n) with n>0, or an error.

If the stream is closed, this pollable is always ready immediately.

The created pollable is a child resource of the output-stream. Implementations may trap if the output-stream is dropped before all derived pollables created with this function are dropped.

#
OutputStream::write

fn OutputStream::write(self : OutputStream, contents : FixedArray[Byte]) -> Result[Unit, StreamError]

Perform a write. This function never blocks.

When the destination of a write is binary data, the bytes from contents are written verbatim. When the destination of a write is known to the implementation to be text, the bytes of contents are transcoded from UTF-8 into the encoding of the destination and then written.

Precondition: check-write gave permit of Ok(n) and contents has a length of less than or equal to n. Otherwise, this function will trap.

returns Err(closed) without writing if the stream has closed since the last call to check-write provided a permit.

#
OutputStream::write_zeroes

fn OutputStream::write_zeroes(self : OutputStream, len : UInt64) -> Result[Unit, StreamError]

Write zeroes to a stream.

This should be used precisely like write with the exact same preconditions (must use check-write first), but instead of passing a list of bytes, you simply pass the number of zero-bytes that should be written.

#
StreamError

pub(all) enum StreamError {
LastOperationFailed(
Error_
)
Closed
} derive(Eq, Show)

An error for input-stream and output-stream operations.

Source Files

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io