Skip to main content

qubit_redact/facade/
debug_display.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//! Lazy `Debug`-to-`Display` adaptation for scalar redaction.
9
10use std::fmt;
11
12/// Presents a borrowed [`fmt::Debug`] value through [`fmt::Display`].
13///
14/// This adapter performs no eager allocation or formatting. Passing it to
15/// [`crate::Redactor::redact_field`] or [`crate::RedactedTextComposer::field`]
16/// lets an opaque high- or secret-sensitivity mask avoid observing the wrapped
17/// value altogether. The wrapped `Debug` implementation runs only when the
18/// selected policy needs the source representation, such as for pass-through,
19/// disabled, low-, or medium-sensitivity rendering.
20///
21/// # Examples
22///
23/// ```
24/// use qubit_redact::{DebugDisplay, Redactor};
25///
26/// let values = vec!["first", "second"];
27/// let output = Redactor::strict().redact_field("selection", &DebugDisplay::new(&values));
28/// assert_eq!(output.text().as_str(), "<redacted>");
29/// ```
30#[derive(Clone, Copy)]
31pub struct DebugDisplay<'value, T: ?Sized> {
32    /// Borrowed value whose debug representation is produced on demand.
33    value: &'value T,
34}
35
36impl<'value, T: ?Sized> DebugDisplay<'value, T> {
37    /// Wraps a borrowed value without formatting or allocating.
38    #[must_use]
39    #[inline(always)]
40    pub const fn new(value: &'value T) -> Self {
41        Self { value }
42    }
43}
44
45impl<T> fmt::Display for DebugDisplay<'_, T>
46where
47    T: fmt::Debug + ?Sized,
48{
49    /// Lazily delegates formatting to the wrapped value's `Debug` output.
50    #[inline]
51    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
52        fmt::Debug::fmt(self.value, formatter)
53    }
54}