Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

IoStream

main.IoStream
const IoStream = struct

File

Code

const IoStream = struct {
    name: []const u8,
    intermediate: bool,
    source: Source,

    pub const IoDirection = enum { input, output };

    pub fn fromIoSource(io: Io, source: cli.Options.IoSource, io_direction: IoDirection) !IoStream {
        return .{
            .name = switch (source) {
                .filename => |filename| filename,
                .stdio => switch (io_direction) {
                    .input => "<stdin>",
                    .output => "<stdout>",
                },
            },
            .intermediate = false,
            .source = try Source.fromIoSource(io, source, io_direction),
        };
    }

    pub fn deinit(self: *IoStream, allocator: Allocator, io: Io) void {
        self.source.deinit(allocator, io);
    }

    pub fn cleanupAfterError(self: *IoStream, io: Io) void {
        switch (self.source) {
            .file => |file| {
                // Delete the output file on error
                file.close(io);
                // Failing to delete is not really a big deal, so swallow any errors
                Io.Dir.cwd().deleteFile(io, self.name) catch {};
            },
            .stdio, .memory, .closed => return,
        }
    }

    pub const Source = union(enum) {
        file: Io.File,
        stdio: Io.File,
        memory: std.ArrayList(u8),
        /// The source has been closed and any usage of the Source in this state is illegal (except deinit).
        closed: void,

        pub fn fromIoSource(io: Io, source: cli.Options.IoSource, io_direction: IoDirection) !Source {
            switch (source) {
                .filename => |filename| return .{
                    .file = switch (io_direction) {
                        .input => try Io.Dir.cwd().openFile(io, filename, .{ .allow_directory = false }),
                        .output => try Io.Dir.cwd().createFile(io, filename, .{}),
                    },
                },
                .stdio => |file| return .{ .stdio = file },
            }
        }

        pub fn deinit(self: *Source, allocator: Allocator, io: Io) void {
            switch (self.*) {
                .file => |file| file.close(io),
                .stdio => {},
                .memory => |*list| list.deinit(allocator),
                .closed => {},
            }
        }

        pub const Data = struct {
            bytes: []const u8,
            needs_free: bool,

            pub fn deinit(self: Data, allocator: Allocator) void {
                if (self.needs_free) {
                    allocator.free(self.bytes);
                }
            }
        };

        pub fn readAll(self: Source, allocator: Allocator, io: Io) !Data {
            return switch (self) {
                inline .file, .stdio => |file| .{
                    .bytes = b: {
                        var file_reader = file.reader(io, &.{});
                        break :b try file_reader.interface.allocRemaining(allocator, .unlimited);
                    },
                    .needs_free = true,
                },
                .memory => |list| .{ .bytes = list.items, .needs_free = false },
                .closed => unreachable,
            };
        }

        pub const Writer = union(enum) {
            file: Io.File.Writer,
            allocating: std.Io.Writer.Allocating,

            pub const Error = Allocator.Error || Io.File.WriteError;

            pub fn interface(this: *@This()) *std.Io.Writer {
                return switch (this.*) {
                    .file => |*fw| &fw.interface,
                    .allocating => |*a| &a.writer,
                };
            }

            pub fn deinit(this: *@This(), source: *Source) void {
                switch (this.*) {
                    .file => {},
                    .allocating => |*a| source.memory = a.toArrayList(),
                }
                this.* = undefined;
            }
        };

        pub fn writer(source: *Source, allocator: Allocator, io: Io, buffer: []u8) Writer {
            return switch (source.*) {
                .file, .stdio => |file| .{ .file = file.writer(io, buffer) },
                .memory => |*list| .{ .allocating = .fromArrayList(allocator, list) },
                .closed => unreachable,
            };
        }
    };
}