io

    MoonBit io: provide simplified I/O abstractions similar to Go.

    io
    moonbit
    Download zip
    Author
    Version
    0.23.16
    License
    Apache-2.0
    Last updated
    3 days ago
    Downloads
    37K

    Dependencies

    #gmlewis/io

    check

    This is a simplified io package based on Go's implementation: https://cs.opensource.google/go/go/+/refs/tags/go1.23.2:src/io/io.go which has the copyright notice:

    // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file.

    #Status

    The code has been updated to support compiler:

    $ moon version --all moon 0.1.20260827 (d0aaa07 2026-08-27) ~/.moon/bin/moon moonc v0.10.11+6ff76a5f9 (2026-08-28) ~/.moon/bin/moonc moonrun 0.1.20260827 (d0aaa07 2026-08-27) ~/.moon/bin/moonrun

    ByteReader

    pub(open) trait ByteReader {
    fn read_byte(Self) -> (Byte, IOError?)
    }

    ByteReader is the interface that wraps the read_byte method.

    read_byte reads and returns the next byte from the input or any error encountered. If read_byte returns an error, no input byte was consumed, and the returned byte value is undefined.

    read_byte provides an efficient interface for byte-at-time processing. A [Reader] that does not implement ByteReader can be wrapped using bufio.NewReader to add this method.

    ByteScanner

    pub(open) trait ByteScanner : ByteReader {
    fn unread_byte(Self) -> IOError?
    }

    ByteScanner is the interface that adds the unread_byte method to the basic read_byte method.

    unread_byte causes the next call to read_byte to return the last byte read. If the last operation was not a successful call to read_byte, unread_byte may return an error, unread the last byte read (or the byte prior to the last-unread byte), or (in implementations that support the [Seeker] interface) seek to one byte before the current offset.

    ByteWriter

    pub(open) trait ByteWriter {
    fn write_byte(Self, Byte) -> IOError?
    }

    ByteWriter is the interface that wraps the write_byte method.

    Closer

    pub(open) trait Closer {
    fn close(Self) -> IOError?
    }

    Closer is the interface that wraps the basic Close method.

    The behavior of Close after the first call is undefined. Specific implementations may document their own behavior.

    ReadCloser

    pub(open) trait ReadCloser : Reader + Closer {
    }

    ReadCloser is the interface that groups the basic Read and Close methods.

    ReadSeekCloser

    pub(open) trait ReadSeekCloser : Reader + Seeker + Closer {
    }

    ReadSeekCloser is the interface that groups the basic Read, Seek and Close methods.

    ReadSeeker

    pub(open) trait ReadSeeker : Reader + Seeker {
    }

    ReadSeeker is the interface that groups the basic Read and Seek methods.

    ReadWriteCloser

    pub(open) trait ReadWriteCloser : Reader + Writer + Closer {
    }

    ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.

    ReadWriteSeeker

    pub(open) trait ReadWriteSeeker : Reader + Writer + Seeker {
    }

    ReadWriteSeeker is the interface that groups the basic Read, Write and Seek methods.

    ReadWriter

    pub(open) trait ReadWriter : Reader + Writer {
    }

    ReadWriter is the interface that groups the basic Read and Write methods.

    Reader

    pub(open) trait Reader {
    fn read(Self, Slice[Byte]) -> (Int, IOError?)
    }

    Reader is the interface that wraps the basic Read method.

    Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered. Even if Read returns n < len(p), it may use all of p as scratch space during the call. If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting for more.

    When Read encounters an error or end-of-file condition after successfully reading n > 0 bytes, it returns the number of bytes read. It may return the (non-None) error from the same call or return the error (and n == 0) from a subsequent call. An instance of this general case is that a Reader returning a non-zero number of bytes at the end of the input stream may return either err == eof or err == None. The next Read should return 0, eof.

    Callers should always process the n > 0 bytes returned before considering the error err. Doing so correctly handles I/O errors that happen after reading some bytes and also both of the allowed eof behaviors.

    If len(p) == 0, Read should always return n == 0. It may return a non-None error if some error condition is known, such as eof.

    Implementations of Read are discouraged from returning a zero byte count with a None error, except when len(p) == 0. Callers should treat a return of 0 and None as indicating that nothing happened; in particular it does not indicate eof.

    Implementations must not retain p.

    ReaderAt

    pub(open) trait ReaderAt {
    fn read_at(Self, Slice[Byte], Int64) -> (Int, IOError?)
    }

    ReaderAt is the interface that wraps the basic read_at method.

    read_at reads len(p) bytes into p starting at offset off in the underlying input source. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered.

    When read_at returns n < len(p), it returns a non-None error explaining why more bytes were not returned. In this respect, read_at is stricter than Read.

    Even if read_at returns n < len(p), it may use all of p as scratch space during the call. If some data is available but not len(p) bytes, read_at blocks until either all the data is available or an error occurs. In this respect read_at is different from Read.

    If the n = len(p) bytes returned by read_at are at the end of the input source, read_at may return either err == eof or err == None.

    If read_at is reading from an input source with a seek offset, read_at should not affect nor be affected by the underlying seek offset.

    Clients of read_at can execute parallel read_at calls on the same input source.

    Implementations must not retain p.

    ReaderFrom

    pub(open) trait ReaderFrom {
    fn read_from(Self, &Reader) -> (Int64, IOError?)
    }

    ReaderFrom is the interface that wraps the read_from method.

    read_from reads data from r until eof or error. The return value n is the number of bytes read. Any error except eof encountered during the read is also returned.

    The [copy] function uses [ReaderFrom] if available.

    Seeker

    pub(open) trait Seeker {
    fn seek(Self, Int64, Whence) -> (Int64, IOError?)
    }

    Seeker is the interface that wraps the basic Seek method.

    Seek sets the offset for the next Read or Write to offset, interpreted according to whence: [SeekStart] means relative to the start of the file, [SeekCurrent] means relative to the current offset, and [SeekEnd] means relative to the end (for example, offset = -2 specifies the penultimate byte of the file). Seek returns the new offset relative to the start of the file or an error, if any.

    Seeking to an offset before the start of the file is an error. Seeking to any positive offset may be allowed, but if the new offset exceeds the size of the underlying object the behavior of subsequent I/O operations is implementation-dependent.

    WriteCloser

    pub(open) trait WriteCloser : Writer + Closer {
    }

    WriteCloser is the interface that groups the basic Write and Close methods.

    WriteSeeker

    pub(open) trait WriteSeeker : Writer + Seeker {
    }

    WriteSeeker is the interface that groups the basic Write and Seek methods.

    Writer

    pub(open) trait Writer {
    fn write(Self, Slice[Byte]) -> (Int, IOError?)
    }

    Writer is the interface that wraps the basic Write method.

    Write writes len(p) bytes from p to the underlying data stream. It returns the number of bytes written from p (0 <= n <= len(p)) and any error encountered that caused the write to stop early. Write must return a non-None error if it returns n < len(p). Write must not modify the slice data, even temporarily.

    Implementations must not retain p.

    WriterAt

    pub(open) trait WriterAt {
    fn write_at(Self, Slice[Byte], Int64) -> (Int, IOError?)
    }

    WriterAt is the interface that wraps the basic write_at method.

    write_at writes len(p) bytes from p to the underlying data stream at offset off. It returns the number of bytes written from p (0 <= n <= len(p)) and any error encountered that caused the write to stop early. write_at must return a non-None error if it returns n < len(p).

    If write_at is writing to a destination with a seek offset, write_at should not affect nor be affected by the underlying seek offset.

    Clients of write_at can execute parallel write_at calls on the same destination if the ranges do not overlap.

    Implementations must not retain p.

    WriterTo

    pub(open) trait WriterTo {
    fn write_to(Self, &Writer) -> (Int64, IOError?)
    }

    WriterTo is the interface that wraps the write_to method.

    write_to writes data to w until there's no more data to write or when an error occurs. The return value n is the number of bytes written. Any error encountered during the write is also returned.

    The copy function uses WriterTo if available.

    IOError

    pub(all) suberror IOError {
    IOError(String)
    } derive(Eq,
    Debug
    )

    An IOError can be tested with equality checks.
    impl Show for IOError

    Buffer

    type Buffer

    impl Reader for Buffer
    impl Writer for Buffer
    impl Eq for Buffer
    impl Show for Buffer

    Buffer::from_bytes

    fn Buffer::from_bytes(b : Bytes) -> Buffer

    Buffer::from_slice

    fn Buffer::from_slice(s : Slice[Byte]) -> Buffer

    Buffer::from_string

    fn Buffer::from_string(s : String) -> Buffer

    Buffer::from_string converts the MoonBit UTF-16 String to UTF-8 and creates a Buffer from the bytes.

    Buffer::get

    #alias("_[_]")
    fn Buffer::get(self : Buffer, index : Int) -> Byte

    Buffer::length

    fn Buffer::length(self : Buffer) -> Int

    Buffer::new

    fn Buffer::new(size_hint? : Int) -> Buffer

    Buffer::new creates a new empty Buffer with an optional size hint. The size hint is used to preallocate memory for the buffer, which can improve performance when the size of the data to be written is known in advance.

    Buffer::read_from

    fn Buffer::read_from(self : Buffer, r : &Reader) -> (Int64, IOError?)

    Buffer::reset

    fn Buffer::reset(self : Buffer, size_hint? : Int) -> Unit

    Buffer::substring

    fn Buffer::substring(self : Buffer, start? : Int, end? : Int) -> String

    Buffer::to_bytes

    fn Buffer::to_bytes(self : Buffer) -> Bytes

    Buffer::to_slice

    fn Buffer::to_slice(self : Buffer) -> Slice[Byte]

    Buffer::write_byte

    fn Buffer::write_byte(self : Buffer, b : Byte) -> (Int, IOError?)

    Buffer::write_bytes

    fn Buffer::write_bytes(self : Buffer, buf : Bytes) -> (Int, IOError?)

    Buffer::write_string

    fn Buffer::write_string(self : Buffer, s : String) -> (Int, IOError?)

    write_string converts the MoonBit UTF-16 String to UTF-8 and writes the bytes to the buffer.

    Discard

    type Discard

    impl Reader for Discard
    impl Writer for Discard

    Discard::read_from

    fn Discard::read_from(_self : Discard, r : &Reader) -> (Int64, IOError?)

    LimitedReader

    type LimitedReader

    A LimitedReader reads from R but limits the amount of data returned to just N bytes. Each call to Read updates N to reflect the new amount remaining. Read returns eof when N <= 0 or when the underlying R returns eof.

    LimitedReader::new

    fn LimitedReader::new(r : &Reader, n : Int64) -> LimitedReader

    LimitedReader::new returns a Reader that reads from r but stops with eof after n bytes. The underlying implementation is a LimitedReader.

    NopCloser

    type NopCloser

    impl Closer for NopCloser
    impl Reader for NopCloser

    NopCloser::new

    fn NopCloser::new(r : &Reader) -> NopCloser

    NopCloser::new returns a [ReadCloser] with a no-op Close method wrapping the provided [Reader] r. If r implements [WriterTo], the returned [ReadCloser] will implement [WriterTo] by forwarding calls to r.

    OffsetWriter

    type OffsetWriter

    An OffsetWriter maps writes at offset base to offset base+off in the underlying writer.

    OffsetWriter::new

    fn OffsetWriter::new(w : &WriterAt, off : Int64) -> OffsetWriter

    OffsetWriter::new returns an [OffsetWriter] that writes to w starting at offset off.

    OffsetWriter::seek

    fn OffsetWriter::seek(self : OffsetWriter, offset : Int64, whence : Whence) -> (Int64, IOError?)

    OffsetWriter::write

    fn OffsetWriter::write(self : OffsetWriter, p : Slice[Byte]) -> (Int, IOError?)

    OffsetWriter::write_at

    fn OffsetWriter::write_at(self : OffsetWriter, p : Slice[Byte], off : Int64) -> (Int, IOError?)

    SectionReader

    type SectionReader

    SectionReader implements Read, Seek, and read_at on a section of an underlying [ReaderAt].

    SectionReader::new

    fn SectionReader::new(r : &ReaderAt, off : Int64, n : Int64) -> SectionReader

    SectionReader::new returns a [SectionReader] that reads from r starting at offset off and stops with eof after n bytes.

    SectionReader::outer

    fn SectionReader::outer(self : SectionReader) -> (&ReaderAt, Int64, Int64)

    Outer returns the underlying [ReaderAt] and offsets for the section.

    The returned values are the same that were passed to [SectionReader::new] when the [SectionReader] was created.

    SectionReader::read

    fn SectionReader::read(self : SectionReader, p : Slice[Byte]) -> (Int, IOError?)

    SectionReader::read_at

    fn SectionReader::read_at(self : SectionReader, p : Slice[Byte], off : Int64) -> (Int, IOError?)

    SectionReader::seek

    fn SectionReader::seek(self : SectionReader, offset : Int64, whence : Whence) -> (Int64, IOError?)

    Slice

    A Slice is a slice of an Array.

    A separate Slice type was needed because of this issue: https://github.com/moonbitlang/core/issues/1063

    This struct is based on MoonBit's "ArrayView" implementation here: https://github.com/moonbitlang/core/blob/main/builtin/arrayview.mbt which has the following copyright:

    Copyright 2024 International Digital Economy Academy

    Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
    impl Eq for Slice[T]
    impl Show for Slice[X]

    Slice::append

    fn[T] Slice::append(self : Slice[T], s : Slice[T]) -> Slice[T]

    append appends s to the end of the slice, reallocating the underlying array if necessary, then returns the new slice.

    Slice::as_array_view

    fn[T] Slice::as_array_view(self : Slice[T]) -> ArrayView[T]

    Slice::cap

    fn[T] Slice::cap(self : Slice[T]) -> Int

    cap returns the total capacity of the slice regardless of the current length.

    Slice::each

    fn[T] Slice::each(self : Slice[T], f : (T) -> Unit) -> Unit

    Slice::fold

    fn[A, B] Slice::fold(self : Slice[A], init~ : B, f : (B, A) -> B) -> B

    Fold out values from a Slice according to certain rules.

    Slice::foldi

    fn[A, B] Slice::foldi(self : Slice[A], init~ : B, f : (Int, B, A) -> B) -> B

    Fold out values from a Slice according to certain rules with index.

    Slice::get

    #alias("_[_]")
    fn[T] Slice::get(self : Slice[T], index : Int) -> T

    Slice::iter

    fn[A] Slice::iter(self : Slice[A]) -> Iter[A]

    Slice::iter2

    fn[A] Slice::iter2(self : Slice[A]) -> Iter2[Int, A]

    Slice::length

    fn[T] Slice::length(self : Slice[T]) -> Int

    length returns the length of the slice.

    Slice::new

    fn[T] Slice::new(buf : Array[T], start? : Int, end? : Int) -> Slice[T]

    Slice::push

    fn[T] Slice::push(self : Slice[T], e : T) -> Slice[T]

    push appends e to the end of the slice, reallocating the underlying array if necessary, then returns the new slice.

    Slice::rev_fold

    fn[A, B] Slice::rev_fold(self : Slice[A], init~ : B, f : (B, A) -> B) -> B

    Fold out values from a Slice according to certain rules in reversed turn.

    Slice::rev_foldi

    fn[A, B] Slice::rev_foldi(self : Slice[A], init~ : B, f : (Int, B, A) -> B) -> B

    Fold out values from a Slice according to certain rules in reversed turn with index.

    Slice::rev_inplace

    fn[T] Slice::rev_inplace(self : Slice[T]) -> Unit

    Slice::set

    #alias("_[_]=_")
    fn[T] Slice::set(self : Slice[T], index : Int, value : T) -> Unit

    Slice::sub

    #alias("_[_:_]")
    fn[T] Slice::sub(self : Slice[T], start? : Int, end? : Int) -> Slice[T]

    Slice::swap

    fn[T] Slice::swap(self : Slice[T], i : Int, j : Int) -> Unit

    Slice::to_bytes

    fn Slice::to_bytes(self : Slice[Byte]) -> Bytes

    to_bytes returns slice as Bytes.

    TeeReader

    type TeeReader

    impl Reader for TeeReader

    TeeReader::new

    fn TeeReader::new(r : &Reader, w : &Writer) -> TeeReader

    TeeReader::new returns a [Reader] that writes to w what it reads from r. All reads from r performed through it are matched with corresponding writes to w. There is no internal buffering - the write must complete before the read completes. Any error encountered while writing is reported as a read error.

    Whence

    pub(all) enum Whence {
    SeekStart
    SeekCurrent
    SeekEnd
    }

    Seek whence values.

    copy

    fn copy(dst : &Writer, src : &Reader) -> (Int64, IOError?)

    copy copies from src to dst until either eof is reached on src or an error occurs. It returns the number of bytes copied and the first error encountered while copying, if any.

    A successful copy returns err == None, not err == eof. Because copy is defined to read from src until eof, it does not treat an eof from Read as an error to be reported.

    If src implements [WriterTo], the copy is implemented by calling src.write_to(dst). Otherwise, if dst implements [ReaderFrom], the copy is implemented by calling dst.read_from(src).

    copy_buffer

    fn copy_buffer(dst : &Writer, src : &Reader, buf : Slice[Byte]?) -> (Int64, IOError?)

    copy_buffer is identical to copy except that it stages through the provided buffer (if one is required) rather than allocating a temporary one. If buf is None, one is allocated; otherwise if it has zero length, copy_buffer panics.

    If either src implements [WriterTo] or dst implements [ReaderFrom], buf will not be used to perform the copy.

    copy_json

    fn copy_json(src : &ByteReader) -> (Json, Int64, IOError?)

    copy_json copies bytes from a source reader until a valid JSON value is completed. It returns the Json value, the number of bytes copied, and any error that occurred during the process.

    copy_n

    fn copy_n(dst : &Writer, src : &Reader, n : Int64) -> (Int64, IOError?)

    copy_n copies n bytes (or until an error) from src to dst. It returns the number of bytes copied and the earliest error encountered while copying. On return, written == n if and only if err == None.

    If dst implements [ReaderFrom], the copy is implemented using it.

    copy_size

    fn copy_size(dst : &Writer, src : &ByteReader, size : Int64) -> (Int64, IOError?)

    copy_size copies a specified number of bytes from a source reader to a destination writer. It returns the number of bytes copied and any error that occurred during the process.

    copy_until

    fn copy_until(dst : &Writer, src : &ByteReader, until : Byte) -> (Int64, IOError?)

    copy_until copies bytes from a source reader to a destination writer until a specified byte is encountered. It returns the number of bytes copied and any error that occurred during the process.

    discard

    let discard : Discard

    discard is a [Writer] on which all Write calls succeed without doing anything.

    eof

    let eof : IOError

    eof is the error returned by Read when no more input is available. (Read must return eof itself, not an error wrapping eof, because callers will test for eof using ==.) Functions should return eof only to signal a graceful end of input. If the eof occurs unexpectedly in a structured data stream, the appropriate error is either [err_unexpected_eof] or some other error giving more detail.

    err_invalid_write

    let err_invalid_write : IOError

    err_invalid_write means that a write returned an impossible count.

    err_no_progress

    let err_no_progress : IOError

    err_no_progress is returned by some clients of a [Reader] when many calls to Read have failed to return any data or error, usually the sign of a broken [Reader] implementation.

    err_offset

    let err_offset : IOError

    err_short_buffer

    let err_short_buffer : IOError

    err_short_buffer means that a read required a longer buffer than was provided.

    err_short_write

    let err_short_write : IOError

    err_short_write means that a write accepted fewer bytes than requested but failed to return an explicit error.

    err_unexpected_eof

    let err_unexpected_eof : IOError

    err_unexpected_eof means that eof was encountered in the middle of reading a fixed-size block or data structure.

    err_whence

    let err_whence : IOError

    read_all

    fn read_all(r : &Reader) -> (Slice[Byte], IOError?)

    read_all reads from r until an error or eof and returns the data it read. A successful call returns err == None, not err == eof. Because read_all is defined to read from src until eof, it does not treat an eof from Read as an error to be reported.

    read_full

    fn read_full(r : &Reader, buf : Slice[Byte]) -> (Int, IOError?)

    read_full reads exactly len(buf) bytes from r into buf. It returns the number of bytes copied and an error if fewer bytes were read. The error is eof only if no bytes were read. If an eof happens after reading some but not all the bytes, read_full returns [err_unexpected_eof]. On return, n == len(buf) if and only if err == None. If r returns an error having read at least len(buf) bytes, the error is dropped.

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io