diff --git a/lib/std/Io/Reader.zig b/lib/std/Io/Reader.zig index 8a177ea183..58ed0899a4 100644 --- a/lib/std/Io/Reader.zig +++ b/lib/std/Io/Reader.zig @@ -1702,33 +1702,13 @@ fn failingDiscard(r: *Reader, limit: Limit) Error!usize { } test "readAlloc when the backing reader provides one byte at a time" { - const OneByteReader = struct { - str: []const u8, - i: usize, - reader: Reader, - - fn stream(r: *Reader, w: *Writer, limit: Limit) StreamError!usize { - assert(@intFromEnum(limit) >= 1); - const self: *@This() = @fieldParentPtr("reader", r); - if (self.str.len - self.i == 0) return error.EndOfStream; - try w.writeByte(self.str[self.i]); - self.i += 1; - return 1; - } - }; const str = "This is a test"; var tiny_buffer: [1]u8 = undefined; - var one_byte_stream: OneByteReader = .{ - .str = str, - .i = 0, - .reader = .{ - .buffer = &tiny_buffer, - .vtable = &.{ .stream = OneByteReader.stream }, - .seek = 0, - .end = 0, - }, - }; - const res = try one_byte_stream.reader.allocRemaining(std.testing.allocator, .unlimited); + var one_byte_stream: testing.Reader = .init(&tiny_buffer, &.{ + .{ .buffer = str }, + }); + one_byte_stream.artificial_limit = .limited(1); + const res = try one_byte_stream.interface.allocRemaining(std.testing.allocator, .unlimited); defer std.testing.allocator.free(res); try std.testing.expectEqualStrings(str, res); } diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 8e7ffd3f23..f9027a4f47 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -1207,12 +1207,14 @@ pub inline fn fuzz( return @import("root").fuzz(context, testOne, options); } -/// A `std.io.Reader` that writes a predetermined list of buffers during `stream`. +/// A `std.Io.Reader` that writes a predetermined list of buffers during `stream`. pub const Reader = struct { calls: []const Call, - interface: std.io.Reader, + interface: std.Io.Reader, next_call_index: usize, next_offset: usize, + /// Further reduces how many bytes are written in each `stream` call. + artificial_limit: std.Io.Limit = .unlimited, pub const Call = struct { buffer: []const u8, @@ -1232,11 +1234,11 @@ pub const Reader = struct { }; } - fn stream(io_r: *std.io.Reader, w: *std.io.Writer, limit: std.io.Limit) std.io.Reader.StreamError!usize { + fn stream(io_r: *std.Io.Reader, w: *std.Io.Writer, limit: std.Io.Limit) std.Io.Reader.StreamError!usize { const r: *Reader = @alignCast(@fieldParentPtr("interface", io_r)); if (r.calls.len - r.next_call_index == 0) return error.EndOfStream; const call = r.calls[r.next_call_index]; - const buffer = limit.sliceConst(call.buffer[r.next_offset..]); + const buffer = r.artificial_limit.sliceConst(limit.sliceConst(call.buffer[r.next_offset..])); const n = try w.write(buffer); r.next_offset += n; if (call.buffer.len - r.next_offset == 0) {