running_process/types.rs
1use std::path::PathBuf;
2
3use thiserror::Error;
4
5/// Output stream selector used by process read and capture APIs.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum StreamKind {
8 /// Standard output.
9 Stdout,
10 /// Standard error.
11 Stderr,
12}
13
14impl StreamKind {
15 /// Return the stable lowercase stream name.
16 pub fn as_str(self) -> &'static str {
17 match self {
18 Self::Stdout => "stdout",
19 Self::Stderr => "stderr",
20 }
21 }
22}
23
24/// One captured line or chunk tagged with its source stream.
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub struct StreamEvent {
27 /// Stream that produced `line`.
28 pub stream: StreamKind,
29 /// Raw bytes read from the stream.
30 pub line: Vec<u8>,
31}
32
33/// Result of a bounded process read operation.
34#[derive(Debug, Clone, PartialEq, Eq)]
35pub enum ReadStatus<T> {
36 /// A line or chunk was read.
37 Line(T),
38 /// The read deadline elapsed before data arrived.
39 Timeout,
40 /// The stream reached end-of-file.
41 Eof,
42}
43
44/// Error returned by process lifecycle and I/O operations.
45#[derive(Debug, Error)]
46pub enum ProcessError {
47 /// Start was requested for a process that has already been started.
48 #[error("process already started")]
49 AlreadyStarted,
50 /// The operation requires a running child process.
51 #[error("process is not running")]
52 NotRunning,
53 /// A blocking compatibility adapter was called from a Tokio runtime.
54 #[error("blocking process adapter cannot run inside a Tokio runtime")]
55 RuntimeContext,
56 /// The process was not configured with piped stdin.
57 #[error("process stdin is not available")]
58 StdinUnavailable,
59 /// Child process creation failed.
60 #[error("failed to spawn process: {0}")]
61 Spawn(std::io::Error),
62 /// Reading or writing child process streams failed.
63 #[error("failed to read process output: {0}")]
64 Io(std::io::Error),
65 /// The requested wait or read operation timed out.
66 #[error("process timed out")]
67 Timeout,
68 /// Captured stdout and stderr exceeded the caller's aggregate byte limit.
69 #[error("captured process output exceeded the {limit}-byte limit")]
70 OutputLimitExceeded {
71 /// Aggregate stdout/stderr capture limit.
72 limit: usize,
73 },
74}
75
76/// Captured output and exit status returned by one-shot process helpers.
77#[derive(Debug, Clone, PartialEq, Eq)]
78pub struct RunOutput {
79 /// Raw stdout bytes captured from the child.
80 pub stdout: Vec<u8>,
81 /// Raw stderr bytes captured from the child.
82 pub stderr: Vec<u8>,
83 /// Process exit code, with Unix signal exits represented as negative signal numbers.
84 pub exit_code: i32,
85}
86
87/// Command representation used by [`ProcessConfig`].
88#[derive(Debug, Clone)]
89pub enum CommandSpec {
90 /// Execute a command line through the platform shell.
91 Shell(String),
92 /// Execute a program and argument vector directly.
93 Argv(Vec<String>),
94}
95
96/// Stdin behavior for a spawned process.
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98pub enum StdinMode {
99 /// Inherit stdin from the current process.
100 Inherit,
101 /// Create a pipe so callers can write to child stdin.
102 Piped,
103 /// Connect child stdin to the platform null device.
104 Null,
105}
106
107/// Stderr handling for a spawned process.
108#[derive(Debug, Clone, Copy, PartialEq, Eq)]
109pub enum StderrMode {
110 /// Merge stderr into stdout handling.
111 Stdout,
112 /// Capture stderr through its own pipe.
113 Pipe,
114}
115
116/// Configuration for [`crate::NativeProcess`].
117#[derive(Debug, Clone)]
118pub struct ProcessConfig {
119 /// Command line or argv to execute.
120 pub command: CommandSpec,
121 /// Working directory for the child process.
122 pub cwd: Option<PathBuf>,
123 /// Environment overrides passed to the child process.
124 pub env: Option<Vec<(String, String)>>,
125 /// Whether stdout/stderr should be retained in capture history.
126 pub capture: bool,
127 /// How stderr should be routed.
128 pub stderr_mode: StderrMode,
129 /// Windows process creation flags.
130 pub creationflags: Option<u32>,
131 /// Whether to create a new process group where supported.
132 pub create_process_group: bool,
133 /// How stdin should be routed.
134 pub stdin_mode: StdinMode,
135 /// Nice value to apply on Unix-like platforms.
136 pub nice: Option<i32>,
137 /// Address space limit (RLIMIT_AS / Job Object process memory limit).
138 ///
139 /// On Linux this calls `setrlimit(RLIMIT_AS, ...)` in the child's
140 /// `pre_exec` hook. On Windows it sets `JOB_OBJECT_LIMIT_PROCESS_MEMORY`
141 /// on the per-spawn Job Object. On other platforms it is silently
142 /// ignored (the spawn still succeeds; limits are best-effort).
143 pub address_space_limit_bytes: Option<u64>,
144}