Skip to content

Commit e9d24f5

Browse files
mitchellhnikneym
authored andcommitted
remove usingnamespace from main.zig
This should be 100% API compatible, and I wrote a comptime test to help ensure that. Still, I suppose something could slip through. The major churn in this PR is to avoid a circular dependency when verifying that the API didn't change. We remove the dependency on main.zig from the backends, which is cleaner in general, but it makes for a big diff.
1 parent e49b44e commit e9d24f5

File tree

9 files changed

+642
-551
lines changed

9 files changed

+642
-551
lines changed

docs/xev-zig.7.scd

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ over the C API. For example, all callbacks in the Zig API must be available
1717
at comptime because the callback call is always inlined -- this results in
1818
a noticable performance improvement over equivalent C consumption of libxev.
1919

20-
The primary Zig API is visible in `src/main.zig` in the libxev source. The main file uses a somewhat convoluted `usingnamespace` to setup the
21-
API so it isn't immediately obvious, but the API is provided by the `Xev`
22-
function. For example, available consts are: `xev.Loop`, `xev.Completion`,
23-
etc.
20+
The primary Zig API is visible in `src/main.zig` in the libxev source.
2421

2522
# INSTALLATION
2623

src/api.zig

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
const builtin = @import("builtin");
2+
const stream = @import("watcher/stream.zig");
3+
const Backend = @import("backend.zig").Backend;
4+
5+
/// Creates the Xev API based on a backend type.
6+
///
7+
/// For the default backend type for your system (i.e. io_uring on Linux),
8+
/// this is the main API you interact with. It is forwarded into the main
9+
/// the "xev" package so you'd use types such as `xev.Loop`, `xev.Completion`,
10+
/// etc.
11+
///
12+
/// Unless you're using a custom or specific backend type, you do NOT ever
13+
/// need to call the Xev function itself.
14+
pub fn Xev(comptime be: Backend, comptime T: type) type {
15+
return struct {
16+
const Self = @This();
17+
const loop = @import("loop.zig");
18+
19+
/// This is used to detect a static vs dynamic API at comptime.
20+
pub const dynamic = false;
21+
22+
/// The backend that this is. This is supplied at comptime so
23+
/// it is up to the caller to say the right thing. This lets custom
24+
/// implementations also "quack" like an implementation.
25+
pub const backend = be;
26+
27+
/// A function to test if this API is available on the
28+
/// current system.
29+
pub const available = T.available;
30+
31+
/// The core loop APIs.
32+
pub const Loop = T.Loop;
33+
pub const Completion = T.Completion;
34+
pub const Result = T.Result;
35+
pub const ReadBuffer = T.ReadBuffer;
36+
pub const WriteBuffer = T.WriteBuffer;
37+
pub const Options = loop.Options;
38+
pub const RunMode = loop.RunMode;
39+
pub const CallbackAction = loop.CallbackAction;
40+
pub const CompletionState = loop.CompletionState;
41+
42+
/// Error types
43+
pub const AcceptError = T.AcceptError;
44+
pub const CancelError = T.CancelError;
45+
pub const CloseError = T.CloseError;
46+
pub const ConnectError = T.ConnectError;
47+
pub const ShutdownError = T.ShutdownError;
48+
pub const WriteError = T.WriteError;
49+
pub const ReadError = T.ReadError;
50+
51+
/// Shared stream types
52+
const SharedStream = stream.Shared(Self);
53+
pub const PollError = SharedStream.PollError;
54+
pub const PollEvent = SharedStream.PollEvent;
55+
pub const WriteQueue = SharedStream.WriteQueue;
56+
pub const WriteRequest = SharedStream.WriteRequest;
57+
58+
/// The high-level helper interfaces that make it easier to perform
59+
/// common tasks. These may not work with all possible Loop implementations.
60+
pub const Async = @import("watcher/async.zig").Async(Self);
61+
pub const File = @import("watcher/file.zig").File(Self);
62+
pub const Process = @import("watcher/process.zig").Process(Self);
63+
pub const Stream = stream.GenericStream(Self);
64+
pub const Timer = @import("watcher/timer.zig").Timer(Self);
65+
pub const TCP = @import("watcher/tcp.zig").TCP(Self);
66+
pub const UDP = @import("watcher/udp.zig").UDP(Self);
67+
68+
/// The callback of the main Loop operations. Higher level interfaces may
69+
/// use a different callback mechanism.
70+
pub const Callback = loop.Callback(T);
71+
72+
/// A callback that does nothing and immediately disarms. This
73+
/// implements xev.Callback and is the default value for completions.
74+
pub const noopCallback = loop.NoopCallback(T);
75+
76+
/// A way to access the raw type.
77+
pub const Sys = T;
78+
79+
test {
80+
@import("std").testing.refAllDecls(@This());
81+
}
82+
83+
test "completion is zero-able" {
84+
const c: Self.Completion = .{};
85+
_ = c;
86+
}
87+
};
88+
}

src/backend.zig

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const builtin = @import("builtin");
2+
const stream = @import("watcher/stream.zig");
3+
4+
/// The backend types.
5+
pub const Backend = enum {
6+
io_uring,
7+
epoll,
8+
kqueue,
9+
wasi_poll,
10+
iocp,
11+
12+
/// Returns a recommend default backend from inspecting the system.
13+
pub fn default() Backend {
14+
return switch (builtin.os.tag) {
15+
.linux => .io_uring,
16+
.ios, .macos => .kqueue,
17+
.freebsd => .kqueue,
18+
.wasi => .wasi_poll,
19+
.windows => .iocp,
20+
else => {
21+
@compileLog(builtin.os);
22+
@compileError("no default backend for this target");
23+
},
24+
};
25+
}
26+
27+
/// Candidate backends for this platform in priority order.
28+
pub fn candidates() []const Backend {
29+
return switch (builtin.os.tag) {
30+
.linux => &.{ .io_uring, .epoll },
31+
.ios, .macos => &.{.kqueue},
32+
.freebsd => &.{.kqueue},
33+
.wasi => &.{.wasi_poll},
34+
.windows => &.{.iocp},
35+
else => {
36+
@compileLog(builtin.os);
37+
@compileError("no candidate backends for this target");
38+
},
39+
};
40+
}
41+
42+
/// Returns the Api (return value of Xev) for the given backend type.
43+
pub fn Api(comptime self: Backend) type {
44+
return switch (self) {
45+
.io_uring => @import("main.zig").IO_Uring,
46+
.epoll => @import("main.zig").Epoll,
47+
.kqueue => @import("main.zig").Kqueue,
48+
.wasi_poll => @import("main.zig").WasiPoll,
49+
.iocp => @import("main.zig").IOCP,
50+
};
51+
}
52+
};

0 commit comments

Comments
 (0)