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/// # Type Parameters
22///
23/// - `'value`: Lifetime of the borrowed source.
24/// - `T`: Source type; its Debug implementation is required when formatting.
25///
26/// # Examples
27///
28/// ```
29/// use qubit_redact::{DebugDisplay, Redactor};
30///
31/// let values = vec!["first", "second"];
32/// let output = Redactor::strict().redact_field("selection", &DebugDisplay::new(&values));
33/// assert_eq!(output.text().as_str(), "<redacted>");
34/// ```
35#[derive(Clone, Copy)]
36pub struct DebugDisplay<'value, T: ?Sized> {
37 /// Borrowed value whose debug representation is produced on demand.
38 value: &'value T,
39}
40
41impl<'value, T: ?Sized> DebugDisplay<'value, T> {
42 /// Wraps a borrowed value without formatting or allocating.
43 ///
44 /// # Parameters
45 ///
46 /// - `value`: Source whose Debug formatter is deferred until needed.
47 ///
48 /// # Returns
49 ///
50 /// A borrowed adapter that has not inspected or formatted the source.
51 #[must_use]
52 #[inline(always)]
53 pub const fn new(value: &'value T) -> Self {
54 Self { value }
55 }
56}
57
58impl<T> fmt::Display for DebugDisplay<'_, T>
59where
60 T: fmt::Debug + ?Sized,
61{
62 /// Lazily delegates formatting to the wrapped value's `Debug` output.
63 ///
64 /// # Parameters
65 ///
66 /// - `formatter`: Destination formatter receiving the source Debug
67 /// representation.
68 ///
69 /// # Returns
70 ///
71 /// Success after the wrapped Debug formatter completes.
72 ///
73 /// # Errors
74 ///
75 /// Propagates any error returned by the wrapped Debug implementation or
76 /// destination.
77 #[inline(always)]
78 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
79 fmt::Debug::fmt(self.value, formatter)
80 }
81}