Skip to main content

qubit_redact/facade/
redaction_inspection.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//! Conclusive sensitivity metadata produced without rendering source values.
9
10use super::RedactionUsage;
11use crate::Sensitivity;
12
13/// Highest sensitivity found by one complete, bounded inspection.
14///
15/// A successful value proves the complete admitted input was classified.
16/// [`None`] from [`Self::max_sensitivity`] therefore means no inspected value
17/// was declared sensitive. Inconclusive traversal is returned as
18/// [`crate::RedactionInspectionError`] instead of this type.
19///
20/// # Examples
21///
22/// ```
23/// use qubit_redact::Redactor;
24/// use qubit_redact::Sensitivity;
25///
26/// let inspection = Redactor::strict()
27///     .inspect_field("password", "raw-secret")
28///     .expect("the scalar inspection is bounded and valid");
29/// assert_eq!(inspection.max_sensitivity(), Some(Sensitivity::Secret));
30/// ```
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub struct RedactionInspection {
33    /// Whether policy evaluation was bypassed for this complete traversal.
34    redaction_disabled: bool,
35    /// Strongest sensitivity observed during the complete traversal.
36    max_sensitivity: Option<Sensitivity>,
37    /// Resource use excluding any output bytes, because inspection does not
38    /// render.
39    usage: RedactionUsage,
40}
41
42impl RedactionInspection {
43    /// Creates a conclusive inspection from runtime-owned metadata.
44    #[must_use]
45    pub(crate) const fn new(
46        redaction_disabled: bool,
47        max_sensitivity: Option<Sensitivity>,
48        usage: RedactionUsage,
49    ) -> Self {
50        Self {
51            redaction_disabled,
52            max_sensitivity,
53            usage,
54        }
55    }
56
57    /// Reports whether the complete traversal found sensitive data.
58    #[must_use]
59    #[inline(always)]
60    pub const fn contains_sensitive(&self) -> bool {
61        self.max_sensitivity.is_some()
62    }
63
64    /// Returns whether redaction was globally disabled for this inspection.
65    #[must_use]
66    #[inline(always)]
67    pub const fn is_redaction_disabled(&self) -> bool {
68        self.redaction_disabled
69    }
70
71    /// Returns the strongest sensitivity found by the complete traversal.
72    ///
73    /// # Returns
74    ///
75    /// `Some(level)` for sensitive data, or `None` when the complete input was
76    /// classified as plain.
77    #[must_use]
78    #[inline(always)]
79    pub const fn max_sensitivity(&self) -> Option<Sensitivity> {
80        self.max_sensitivity
81    }
82
83    /// Returns resources consumed while classifying the input.
84    ///
85    /// Output bytes are always zero because inspection never renders values.
86    #[must_use]
87    #[inline(always)]
88    pub const fn usage(&self) -> RedactionUsage {
89        self.usage
90    }
91}