Skip to main content

qubit_redact/facade/
redacted_text.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//! Final text produced by one redaction operation.
9
10use std::borrow::Cow;
11use std::fmt;
12
13/// Final UTF-8 text produced by a redaction operation under its selected
14/// policy.
15///
16/// The value has crossed the runtime's plain-text presentation boundary. It is
17/// owned and can be rendered with [`std::fmt::Display`] without running another
18/// redaction pass. This guarantee is policy-relative: a disabled policy or an
19/// explicitly unredacted writer operation may deliberately preserve source
20/// content. Callers must not treat this type as proof that the text is
21/// confidential in every policy configuration. Any additional length
22/// restriction belongs to the caller's final logging or presentation sink.
23///
24/// # Examples
25///
26/// ```
27/// use qubit_redact::Redactor;
28///
29/// let output = Redactor::strict().redact_field("password", "raw-secret");
30/// assert_eq!(output.text().as_str(), "<redacted>");
31/// ```
32#[derive(Debug, Clone, PartialEq, Eq, Hash)]
33pub struct RedactedText(
34    /// Owned text that has already crossed the redaction safety boundary.
35    String,
36);
37
38impl RedactedText {
39    /// Creates final text from an already escaped representation.
40    #[must_use]
41    #[inline]
42    pub(crate) fn from_escaped(value: impl Into<Cow<'static, str>>) -> Self {
43        Self(value.into().into_owned())
44    }
45
46    /// Borrows the final redacted text.
47    #[must_use]
48    #[inline(always)]
49    pub fn as_str(&self) -> &str {
50        &self.0
51    }
52
53    /// Consumes the wrapper and returns its owned text.
54    #[must_use]
55    #[inline]
56    pub fn into_string(self) -> String {
57        self.0
58    }
59}
60
61impl AsRef<str> for RedactedText {
62    /// Borrows the safe text through the standard string-reference contract.
63    #[inline(always)]
64    fn as_ref(&self) -> &str {
65        self.as_str()
66    }
67}
68
69impl fmt::Display for RedactedText {
70    /// Writes only the finalized safe text to the destination formatter.
71    #[inline(always)]
72    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
73        formatter.write_str(self.as_str())
74    }
75}