How to accept allvariations of the same generic

79 Views Asked by At

I am learning zig by writing a multi threaded HTTP proxy. As part of this I wrote a function to read from one stream and write it to the other:

const std = @import("std");
const http = std.http;

const Source = enum {
    client,
    server,
};

const Reader = union(Source) {
    client: *http.Client.Request.Reader,
    server: *http.Server.Response.Reader,
};

const Writer = union(Source) {
    client: *http.Client.Request.Writer,
    server: *http.Server.Response.Writer,
};

pub fn copy(reader: Reader, writer: Writer, comptime buffer_size: usize) !void {
    var buffer: [buffer_size]u8 = undefined;

    while (true) {
        var nread = switch (reader) {
            .client => try reader.client.*.read(&buffer),
            .server => try reader.server.*.read(&buffer),
        };

        if (nread == 0) {
            break;
        }

        _ = try switch (writer) {
            .client => writer.client.write(buffer[0..nread]),
            .server => writer.server.write(buffer[0..nread]),
        };
    }
}

This seems a bit obtuse and is quite clunky to use and extend but what I tried initially doesn't work:

const std = @import("std");
const io = std.io;


pub fn copy(reader: *io.Reader, writer: *io.Writer, comptime buffer_size: usize) !void {
    var buffer: [buffer_size]u8 = undefined;

    while (true) {
        var nread = try reader.*.read(&buffer),

        if (nread == 0) {
            break;
        }

        _ = writer.client.write(buffer[0..nread]),
    }
}

The compiler complains that io.Reader is a function, not a type. I believe if I called io.Reader and io.Writer with some parameters it would not throw this error, but then the function would only accept the specific variation of the generic rather than the generic itself. I could perhaps require that the generic parameters are passed into the copy function but there are a total of 6 parameters that would need to be specified.

There has to be a better way, right?

0

There are 0 best solutions below