| ... | ... | @@ -1,53 +0,0 @@ |
| 1 | | const std = @import("../std.zig"); |
| 2 | | const io = std.io; |
| 3 | | |
| 4 | | /// Takes a tuple of streams, and constructs a new stream that writes to all of them |
| 5 | | pub fn MultiWriter(comptime Writers: type) type { |
| 6 | | comptime var ErrSet = error{}; |
| 7 | | inline for (@typeInfo(Writers).@"struct".fields) |field| { |
| 8 | | const StreamType = field.type; |
| 9 | | ErrSet = ErrSet || StreamType.Error; |
| 10 | | } |
| 11 | | |
| 12 | | return struct { |
| 13 | | const Self = @This(); |
| 14 | | |
| 15 | | streams: Writers, |
| 16 | | |
| 17 | | pub const Error = ErrSet; |
| 18 | | pub const Writer = io.GenericWriter(*Self, Error, write); |
| 19 | | |
| 20 | | pub fn writer(self: *Self) Writer { |
| 21 | | return .{ .context = self }; |
| 22 | | } |
| 23 | | |
| 24 | | pub fn write(self: *Self, bytes: []const u8) Error!usize { |
| 25 | | inline for (self.streams) |stream| |
| 26 | | try stream.writeAll(bytes); |
| 27 | | return bytes.len; |
| 28 | | } |
| 29 | | }; |
| 30 | | } |
| 31 | | |
| 32 | | pub fn multiWriter(streams: anytype) MultiWriter(@TypeOf(streams)) { |
| 33 | | return .{ .streams = streams }; |
| 34 | | } |
| 35 | | |
| 36 | | const testing = std.testing; |
| 37 | | |
| 38 | | test "MultiWriter" { |
| 39 | | var tmp = testing.tmpDir(.{}); |
| 40 | | defer tmp.cleanup(); |
| 41 | | var f = try tmp.dir.createFile("t.txt", .{}); |
| 42 | | |
| 43 | | var buf1: [255]u8 = undefined; |
| 44 | | var fbs1 = io.fixedBufferStream(&buf1); |
| 45 | | var buf2: [255]u8 = undefined; |
| 46 | | var stream = multiWriter(.{ fbs1.writer(), f.writer() }); |
| 47 | | |
| 48 | | try stream.writer().print("HI", .{}); |
| 49 | | f.close(); |
| 50 | | |
| 51 | | try testing.expectEqualSlices(u8, "HI", fbs1.getWritten()); |
| 52 | | try testing.expectEqualSlices(u8, "HI", try tmp.dir.readFile("t.txt", &buf2)); |
| 53 | | } |