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
// =============================================================================
// Copyright (c) 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! Atomically published output from one redaction batch.
use crate::RedactionHandle;
use crate::RedactionHandleError;
use crate::RedactionSummary;
use crate::RedactionTextOutput;
/// Final output published after a batch commits successfully.
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct BatchPublication {
/// Identity shared by every handle created before publication.
transaction_id: u64,
/// Independently resolvable final item outputs.
items: Vec<RedactionTextOutput>,
/// Aggregate accounting for the complete batch.
summary: RedactionSummary,
}
impl BatchPublication {
/// Creates output for the completed batch identity and staged items.
///
/// # Parameters
///
/// - `transaction_id`: Identity shared by this publication's handles.
/// - `items`: Final items in handle-index order.
/// - `summary`: Aggregate accounting for the completed batch.
///
/// # Returns
///
/// An immutable publication retaining all supplied items and accounting.
#[must_use]
#[inline(always)]
pub(crate) fn new(transaction_id: u64, items: Vec<RedactionTextOutput>, summary: RedactionSummary) -> Self {
Self {
transaction_id,
items,
summary,
}
}
/// Returns aggregate accounting across all published batch items.
///
/// # Returns
///
/// Aggregate accounting across the whole published batch.
#[must_use]
#[inline(always)]
pub(crate) const fn summary(&self) -> &RedactionSummary {
&self.summary
}
/// Borrows the item selected by `handle` without cloning its final text.
///
/// # Errors
///
/// Returns [`RedactionHandleError::DifferentTransaction`] for another
/// batch identity and [`RedactionHandleError::MissingItem`] for an invalid
/// index in this batch.
///
/// # Parameters
///
/// - `handle`: Runtime token issued for this batch.
///
/// # Returns
///
/// The matching published item borrowed from this output.
#[inline]
pub(crate) fn resolve(&self, handle: RedactionHandle) -> Result<&RedactionTextOutput, RedactionHandleError> {
if handle.transaction_id != self.transaction_id {
return Err(RedactionHandleError::DifferentTransaction);
}
self.items
.get(handle.item_index)
.ok_or(RedactionHandleError::MissingItem)
}
}