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
// =============================================================================
// Copyright (c) 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! Shared input accounting for bounded diagnostic redaction.
/// Tracks source bytes consumed across one diagnostic rendering.
///
/// Once a reservation does not fit, the budget becomes permanently exhausted
/// so later diagnostic segments cannot inspect additional source bytes.
#[must_use]
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct DiagnosticInputBudget {
/// Source bytes still available for inspection.
remaining_input_bytes: usize,
/// Whether a reservation has exhausted or exceeded the budget.
exhausted: bool,
}
impl DiagnosticInputBudget {
/// Creates input accounting from a validated maximum source-byte limit.
///
/// # Parameters
///
/// * `max_input_bytes` - Maximum source bytes available to the diagnostic.
///
/// # Returns
///
/// A budget with all bytes available for reservation.
#[inline(always)]
pub(crate) const fn new(max_input_bytes: usize) -> Self {
Self {
remaining_input_bytes: max_input_bytes,
exhausted: false,
}
}
/// Reserves source bytes before inspecting a diagnostic segment.
///
/// # Parameters
///
/// * `input_bytes` - Source-byte length that will be inspected.
///
/// # Returns
///
/// `true` when the full segment fits and may be inspected. `false` when
/// the segment must be skipped; this permanently exhausts the budget.
#[inline]
pub(crate) fn reserve(&mut self, input_bytes: usize) -> bool {
if self.exhausted || input_bytes > self.remaining_input_bytes {
self.remaining_input_bytes = 0;
self.exhausted = true;
return false;
}
self.remaining_input_bytes -= input_bytes;
self.exhausted = self.remaining_input_bytes == 0;
true
}
/// Returns source bytes still available before the next reservation.
///
/// # Returns
///
/// The remaining source-byte allowance, or zero after exhaustion.
#[must_use]
#[inline(always)]
pub(crate) const fn remaining_input_bytes(&self) -> usize {
self.remaining_input_bytes
}
}