zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit a1a1f94a0dbd4e4975577357987c786cacc9e6a2 (tree)
parent 0de35af98b3404f0cf7cd9497f661239d197bbbf
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Tue, 23 Jun 2020 22:23:20 -0400

Merge pull request #5681 from kubkon/refactor-wasi-preopens

[libstd]: refactor std.fs.wasi.PreopenList.find()
Diffstat:
Mdoc/langref.html.in | 2+-
Mlib/std/fs/wasi.zig | 76+++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mlib/std/testing.zig | 2+-
3 files changed, 43 insertions(+), 37 deletions(-)

diff --git a/doc/langref.html.in b/doc/langref.html.in @@ -9738,7 +9738,7 @@ pub fn main() !void { } {#code_end#} <pre><code>$ wasmtime --dir=. preopens.wasm -0: { .fd = 3, .Dir = '.' } +0: Preopen{ .fd = 3, .type = PreopenType{ .Dir = '.' } } </code></pre> {#header_close#} {#header_close#} diff --git a/lib/std/fs/wasi.zig b/lib/std/fs/wasi.zig @@ -5,13 +5,39 @@ const Allocator = mem.Allocator; usingnamespace std.os.wasi; -/// Type of WASI preopen. +/// Type-tag of WASI preopen. /// /// WASI currently offers only `Dir` as a valid preopen resource. -pub const PreopenType = enum { +pub const PreopenTypeTag = enum { Dir, }; +/// Type of WASI preopen. +/// +/// WASI currently offers only `Dir` as a valid preopen resource. +pub const PreopenType = union(PreopenTypeTag) { + /// Preopened directory type. + Dir: []const u8, + + const Self = @This(); + + pub fn eql(self: Self, other: PreopenType) bool { + if (!mem.eql(u8, @tagName(self), @tagName(other))) return false; + + switch (self) { + PreopenTypeTag.Dir => |this_path| return mem.eql(u8, this_path, other.Dir), + } + } + + pub fn format(self: Self, comptime fmt: []const u8, options: std.fmt.FormatOptions, out_stream: var) !void { + try out_stream.print("PreopenType{{ ", .{}); + switch (self) { + PreopenType.Dir => |path| try out_stream.print(".Dir = '{}'", .{path}), + } + return out_stream.print(" }}", .{}); + } +}; + /// WASI preopen struct. This struct consists of a WASI file descriptor /// and type of WASI preopen. It can be obtained directly from the WASI /// runtime using `PreopenList.populate()` method. @@ -20,29 +46,15 @@ pub const Preopen = struct { fd: fd_t, /// Type of the preopen. - @"type": union(PreopenType) { - /// Path to a preopened directory. - Dir: []const u8, - }, + @"type": PreopenType, - const Self = @This(); - - /// Construct new `Preopen` instance of type `PreopenType.Dir` from - /// WASI file descriptor and WASI path. - pub fn newDir(fd: fd_t, path: []const u8) Self { - return Self{ + /// Construct new `Preopen` instance. + pub fn new(fd: fd_t, preopen_type: PreopenType) Preopen { + return Preopen{ .fd = fd, - .@"type" = .{ .Dir = path }, + .@"type" = preopen_type, }; } - - pub fn format(self: Self, comptime fmt: []const u8, options: std.fmt.FormatOptions, out_stream: var) !void { - try out_stream.print("{{ .fd = {}, ", .{self.fd}); - switch (self.@"type") { - PreopenType.Dir => |path| try out_stream.print(".Dir = '{}'", .{path}), - } - return out_stream.print(" }}", .{}); - } }; /// Dynamically-sized array list of WASI preopens. This struct is a @@ -113,24 +125,18 @@ pub const PreopenList = struct { ESUCCESS => {}, else => |err| return os.unexpectedErrno(err), } - const preopen = Preopen.newDir(fd, path_buf); + const preopen = Preopen.new(fd, PreopenType{ .Dir = path_buf }); try self.buffer.append(preopen); fd += 1; } } - /// Find preopen by path. If the preopen exists, return it. + /// Find preopen by type. If the preopen exists, return it. /// Otherwise, return `null`. - /// - /// TODO make the function more generic by searching by `PreopenType` union. This will - /// be needed in the future when WASI extends its capabilities to resources - /// other than preopened directories. - pub fn find(self: Self, path: []const u8) ?*const Preopen { - for (self.buffer.items) |preopen| { - switch (preopen.@"type") { - PreopenType.Dir => |preopen_path| { - if (mem.eql(u8, path, preopen_path)) return &preopen; - }, + pub fn find(self: Self, preopen_type: PreopenType) ?*const Preopen { + for (self.buffer.items) |*preopen| { + if (preopen.@"type".eql(preopen_type)) { + return preopen; } } return null; @@ -156,7 +162,7 @@ test "extracting WASI preopens" { try preopens.populate(); std.testing.expectEqual(@as(usize, 1), preopens.asSlice().len); - const preopen = preopens.find(".") orelse unreachable; - std.testing.expect(std.mem.eql(u8, ".", preopen.@"type".Dir)); + const preopen = preopens.find(PreopenType{ .Dir = "." }) orelse unreachable; + std.testing.expect(preopen.@"type".eql(PreopenType{ .Dir = "." })); std.testing.expectEqual(@as(usize, 3), preopen.fd); } diff --git a/lib/std/testing.zig b/lib/std/testing.zig @@ -215,7 +215,7 @@ fn getCwdOrWasiPreopen() std.fs.Dir { defer preopens.deinit(); preopens.populate() catch @panic("unable to make tmp dir for testing: unable to populate preopens"); - const preopen = preopens.find(".") orelse + const preopen = preopens.find(std.fs.wasi.PreopenType{ .Dir = "." }) orelse @panic("unable to make tmp dir for testing: didn't find '.' in the preopens"); return std.fs.Dir{ .fd = preopen.fd };