Skip to main content

liminal/durability/
receipt.rs

1use std::fmt;
2
3/// Opaque processing outcome supplied by a consumer for dedup completion.
4#[derive(Clone, PartialEq, Eq)]
5pub struct ProcessingReceipt(Vec<u8>);
6
7impl ProcessingReceipt {
8    /// Wraps consumer-defined receipt bytes without interpretation.
9    #[must_use]
10    pub const fn new(bytes: Vec<u8>) -> Self {
11        Self(bytes)
12    }
13
14    /// Returns the opaque receipt bytes.
15    #[must_use]
16    pub fn as_bytes(&self) -> &[u8] {
17        &self.0
18    }
19
20    /// Consumes the receipt and returns its opaque bytes.
21    #[must_use]
22    pub fn into_bytes(self) -> Vec<u8> {
23        self.0
24    }
25}
26
27impl fmt::Debug for ProcessingReceipt {
28    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
29        write!(formatter, "ProcessingReceipt({} bytes)", self.0.len())
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::ProcessingReceipt;
36
37    #[test]
38    fn receipt_debug_reports_length_not_contents() {
39        let receipt = ProcessingReceipt::new(b"secret receipt".to_vec());
40
41        let debug = format!("{receipt:?}");
42
43        assert_eq!(debug, "ProcessingReceipt(14 bytes)");
44        assert!(!debug.contains("secret"));
45    }
46
47    #[test]
48    fn receipts_compare_by_bytes() {
49        let left = ProcessingReceipt::new(vec![1, 2, 3]);
50        let right = ProcessingReceipt::new(vec![1, 2, 3]);
51
52        assert_eq!(left, right);
53    }
54}