Skip to main content

qubit_redact/facade/
redacted_text_composer.rs

1// =============================================================================
2//    Copyright (c) 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Consumption-based construction of one ordered redacted text.
9
10use crate::RedactionTextOutput;
11use crate::domain::Redact;
12use crate::runtime::TextSession;
13
14/// Builds one ordered, redacted text value through consuming chained calls.
15///
16/// # Examples
17///
18/// ```
19/// use qubit_redact::Redactor;
20///
21/// let output = Redactor::strict()
22///     .text_composer()
23///     .literal("password=")
24///     .field("password", "raw-secret")
25///     .finish();
26/// assert!(!output.text().as_str().contains("raw-secret"));
27/// ```
28pub struct RedactedTextComposer {
29    /// Typed transaction that exclusively owns this composer's text output.
30    session: TextSession,
31}
32
33impl RedactedTextComposer {
34    /// Creates a composer backed by one private runtime transaction.
35    #[must_use]
36    pub(crate) const fn from_session(session: TextSession) -> Self {
37        Self { session }
38    }
39
40    /// Appends trusted program-authored text.
41    #[must_use]
42    pub fn literal(mut self, text: &'static str) -> Self {
43        let _ = self.session.literal(text);
44        self
45    }
46
47    /// Redacts and appends one scalar field.
48    #[must_use]
49    pub fn field<T>(mut self, field: &str, value: &T) -> Self
50    where
51        T: std::fmt::Display + ?Sized,
52    {
53        let _ = self.session.field(field, value);
54        self
55    }
56
57    /// Redacts and appends one domain value.
58    #[must_use]
59    pub fn value<T>(mut self, value: &T) -> Self
60    where
61        T: Redact + ?Sized,
62    {
63        let _ = self.session.value(value);
64        self
65    }
66
67    /// Appends command-line text configured through the argv writer.
68    #[must_use]
69    pub fn argv<F>(mut self, configure: F) -> Self
70    where
71        F: for<'session> FnOnce(&mut crate::formats::argv::ArgvRedactionWriter<'session>),
72    {
73        self.session.argv(configure);
74        self
75    }
76
77    /// Appends environment text configured through the environment writer.
78    #[must_use]
79    pub fn env<F>(mut self, configure: F) -> Self
80    where
81        F: for<'session> FnOnce(&mut crate::formats::env::EnvRedactionWriter<'session>),
82    {
83        self.session.env(configure);
84        self
85    }
86
87    /// Appends process text configured through the process writer.
88    #[must_use]
89    pub fn process<F>(mut self, configure: F) -> Self
90    where
91        F: for<'session> FnOnce(&mut crate::formats::process::ProcessRedactionWriter<'session>),
92    {
93        let _ = self.session.process(configure);
94        self
95    }
96
97    /// Appends JSON text configured through the JSON writer.
98    #[cfg(feature = "json")]
99    #[must_use]
100    pub fn json<F>(mut self, configure: F) -> Self
101    where
102        F: for<'session> FnOnce(&mut crate::formats::json::JsonRedactionWriter<'session>),
103    {
104        let _ = self.session.json(configure);
105        self
106    }
107
108    /// Appends HTTP text configured through the HTTP writer.
109    #[cfg(feature = "http")]
110    #[must_use]
111    pub fn http<F>(mut self, configure: F) -> Self
112    where
113        F: for<'session> FnOnce(&mut crate::formats::http::HttpRedactionWriter<'session>),
114    {
115        let _ = self.session.http(configure);
116        self
117    }
118
119    /// Appends URI text configured through the URI writer.
120    #[cfg(feature = "uri")]
121    #[must_use]
122    pub fn uri<F>(mut self, configure: F) -> Self
123    where
124        F: for<'session> FnOnce(&mut crate::formats::uri::UriRedactionWriter<'session>),
125    {
126        let _ = self.session.uri(configure);
127        self
128    }
129
130    /// Consumes the composer and publishes its redacted text and summary.
131    #[must_use]
132    pub fn finish(self) -> RedactionTextOutput {
133        self.session.finish()
134    }
135}