qubit_redact/facade/redactor/process.rs
1// =============================================================================
2// Copyright (c) 2025 - 2026 Haixing Hu.
3//
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Process, argument-vector, and environment redaction operations.
9
10use std::ffi::OsStr;
11use std::iter::once;
12
13use super::Redactor;
14use crate::RedactionInspection;
15use crate::RedactionInspectionError;
16use crate::RedactionTextOutput;
17
18impl Redactor {
19 /// Redacts an argument vector through one completed text transaction.
20 ///
21 /// # Type Parameters
22 ///
23 /// - `'items`: Borrow of argument item contents.
24 /// - `I`: One-pass iterator preserving argument order.
25 ///
26 /// # Parameters
27 ///
28 /// - `items`: Arguments with caller-supplied classification hints.
29 ///
30 /// # Returns
31 ///
32 /// Final redacted text and its execution summary, including any truncation
33 /// or admission failure recorded while processing the value.
34 #[must_use]
35 #[inline]
36 pub fn redact_argv<'items, I>(&self, items: I) -> RedactionTextOutput
37 where
38 I: IntoIterator<Item = crate::formats::argv::ArgvItem<'items>>,
39 {
40 let mut session = self.text_runtime();
41 session.argv(|argv| {
42 let _ = argv.items(items);
43 });
44 session.finish()
45 }
46
47 /// Inspects explicitly classified argv items without rendering them.
48 ///
49 /// # Errors
50 ///
51 /// Returns [`RedactionInspectionError`] when non-UTF-8 data or a shared
52 /// resource limit prevents complete inspection.
53 ///
54 /// # Type Parameters
55 ///
56 /// - `'items`: Borrow of argument item contents.
57 /// - `I`: One-pass iterator preserving argument order.
58 ///
59 /// # Parameters
60 ///
61 /// - `items`: Arguments with caller-supplied classification hints.
62 ///
63 /// # Returns
64 ///
65 /// A conclusive sensitivity inspection, or a value-free error containing
66 /// resource usage and reasons why complete classification was unavailable.
67 #[inline]
68 pub fn inspect_argv<'items, I>(&self, items: I) -> Result<RedactionInspection, RedactionInspectionError>
69 where
70 I: IntoIterator<Item = crate::formats::argv::ArgvItem<'items>>,
71 {
72 let mut session = self.inspection_runtime();
73 crate::formats::argv::inspection::inspect_items(&mut session, items, false);
74 session.finish()
75 }
76
77 /// Redacts argv items using heuristic option classification.
78 ///
79 /// # Type Parameters
80 ///
81 /// - `'items`: Borrow of argument item contents.
82 /// - `I`: One-pass iterator preserving argument order.
83 ///
84 /// # Parameters
85 ///
86 /// - `items`: Arguments with caller-supplied classification hints.
87 ///
88 /// # Returns
89 ///
90 /// Final redacted text and its execution summary, including any truncation
91 /// or admission failure recorded while processing the value.
92 #[must_use]
93 #[inline]
94 pub fn redact_heuristic_argv<'items, I>(&self, items: I) -> RedactionTextOutput
95 where
96 I: IntoIterator<Item = crate::formats::argv::ArgvItem<'items>>,
97 {
98 let mut session = self.text_runtime();
99 session.argv(|argv| {
100 let _ = argv.heuristic_items(items);
101 });
102 session.finish()
103 }
104
105 /// Inspects argv items using heuristic option classification.
106 ///
107 /// # Errors
108 ///
109 /// Returns [`RedactionInspectionError`] when non-UTF-8 data, incomplete
110 /// option syntax, or a shared resource limit prevents complete inspection.
111 ///
112 /// # Type Parameters
113 ///
114 /// - `'items`: Borrow of argument item contents.
115 /// - `I`: One-pass iterator preserving argument order.
116 ///
117 /// # Parameters
118 ///
119 /// - `items`: Arguments with caller-supplied classification hints.
120 ///
121 /// # Returns
122 ///
123 /// A conclusive sensitivity inspection, or a value-free error containing
124 /// resource usage and reasons why complete classification was unavailable.
125 #[inline]
126 pub fn inspect_heuristic_argv<'items, I>(&self, items: I) -> Result<RedactionInspection, RedactionInspectionError>
127 where
128 I: IntoIterator<Item = crate::formats::argv::ArgvItem<'items>>,
129 {
130 let mut session = self.inspection_runtime();
131 crate::formats::argv::inspection::inspect_items(&mut session, items, true);
132 session.finish()
133 }
134
135 /// Redacts one environment assignment through one completed transaction.
136 ///
137 /// # Parameters
138 ///
139 /// - `name`: Environment variable name used for classification.
140 /// - `value`: Environment variable value to inspect or redact.
141 ///
142 /// # Returns
143 ///
144 /// Final redacted text and its execution summary, including any truncation
145 /// or admission failure recorded while processing the value.
146 #[must_use]
147 #[inline]
148 pub fn redact_env(&self, name: &str, value: &str) -> RedactionTextOutput {
149 let mut session = self.text_runtime();
150 session.env(|environment| {
151 let _ = environment.pair(name, value);
152 });
153 session.finish()
154 }
155
156 /// Inspects one environment assignment without rendering it.
157 ///
158 /// # Errors
159 ///
160 /// Returns [`RedactionInspectionError`] when the shared input or
161 /// structural budget prevents complete inspection.
162 ///
163 /// # Parameters
164 ///
165 /// - `name`: Environment variable name used for classification.
166 /// - `value`: Environment variable value to inspect or redact.
167 ///
168 /// # Returns
169 ///
170 /// A conclusive sensitivity inspection, or a value-free error containing
171 /// resource usage and reasons why complete classification was unavailable.
172 #[inline]
173 pub fn inspect_env(&self, name: &str, value: &str) -> Result<RedactionInspection, RedactionInspectionError> {
174 let mut session = self.inspection_runtime();
175 crate::formats::env::inspection::inspect_pair(&mut session, name, value);
176 session.finish()
177 }
178
179 /// Redacts environment assignments through one completed transaction.
180 ///
181 /// # Type Parameters
182 ///
183 /// - `'items`: Borrow of native environment names and values.
184 /// - `I`: One-pass iterator of environment assignments.
185 ///
186 /// # Parameters
187 ///
188 /// - `pairs`: Native names and values, visited in iterator order.
189 ///
190 /// # Returns
191 ///
192 /// Final redacted text and its execution summary, including any truncation
193 /// or admission failure recorded while processing the value.
194 #[must_use]
195 #[inline]
196 pub fn redact_env_pairs<'items, I>(&self, pairs: I) -> RedactionTextOutput
197 where
198 I: IntoIterator<Item = (&'items OsStr, &'items OsStr)>,
199 {
200 let mut session = self.text_runtime();
201 session.env(|environment| {
202 let _ = environment.os_pairs(pairs);
203 });
204 session.finish()
205 }
206
207 /// Inspects environment assignments without rendering them.
208 ///
209 /// # Errors
210 ///
211 /// Returns [`RedactionInspectionError`] when non-UTF-8 data or a shared
212 /// resource limit prevents complete inspection.
213 ///
214 /// # Type Parameters
215 ///
216 /// - `'items`: Borrow of native environment names and values.
217 /// - `I`: One-pass iterator of environment assignments.
218 ///
219 /// # Parameters
220 ///
221 /// - `pairs`: Native names and values, visited in iterator order.
222 ///
223 /// # Returns
224 ///
225 /// A conclusive sensitivity inspection, or a value-free error containing
226 /// resource usage and reasons why complete classification was unavailable.
227 #[inline]
228 pub fn inspect_env_pairs<'items, I>(&self, pairs: I) -> Result<RedactionInspection, RedactionInspectionError>
229 where
230 I: IntoIterator<Item = (&'items OsStr, &'items OsStr)>,
231 {
232 let mut session = self.inspection_runtime();
233 crate::formats::env::inspection::inspect_os_pairs(&mut session, pairs);
234 session.finish()
235 }
236
237 /// Redacts one process command through one completed text transaction.
238 ///
239 /// # Type Parameters
240 ///
241 /// - `'arguments`: Borrow of the executable and argument data.
242 /// - `'variables`: Borrow of environment names and values.
243 /// - `A`: One-pass iterator of argument items.
244 /// - `E`: One-pass iterator of environment assignments.
245 ///
246 /// # Parameters
247 ///
248 /// - `program`: Executable represented as native operating-system text.
249 /// - `arguments`: Arguments in their original command order.
250 /// - `variables`: Environment assignments appended after command
251 /// processing.
252 ///
253 /// # Returns
254 ///
255 /// Final redacted text and its execution summary, including any truncation
256 /// or admission failure recorded while processing the value.
257 #[must_use]
258 #[inline]
259 pub fn redact_process<'arguments, 'variables, A, E>(
260 &self,
261 program: &'arguments OsStr,
262 arguments: A,
263 variables: E,
264 ) -> RedactionTextOutput
265 where
266 A: IntoIterator<Item = crate::formats::argv::ArgvItem<'arguments>>,
267 E: IntoIterator<Item = (&'variables OsStr, &'variables OsStr)>,
268 {
269 let mut session = self.text_runtime();
270 let _ = session.process(|process| {
271 let _ = process.command(program, arguments, variables);
272 });
273 session.finish()
274 }
275
276 /// Inspects one process command without rendering its components.
277 ///
278 /// # Errors
279 ///
280 /// Returns [`RedactionInspectionError`] when argv or environment data is
281 /// invalid, incomplete, or rejected by a shared resource limit.
282 ///
283 /// # Type Parameters
284 ///
285 /// - `'arguments`: Borrow of the executable and argument data.
286 /// - `'variables`: Borrow of environment names and values.
287 /// - `A`: One-pass iterator of argument items.
288 /// - `E`: One-pass iterator of environment assignments.
289 ///
290 /// # Parameters
291 ///
292 /// - `program`: Executable represented as native operating-system text.
293 /// - `arguments`: Arguments in their original command order.
294 /// - `variables`: Environment assignments appended after command
295 /// processing.
296 ///
297 /// # Returns
298 ///
299 /// A conclusive sensitivity inspection, or a value-free error containing
300 /// resource usage and reasons why complete classification was unavailable.
301 #[inline]
302 pub fn inspect_process<'arguments, 'variables, A, E>(
303 &self,
304 program: &'arguments OsStr,
305 arguments: A,
306 variables: E,
307 ) -> Result<RedactionInspection, RedactionInspectionError>
308 where
309 A: IntoIterator<Item = crate::formats::argv::ArgvItem<'arguments>>,
310 E: IntoIterator<Item = (&'variables OsStr, &'variables OsStr)>,
311 {
312 let mut session = self.inspection_runtime();
313 let command = once(crate::formats::argv::ArgvItem::plain(program)).chain(arguments);
314 crate::formats::argv::inspection::inspect_items(&mut session, command, true);
315 crate::formats::env::inspection::inspect_os_pairs(&mut session, variables);
316 session.finish()
317 }
318}