Skip to main content

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}