Created
March 25, 2024 17:07
-
-
Save mikdusan/3f996e61e1ab09fc26e6b5e55a9d3ae8 to your computer and use it in GitHub Desktop.
Zig pipelines with a ruby-like flexible interface for closes, redirects, pipes, symbolic names, files-by-paths, etc.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
test "pipeline" { | |
// SILLY PIPELINE EXAMPLE | |
// | |
// cat /etc/passwd | (code-filter) | sort > /tmp/out.txt | |
// |-- child[0] ---| |---- child[1] -----| | |
// | |
// note: not convinced splitting ChildBuilder/ChildProcess is ideal | |
var builder = .{ | |
try ChildBuilder.init(testing.allocator), | |
try ChildBuilder.init(testing.allocator), | |
}; | |
defer builder[0].deinit(); | |
defer builder[1].deinit(); | |
try builder[0].addArgs(&.{"cat", "/etc/passwd"}); | |
try builder[1].addArgs(&.{"sort"}); | |
try builder[1].redirectEndpointTo(.stdout, .{ .create, "/tmp/out.txt" }); | |
const pipe_end = .{ | |
try builder[0].makeEndpointPipe(.stdout, .output), | |
try builder[1].makeEndpointPipe(.stdin, .input), | |
}; | |
var pipe_end_open: [2]bool = .{ true, true }; | |
defer if (pipe_end_open[0]) pipe_end[0].close(); | |
defer if (pipe_end_open[1]) pipe_end[1].close(); | |
var child = .{ | |
try builder[0].spawn(testing.allocator), | |
try builder[1].spawn(testing.allocator), | |
}; | |
defer child[0].deinit(); | |
defer child[1].deinit(); | |
try filter(pipe_end[0], pipe_end[1]); | |
pipe_end[0].close(); | |
pipe_end_open[0] = false; | |
pipe_end[1].close(); | |
pipe_end_open[1] = false; | |
const wr = .{ | |
try child[0].wait(.{}), | |
try child[1].wait(.{}), | |
}; | |
try testing.expect(wr[0] == .exit); | |
try testing.expectEqual(wr[0].exit, 0); | |
try testing.expect(wr[1] == .exit); | |
try testing.expectEqual(wr[1].exit, 0); | |
} | |
fn filter(in: std.fs.File, out: std.fs.File) !void { | |
const r = in.reader(); | |
const w = out.writer(); | |
while (true) { | |
const b = r.readByte() catch break; | |
try w.writeByte(if (b == ':') '_' else b); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment