Skip to main content

liminal_protocol/lifecycle/admission/
record.rs

1use crate::algebra::{ResourceDimension, ResourceVector};
2use crate::wire::{RecordAdmissionEnvelope, RecordTooLarge};
3
4/// Successful static ordinary-record size preflight.
5///
6/// The exact encoded charge is carried forward so a later protocol operation
7/// does not need to recompute or substitute the value that passed stage 8.
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub struct RecordSizePermit {
10    encoded_record_charge: ResourceVector,
11}
12
13impl RecordSizePermit {
14    /// Returns the exact encoded charge that passed both component limits.
15    #[must_use]
16    pub const fn encoded_record_charge(self) -> ResourceVector {
17        self.encoded_record_charge
18    }
19}
20
21/// Static ordinary-record size decision in entry-before-byte order.
22#[derive(Clone, Debug, PartialEq, Eq)]
23pub enum RecordSizeDecision {
24    /// Both components fit and later admission stages may run.
25    Eligible(RecordSizePermit),
26    /// The first failing component and unchanged request data.
27    Respond(RecordTooLarge),
28}
29
30/// Applies the frozen stage-8 `RecordTooLarge` selector.
31///
32/// Entries are tested before bytes and equality passes. The function consumes
33/// the request envelope so the refusal cannot accidentally name another
34/// operation while the success permit retains the exact admitted charge.
35#[must_use]
36pub const fn check_record_size(
37    request: RecordAdmissionEnvelope,
38    encoded_record_charge: ResourceVector,
39    max_ordinary_record_charge: ResourceVector,
40) -> RecordSizeDecision {
41    if encoded_record_charge.entries > max_ordinary_record_charge.entries {
42        return RecordSizeDecision::Respond(RecordTooLarge {
43            request,
44            dimension: ResourceDimension::Entries,
45            encoded_record_charge,
46            max_ordinary_record_charge,
47        });
48    }
49    if encoded_record_charge.bytes > max_ordinary_record_charge.bytes {
50        return RecordSizeDecision::Respond(RecordTooLarge {
51            request,
52            dimension: ResourceDimension::Bytes,
53            encoded_record_charge,
54            max_ordinary_record_charge,
55        });
56    }
57    RecordSizeDecision::Eligible(RecordSizePermit {
58        encoded_record_charge,
59    })
60}