zig-0.16.0-67c9d57
I wrote code where an Io.Reader is chosen based on the code execution. This is a natural pattern.
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const allocator = arena.allocator();
defer arena.deinit();
const lib: []const Package = @import("library.zon");
const target = CmdLine.string("install") orelse {
std.debug.print("not downloading\n", .{});
return;
};
var reader: std.Io.Reader = undefined;
if (CmdLine.hasFlag("-f")) {
const file = try allocator.create(std.fs.File);
file.* = try std.fs.cwd().openFile(target, .{});
reader = std.fs.File.reader(file.*, try allocator.alloc(u8, 4096)).interface;
} else {
for (lib) |pkg| {
std.debug.print("{s}", .{pkg.name});
if (std.mem.eql(u8, pkg.name, target)) {
const response = try allocator.create(std.ArrayListUnmanaged(u8));
response.* = try get(allocator, pkg.sources.url);
reader = std.Io.Reader.fixed(response.items);
}
}
}
var decompressor = try std.compress.xz.Decompress.init(&reader,
allocator, try allocator.alloc(u8, 0));
var file_buf: [4096]u8 = undefined;
var file = try std.fs.cwd().createFile("secret.tar", .{.read = true});
var writer = std.fs.File.writer(file, &file_buf).interface;
_ = try decompressor.reader.stream(&writer, .unlimited);
defer file.close();
}
The code compiles, given appropriate argument parsing. However, when I take the branch where the target is a file, the file reader fails to serve requests from the decompressor.
/usr/local/Paquets/zig-0.16.0-67c9d57/build/stage3/lib/zig/std/fs/File.zig:1294:25: 0x1021d6213 in readVec (gpq)
.failure => return error.ReadFailed,
^
/usr/local/Paquets/zig-0.16.0-67c9d57/build/stage3/lib/zig/std/Io/Reader.zig:1099:36: 0x102190343 in fillUnbuffered (gpq)
while (r.end < r.seek + n) _ = try r.vtable.readVec(r, &bufs);
^
/usr/local/Paquets/zig-0.16.0-67c9d57/build/stage3/lib/zig/std/Io/Reader.zig:1085:5: 0x10216f957 in fill (gpq)
return fillUnbuffered(r, n);
^
/usr/local/Paquets/zig-0.16.0-67c9d57/build/stage3/lib/zig/std/Io/Reader.zig:486:5: 0x1021639cf in peek (gpq)
try r.fill(n);
^
/usr/local/Paquets/zig-0.16.0-67c9d57/build/stage3/lib/zig/std/Io/Reader.zig:534:20: 0x102142287 in take (gpq)
const result = try r.peek(n);
^
/usr/local/Paquets/zig-0.16.0-67c9d57/build/stage3/lib/zig/std/Io/Reader.zig:551:13: 0x1021be833 in takeArray__anon_20609 (gpq)
return (try r.take(n))[0..n];
^
/usr/local/Paquets/zig-0.16.0-67c9d57/build/stage3/lib/zig/std/compress/xz/Decompress.zig:63:19: 0x1021be2df in init (gpq)
const magic = try input.takeArray(6);
^
/Users/giorno/projects/gpq/src/main.zig:92:24: 0x1021bf20b in main (gpq)
var decompressor = try std.compress.xz.Decompress.init(&reader,
^
But if I change the inner section to
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const allocator = arena.allocator();
defer arena.deinit();
const lib: []const Package = @import("library.zon");
const target = CmdLine.string("install") orelse {
std.debug.print("not downloading\n", .{});
return;
};
var file_reader: std.fs.File.Reader = undefined;
var reader: std.Io.Reader = undefined;
if (CmdLine.hasFlag("-f")) {
const file = try allocator.create(std.fs.File);
file.* = try std.fs.cwd().openFile(target, .{});
file_reader = std.fs.File.reader(file.*, try allocator.alloc(u8, 4096));
} else {
for (lib) |pkg| {
std.debug.print("{s}", .{pkg.name});
if (std.mem.eql(u8, pkg.name, target)) {
const response = try allocator.create(std.ArrayListUnmanaged(u8));
response.* = try get(allocator, pkg.sources.url);
reader = std.Io.Reader.fixed(response.items);
}
}
}
var decompressor = try std.compress.xz.Decompress.init(&file_reader.interface,
allocator, try allocator.alloc(u8, 0));
var file_buf: [4096]u8 = undefined;
var file = try std.fs.cwd().createFile("secret.tar", .{.read = true});
var writer = std.fs.File.writer(file, &file_buf).interface;
_ = try decompressor.reader.stream(&writer, .unlimited);
defer file.close();
}
the error is resolved. I found it was located in std/fs/File.zig:readVec, caused by the compiler's requirement for a traceable source (a file reader in this case) to perform a comptime upcast of the Io.Reader. I consider this an inconvenient constraint that isn't evident in the high-level user code. While I'm aware this is being addressed, I wanted to document this specific pattern, which I believe should be allowed.
zig-0.16.0-67c9d57I wrote code where an Io.Reader is chosen based on the code execution. This is a natural pattern.
The code compiles, given appropriate argument parsing. However, when I take the branch where the target is a file, the file reader fails to serve requests from the decompressor.
But if I change the inner section to
the error is resolved. I found it was located in
std/fs/File.zig:readVec, caused by the compiler's requirement for a traceable source (a file reader in this case) to perform a comptime upcast of theIo.Reader. I consider this an inconvenient constraint that isn't evident in the high-level user code. While I'm aware this is being addressed, I wanted to document this specific pattern, which I believe should be allowed.