1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*******************************************************************************
*
* Copyright (c) 2026.
* Haixing Hu, Qubit Co. Ltd.
*
* All rights reserved.
*
******************************************************************************/
use std::time::Duration;
use super::{
output_collector::collect_output,
output_reader::OutputReader,
stdin_writer::StdinWriter,
};
use crate::{
CommandError,
CommandOutput,
};
/// Output and stdin helper threads for one running command.
pub(crate) struct CommandIo {
/// Reader thread draining stdout.
stdout_reader: OutputReader,
/// Reader thread draining stderr.
stderr_reader: OutputReader,
/// Optional writer thread feeding stdin.
stdin_writer: StdinWriter,
}
impl CommandIo {
/// Creates a command I/O helper bundle.
///
/// # Parameters
///
/// * `stdout_reader` - Reader thread draining stdout.
/// * `stderr_reader` - Reader thread draining stderr.
/// * `stdin_writer` - Optional writer thread feeding stdin.
///
/// # Returns
///
/// I/O helper bundle consumed when output is collected or drained.
pub(crate) fn new(
stdout_reader: OutputReader,
stderr_reader: OutputReader,
stdin_writer: StdinWriter,
) -> Self {
Self {
stdout_reader,
stderr_reader,
stdin_writer,
}
}
/// Collects output from all helper threads.
///
/// # Parameters
///
/// * `command` - Human-readable command text for diagnostics.
/// * `status` - Process exit status.
/// * `elapsed` - Observed command duration.
/// * `lossy_output` - Whether text accessors should replace invalid UTF-8.
///
/// # Returns
///
/// Captured command output.
///
/// # Errors
///
/// Returns [`CommandError`] if stream collection or stdin writing fails.
pub(crate) fn collect(
self,
command: &str,
status: std::process::ExitStatus,
elapsed: Duration,
lossy_output: bool,
) -> Result<CommandOutput, CommandError> {
collect_output(
command,
status,
elapsed,
lossy_output,
self.stdout_reader,
self.stderr_reader,
self.stdin_writer,
)
}
}