Skip to main content

qubit_redact/domain/
redact.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//! Non-destructive redaction contract for domain objects.
9
10use std::fmt::{
11    self,
12    Formatter,
13};
14
15use crate::{
16    Redacted,
17    RedactionPolicy,
18    RedactionSession,
19};
20
21/// Formats a domain object through an explicit immutable redaction policy.
22///
23/// Implementations must write only the redacted representation from
24/// [`Self::fmt_redacted`]. The original object remains unchanged.
25/// Domain owners remain responsible for deciding which fields are sensitive
26/// and for selecting the redaction boundary. This trait does not infer that a
27/// newly added field needs redaction.
28pub trait Redact {
29    /// Creates a borrowed view using a snapshot of the current default policy.
30    ///
31    /// # Returns
32    ///
33    /// A lazy redacted view borrowing this object and owning its policy
34    /// snapshot.
35    #[inline(always)]
36    fn redacted(&self) -> Redacted<'_, Self>
37    where
38        Self: Sized,
39    {
40        Redacted::new(self, RedactionPolicy::default())
41    }
42
43    /// Creates a borrowed view using a snapshot of `policy`.
44    ///
45    /// # Parameters
46    ///
47    /// * `policy` - Policy to clone into the returned view.
48    ///
49    /// # Returns
50    ///
51    /// A lazy redacted view borrowing this object and owning the cloned policy.
52    #[inline(always)]
53    fn redacted_with(&self, policy: &RedactionPolicy) -> Redacted<'_, Self>
54    where
55        Self: Sized,
56    {
57        Redacted::new(self, policy.clone())
58    }
59
60    /// Writes this object's redacted debug representation.
61    ///
62    /// Implementations should honor the formatting flags carried by
63    /// `formatter`, including alternate pretty formatting. Sensitive fields
64    /// must not invoke their original `Debug` or `Display` implementations.
65    ///
66    /// # Parameters
67    ///
68    /// * `session` - Shared diagnostic session governing this representation
69    ///   and all nested values.
70    /// * `formatter` - Destination formatting context.
71    ///
72    /// # Returns
73    ///
74    /// The formatter result for the complete redacted representation.
75    ///
76    /// # Errors
77    ///
78    /// Returns [`fmt::Error`] when the destination formatter cannot accept the
79    /// complete representation.
80    #[doc(hidden)]
81    fn fmt_redacted(
82        &self,
83        session: &RedactionSession<'_>,
84        formatter: &mut Formatter<'_>,
85    ) -> fmt::Result;
86}