1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// =============================================================================
// Copyright (c) 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! Non-rendering transaction with typed inspection ownership.
use std::sync::Arc;
use super::inspection_runtime::InspectionRuntime;
use super::runtime_core::RuntimeCore;
use super::runtime_session::RuntimeSession;
use crate::Redact;
use crate::RedactionCompletion;
use crate::RedactionInspection;
use crate::RedactionInspectionError;
use crate::RedactionPolicy;
use crate::RedactionReasons;
use crate::Sensitivity;
/// Owns one non-rendering runtime and its sensitivity accumulator.
pub(crate) struct InspectionSession {
/// Shared accounting and obligatory inspection accumulator.
runtime: InspectionRuntime,
}
impl InspectionSession {
/// Creates an inspection transaction from one policy snapshot.
///
/// # Parameters
///
/// - `policy`: Immutable snapshot shared by the new transaction.
///
/// # Returns
///
/// Fresh mode-specific state with empty resource accounting.
#[must_use]
#[inline(always)]
pub(crate) fn new(policy: Arc<RedactionPolicy>) -> Self {
Self {
runtime: InspectionRuntime::new(policy),
}
}
/// Classifies one domain value without rendering field content.
///
/// # Type Parameters
///
/// - `T`: Possibly unsized value implementing structural `Redact`.
///
/// # Parameters
///
/// - `value`: Domain value traversed through the inspection writer.
pub(crate) fn inspect<T>(&mut self, value: &T)
where
T: Redact + ?Sized,
{
let mut writer = crate::domain::RedactionWriter::new_root(self);
value.write_redacted(&mut writer);
let _ = writer.finish_with_completion();
}
/// Consumes this transaction into a conclusive result or fail-closed error.
///
/// # Errors
///
/// Returns the recorded reasons and usage if any omission prevents a
/// conclusive sensitivity decision.
///
/// # Returns
///
/// A conclusive inspection only when no completion or provenance indicates
/// omission.
pub(crate) fn finish(self) -> Result<RedactionInspection, RedactionInspectionError> {
let (max_sensitivity, summary) = self.runtime.into_parts();
if summary.completion() == RedactionCompletion::Complete && summary.reasons() == RedactionReasons::empty() {
return Ok(RedactionInspection::new(
summary.is_redaction_disabled(),
max_sensitivity,
summary.usage(),
));
}
Err(RedactionInspectionError::new(summary.reasons(), summary.usage()))
}
}
impl RuntimeSession for InspectionSession {
/// Borrows the publication-independent inspection core.
///
/// # Returns
///
/// The accounting core borrowed without changing transaction state.
#[inline(always)]
fn runtime(&self) -> &RuntimeCore {
&self.runtime.core
}
/// Mutably borrows the publication-independent inspection core.
///
/// # Returns
///
/// An exclusive borrow of the transaction accounting core.
#[inline(always)]
fn runtime_mut(&mut self) -> &mut RuntimeCore {
&mut self.runtime.core
}
/// Identifies this session as non-rendering inspection state.
///
/// # Returns
///
/// Whether this implementation observes sensitivity without rendering
/// output.
#[inline(always)]
fn is_inspection(&self) -> bool {
true
}
/// Records the strongest sensitivity in the obligatory accumulator.
///
/// # Parameters
///
/// - `sensitivity`: New classification combined with the inspection
/// maximum.
#[inline(always)]
fn observe_sensitivity(&mut self, sensitivity: Sensitivity) {
self.runtime.observe_sensitivity(sensitivity);
}
}