| ... | @@ -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 | } |