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}