|
1 | | -//! Compatibility layer for Zig 0.15 and 0.16 |
| 1 | +//! Compatibility layer for Zig 0.14 / 0.15 / 0.16. |
| 2 | +//! |
| 3 | +//! Several stdlib APIs the examples rely on were renamed or removed in |
| 4 | +//! Zig 0.16 (Writergate, `std.fs` -> `std.Io.Dir`, `GeneralPurposeAllocator` |
| 5 | +//! -> `DebugAllocator`, etc). This module hides the version differences |
| 6 | +//! so each example can stay short and readable. |
2 | 7 | const std = @import("std"); |
3 | 8 | const builtin = @import("builtin"); |
4 | 9 |
|
@@ -44,8 +49,7 @@ pub fn fixedBufferStream(buffer: []u8) FixedBufferStream { |
44 | 49 | } |
45 | 50 |
|
46 | 51 | /// Type alias for FixedBufferStream that works in both versions |
47 | | -pub const FixedBufferStream = if (is_zig_0_16_or_later) |
48 | | -blk: { |
| 52 | +pub const FixedBufferStream = if (is_zig_0_16_or_later) blk: { |
49 | 53 | // Zig 0.16: Define our own FixedBufferStream with custom Writer |
50 | 54 | break :blk struct { |
51 | 55 | buffer: []u8, |
@@ -91,3 +95,115 @@ blk: { |
91 | 95 | // Zig 0.15: Use standard library type |
92 | 96 | break :blk @TypeOf(std.io.fixedBufferStream(@as([]u8, undefined))); |
93 | 97 | }; |
| 98 | + |
| 99 | +// ===== Allocator compat ====================================================== |
| 100 | + |
| 101 | +/// `std.heap.GeneralPurposeAllocator` was renamed to `std.heap.DebugAllocator` |
| 102 | +/// in Zig 0.16. Use this alias to write code that works on all supported |
| 103 | +/// versions. |
| 104 | +pub const GeneralPurposeAllocator = if (is_zig_0_16_or_later) |
| 105 | + std.heap.DebugAllocator |
| 106 | +else |
| 107 | + std.heap.GeneralPurposeAllocator; |
| 108 | + |
| 109 | +// ===== Filesystem compat ===================================================== |
| 110 | +// |
| 111 | +// `std.fs.cwd()` and the synchronous `std.fs.File` API were removed in 0.16. |
| 112 | +// The new API lives under `std.Io.Dir` / `std.Io.File` and threads an `io` |
| 113 | +// instance through every call. The helpers below give the examples a small, |
| 114 | +// uniform surface that hides this difference. |
| 115 | + |
| 116 | +/// Create directories as needed up to (and including) `path`. Equivalent to |
| 117 | +/// `mkdir -p` on POSIX. |
| 118 | +pub fn makePath(path: []const u8) !void { |
| 119 | + if (comptime is_zig_0_16_or_later) { |
| 120 | + // Zig 0.16 renamed `makePath` to `createDirPath`. |
| 121 | + const io = ioInstance(); |
| 122 | + try std.Io.Dir.cwd().createDirPath(io, path); |
| 123 | + } else { |
| 124 | + try std.fs.cwd().makePath(path); |
| 125 | + } |
| 126 | +} |
| 127 | + |
| 128 | +/// Create a single directory. Returns an error if `path` already exists. |
| 129 | +pub fn makeDir(path: []const u8) !void { |
| 130 | + if (comptime is_zig_0_16_or_later) { |
| 131 | + // Zig 0.16 renamed `makeDir` to `createDir`; pass the platform default |
| 132 | + // permissions so callers don't need to know the new shape. |
| 133 | + const io = ioInstance(); |
| 134 | + try std.Io.Dir.cwd().createDir(io, path, .default_dir); |
| 135 | + } else { |
| 136 | + try std.fs.cwd().makeDir(path); |
| 137 | + } |
| 138 | +} |
| 139 | + |
| 140 | +/// Delete a regular file relative to the current working directory. |
| 141 | +pub fn deleteFile(path: []const u8) !void { |
| 142 | + if (comptime is_zig_0_16_or_later) { |
| 143 | + const io = ioInstance(); |
| 144 | + try std.Io.Dir.cwd().deleteFile(io, path); |
| 145 | + } else { |
| 146 | + try std.fs.cwd().deleteFile(path); |
| 147 | + } |
| 148 | +} |
| 149 | + |
| 150 | +/// One-shot "create file and write everything to it" helper. Hides the |
| 151 | +/// reader/writer plumbing differences between 0.15 and 0.16. |
| 152 | +pub fn writeFile(path: []const u8, content: []const u8) !void { |
| 153 | + if (comptime is_zig_0_16_or_later) { |
| 154 | + const io = ioInstance(); |
| 155 | + var file = try std.Io.Dir.cwd().createFile(io, path, .{}); |
| 156 | + defer file.close(io); |
| 157 | + try file.writeStreamingAll(io, content); |
| 158 | + } else { |
| 159 | + const file = try std.fs.cwd().createFile(path, .{}); |
| 160 | + defer file.close(); |
| 161 | + try file.writeAll(content); |
| 162 | + } |
| 163 | +} |
| 164 | + |
| 165 | +/// Get a usable `std.Io` instance on 0.16. Cheap to call: returns the |
| 166 | +/// process-global single-threaded implementation. |
| 167 | +fn ioInstance() std.Io { |
| 168 | + if (comptime !is_zig_0_16_or_later) @compileError("ioInstance is 0.16+ only"); |
| 169 | + return std.Io.Threaded.global_single_threaded.io(); |
| 170 | +} |
| 171 | + |
| 172 | +// ===== Child process compat ================================================== |
| 173 | +// |
| 174 | +// Zig 0.16 removed `std.process.Child.init(argv, allocator)` and reworked |
| 175 | +// child-process spawning around `std.process.spawn(io, options)`. The wrapper |
| 176 | +// below is intentionally narrow — it exposes only what the examples need: |
| 177 | +// spawn-with-argv, get the OS pid, and kill. |
| 178 | + |
| 179 | +pub const ChildProcess = struct { |
| 180 | + /// OS-level pid. Optional because 0.16 stores it as `?i32` (the value is |
| 181 | + /// `null` after `kill`/`wait`); on 0.14/0.15 it is always populated. |
| 182 | + pid: ?std.process.Child.Id, |
| 183 | + child: std.process.Child, |
| 184 | + |
| 185 | + /// Spawn a process with the given argv. `allocator` is used for argv |
| 186 | + /// translation on 0.14/0.15; ignored on 0.16 (which routes through Io). |
| 187 | + pub fn spawn(argv: []const []const u8, allocator: std.mem.Allocator) !ChildProcess { |
| 188 | + if (comptime is_zig_0_16_or_later) { |
| 189 | + const io = ioInstance(); |
| 190 | + const child = try std.process.spawn(io, .{ .argv = argv }); |
| 191 | + return .{ .pid = child.id, .child = child }; |
| 192 | + } else { |
| 193 | + // The 0.14/0.15 Child.init signature requires an allocator; suppress |
| 194 | + // the "unused parameter" warning by referencing it explicitly here. |
| 195 | + var child = std.process.Child.init(argv, allocator); |
| 196 | + try child.spawn(); |
| 197 | + return .{ .pid = child.id, .child = child }; |
| 198 | + } |
| 199 | + } |
| 200 | + |
| 201 | + pub fn kill(self: *ChildProcess) !void { |
| 202 | + if (comptime is_zig_0_16_or_later) { |
| 203 | + const io = ioInstance(); |
| 204 | + self.child.kill(io); |
| 205 | + } else { |
| 206 | + _ = try self.child.kill(); |
| 207 | + } |
| 208 | + } |
| 209 | +}; |
0 commit comments