use super::StructuralBudget;
use super::structural_entry::StructuralEntry;
use super::summary_builder::SummaryBuilder;
use crate::RedactionReason;
use crate::RedactionSummary;
use crate::RedactionUsage;
pub(crate) struct JsonStructureAdmission<'runtime> {
structural: &'runtime mut StructuralBudget,
usage: &'runtime mut RedactionUsage,
active_operation_usage: &'runtime mut Option<RedactionUsage>,
summary: &'runtime mut SummaryBuilder,
active_operation_summary: &'runtime mut Option<SummaryBuilder>,
}
impl<'runtime> JsonStructureAdmission<'runtime> {
#[must_use]
pub(super) const fn new(
structural: &'runtime mut StructuralBudget,
usage: &'runtime mut RedactionUsage,
active_operation_usage: &'runtime mut Option<RedactionUsage>,
summary: &'runtime mut SummaryBuilder,
active_operation_summary: &'runtime mut Option<SummaryBuilder>,
) -> Self {
Self {
structural,
usage,
active_operation_usage,
summary,
active_operation_summary,
}
}
#[must_use]
pub(crate) fn admit_node(&mut self, depth: usize) -> bool {
match self.structural.admit_format_node(depth) {
StructuralEntry::Entered => {
self.record_structural_node(depth);
true
}
StructuralEntry::DepthLimitReached => {
self.record_summary(RedactionSummary::truncated(RedactionReason::DepthLimitReached));
false
}
StructuralEntry::TraversalLimitReached => {
self.record_summary(RedactionSummary::truncated(RedactionReason::TraversalLimitReached));
false
}
}
}
#[must_use]
pub(crate) fn admit_collection_item(&mut self) -> bool {
if self.structural.admit_collection_item() {
self.record_collection_item();
true
} else {
self.record_summary(RedactionSummary::truncated(RedactionReason::TraversalLimitReached));
false
}
}
fn record_structural_node(&mut self, depth: usize) {
*self.usage = (*self.usage).with_domain_node(depth);
if let Some(usage) = self.active_operation_usage.as_mut() {
*usage = usage.with_domain_node(depth);
}
}
fn record_collection_item(&mut self) {
*self.usage = (*self.usage).with_collection_item();
if let Some(usage) = self.active_operation_usage.as_mut() {
*usage = usage.with_collection_item();
}
}
fn record_summary(&mut self, delta: RedactionSummary) {
*self.summary = self.summary.merge(delta);
if let Some(summary) = self.active_operation_summary.as_mut() {
*summary = summary.merge(delta);
}
}
}