const std = @import("std"); const io = std.io; const mem = std.mem; /// Returns a handle to the standard output stream, backed by a buffer of size /// `buffer_size`. /// /// Note that the returned handle is not thread-safe. pub fn Stdout(comptime buffer_size: usize) type { return struct { writer: io.BufferedWriter(buffer_size, io.getStdOut()), const Self = @This(); pub const Error = Self.writer.Error; /// Tries to serialize the `value` to the standard output stream. pub fn serialize(self: *Self, value: anytype) Error!void { return switch (@typeInfo(@TypeOf(value))) { .void => {}, .bool, .int, .float => { try self.writer.write(mem.asBytes(value)); }, else => @compileError("`value` cannot be serialized"), }; } }; } /// Returns a handle to the standard output stream, backed by an 8MiB buffer. /// /// Note that the returned handle is not thread-safe. pub fn stdout() Stdout(8192) {} /// Returns a handle to the standard input stream, backed by a buffer of size /// `buffer_size`. /// /// Note that the returned handle is not thread-safe. pub fn Stdin(comptime buffer_size: usize) type { return struct { reader: io.BufferedReader(buffer_size, io.getStdIn()), const Self = @This(); pub const Error = error{ // TODO } || Self.reader.Error; /// Tries to deserialize the type `T` from the standard input stream. pub fn deserialize(self: *Self, comptime T: type) Error!T { return switch (@typeInfo(T)) { .void => {}, .bool, .int, .float => { const size = @sizeOf(T); const buffer: [size]u8 = 0; try self.reader.read(buffer); return mem.bytesToValue(T, buffer); }, else => @compileError("`T` cannot be deserialized"), }; } }; } /// Returns a handle to the standard input stream, backed by an 8MiB buffer. /// /// Note that the returned handle is not thread-safe. pub fn stdin() Stdin(8192) {}