authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-16 13:43:50+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-05-16 13:43:50+03:00
log092f726eeca1b73d29efb7074bc3302f974aba7d
treeea9001c6fd6df2ca7f1de948398936198b82bf62
parente2a0f5741df8b00290c0900122c4aca6ccdf6a2d
parent277d088558490ae822826d3713cf961624d56465
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #5175 from daurnimator/multi-out-stream

std: add io.MultiOutStream

2 files changed, 54 insertions(+), 0 deletions(-)

lib/std/io.zig+3
...@@ -123,6 +123,9 @@ pub const cOutStream = @import("io/c_out_stream.zig").cOutStream;...@@ -123,6 +123,9 @@ pub const cOutStream = @import("io/c_out_stream.zig").cOutStream;
123pub const CountingOutStream = @import("io/counting_out_stream.zig").CountingOutStream;123pub const CountingOutStream = @import("io/counting_out_stream.zig").CountingOutStream;
124pub const countingOutStream = @import("io/counting_out_stream.zig").countingOutStream;124pub const countingOutStream = @import("io/counting_out_stream.zig").countingOutStream;
125125
126pub const MultiOutStream = @import("io/multi_out_stream.zig").MultiOutStream;
127pub const multiOutStream = @import("io/multi_out_stream.zig").multiOutStream;
128
126pub const BitInStream = @import("io/bit_in_stream.zig").BitInStream;129pub const BitInStream = @import("io/bit_in_stream.zig").BitInStream;
127pub const bitInStream = @import("io/bit_in_stream.zig").bitInStream;130pub const bitInStream = @import("io/bit_in_stream.zig").bitInStream;
128131
lib/std/io/multi_out_stream.zig created+51
...@@ -0,0 +1,51 @@
1const std = @import("../std.zig");
2const io = std.io;
3const testing = std.testing;
4
5/// Takes a tuple of streams, and constructs a new stream that writes to all of them
6pub fn MultiOutStream(comptime OutStreams: type) type {
7 comptime var ErrSet = error{};
8 inline for (@typeInfo(OutStreams).Struct.fields) |field| {
9 const StreamType = field.field_type;
10 ErrSet = ErrSet || StreamType.Error;
11 }
12
13 return struct {
14 const Self = @This();
15
16 streams: OutStreams,
17
18 pub const Error = ErrSet;
19 pub const OutStream = io.OutStream(*Self, Error, write);
20 pub fn outStream(self: *Self) OutStream {
21 return .{ .context = self };
22 }
23
24 pub fn write(self: *Self, bytes: []const u8) Error!usize {
25 var batch = std.event.Batch(Error!void, self.streams.len, .auto_async).init();
26 comptime var i = 0;
27 inline while (i < self.streams.len) : (i += 1) {
28 const stream = self.streams[i];
29 // TODO: remove ptrCast: https://github.com/ziglang/zig/issues/5258
30 batch.add(@ptrCast(anyframe->Error!void, &async stream.writeAll(bytes)));
31 }
32 try batch.wait();
33 return bytes.len;
34 }
35 };
36}
37
38pub fn multiOutStream(streams: var) MultiOutStream(@TypeOf(streams)) {
39 return .{ .streams = streams };
40}
41
42test "MultiOutStream" {
43 var buf1: [255]u8 = undefined;
44 var fbs1 = io.fixedBufferStream(&buf1);
45 var buf2: [255]u8 = undefined;
46 var fbs2 = io.fixedBufferStream(&buf2);
47 var stream = multiOutStream(.{fbs1.outStream(), fbs2.outStream()});
48 try stream.outStream().print("HI", .{});
49 testing.expectEqualSlices(u8, "HI", fbs1.getWritten());
50 testing.expectEqualSlices(u8, "HI", fbs2.getWritten());
51}