const std = @import("std"); const Allocator = std.mem.Allocator; const print = std.debug.print; const types = @import("./lib/types.zig"); const CommandStatus = types.CommandStatus; const OutputCapture = types.OutputCapture; const InputSource = types.InputSource; const cmd = @import("../cmd.zig"); const Command = cmd.Command; // Function type for executing commands with output capture const ExecuteCommandFn = *const fn (Command, Allocator, ?*OutputCapture, ?*InputSource) anyerror!CommandStatus; pub const PipeCommand = struct { left: *Command, right: *Command, pub fn eval(pipe: PipeCommand, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource, executeCommandWithOutput: ExecuteCommandFn) !CommandStatus { _ = input_source; // Pipe handles its own input flow // Create output capture for the left command var left_output = OutputCapture.init(allocator); defer left_output.deinit(); // Execute the left command and capture its output const left_status = try executeCommandWithOutput(pipe.left.*, allocator, &left_output, null); // If the left command failed, return its status if (left_status != .Code or left_status.Code != 0) { return left_status; } // Create input source from the left command's output const left_output_data = left_output.getContents(); var right_input = InputSource.init(left_output_data); // Execute the right command with the left command's output as input const right_status = try executeCommandWithOutput(pipe.right.*, allocator, output_capture, &right_input); return right_status; } };