c :: import "@ffi/c" ReadError :: enum { read_failed } WriteError :: enum { write_failed no_progress } Io :: struct { context ?*mut anyopaque vtable @IoVTable } IoVTable :: struct { read @func(context ?*mut anyopaque, stream ReadStream, buffer []mut u8) usize ! ReadError write @func(context ?*mut anyopaque, stream WriteStream, bytes []u8) usize ! WriteError } ReadStream :: enum(c_int) { stdin = 0 } WriteStream :: enum(c_int) { stdout = 1 stderr = 2 } Reader :: struct { impl Io stream ReadStream } Writer :: struct { impl Io stream WriteStream } read func(reader Reader, buffer []mut u8) usize ! ReadError { if buffer.len == 0 { return 0 } count usize :: try reader.impl.vtable.read(reader.impl.context, reader.stream, buffer) if count > buffer.len { return .read_failed } return count } write func(writer Writer, bytes []u8) usize ! WriteError { if bytes.len == 0 { return 0 } count usize :: try writer.impl.vtable.write(writer.impl.context, writer.stream, bytes) if count > bytes.len { return .write_failed } return count } write_all func(writer Writer, bytes []u8) void ! WriteError { offset usize = 0 while offset < bytes.len { count usize :: write(writer, bytes[offset..]) catch |err| { return err } if count == 0 { return .no_progress } offset += count } return } hide system_read func(_ ?*mut anyopaque, stream ReadStream, buffer []mut u8) usize ! ReadError { request usize = buffer.len maximum usize :: usize(maxval!(c_long)) if request > maximum { request = maximum } while true { count c_long :: c.read(c_int(stream), buffer.ptr, c_ulong(request)) if count >= 0 { return usize(count) } if c.__error()^ != 4 { return .read_failed } } } hide system_write func(_ ?*mut anyopaque, stream WriteStream, bytes []u8) usize ! WriteError { fd c_int :: c_int(stream) request usize = bytes.len maximum usize :: usize(maxval!(c_long)) if request > maximum { request = maximum } while true { count c_long :: c.write(fd, bytes.ptr, c_ulong(request)) if count >= 0 { return usize(count) } if c.__error()^ != 4 { return .write_failed } } } hide system_vtable IoVTable :: IoVTable { read = system_read, write = system_write, } hide system func() Io { return Io { context = none, vtable = &system_vtable, } }