Skip to main content

liminal_protocol/wire/
request.rs

1use alloc::vec::Vec;
2
3use super::{
4    AttachAttemptToken, AttachSecret, ClientDiscriminant, ConversationId, DeliverySeq,
5    DetachAttemptToken, EnrollmentToken, Generation, LeaveAttemptToken, ObserverEpoch,
6    ParticipantId, RecordAdmissionAttemptToken,
7};
8
9/// Enrollment request body (`0x0001`).
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct EnrollmentRequest {
12    /// Conversation to enroll in.
13    pub conversation_id: ConversationId,
14    /// Durable single-purpose enrollment token.
15    pub enrollment_token: EnrollmentToken,
16}
17
18/// Credential-bearing attach request body (`0x0002`).
19#[derive(Clone, Debug, PartialEq, Eq)]
20pub struct CredentialAttachRequest {
21    /// Conversation containing the participant.
22    pub conversation_id: ConversationId,
23    /// Permanent participant identity.
24    pub participant_id: ParticipantId,
25    /// Presented nonzero credential generation.
26    pub capability_generation: Generation,
27    /// Presented attach secret.
28    pub attach_secret: AttachSecret,
29    /// Durable single-purpose attach token.
30    pub attach_attempt_token: AttachAttemptToken,
31    /// Marker accepted atomically by a fenced recovery attach.
32    pub accept_marker_delivery_seq: Option<DeliverySeq>,
33}
34
35/// Explicit detach request body (`0x0003`).
36#[derive(Clone, Debug, PartialEq, Eq)]
37pub struct DetachRequest {
38    /// Conversation containing the participant.
39    pub conversation_id: ConversationId,
40    /// Permanent participant identity.
41    pub participant_id: ParticipantId,
42    /// Presented nonzero credential generation.
43    pub capability_generation: Generation,
44    /// Durable single-purpose detach token.
45    pub detach_attempt_token: DetachAttemptToken,
46}
47
48/// Continuous cumulative acknowledgement body (`0x0004`).
49#[derive(Clone, Debug, PartialEq, Eq)]
50pub struct ParticipantAck {
51    /// Conversation containing the participant.
52    pub conversation_id: ConversationId,
53    /// Permanent participant identity.
54    pub participant_id: ParticipantId,
55    /// Presented nonzero credential generation.
56    pub capability_generation: Generation,
57    /// Greatest continuously available sequence being acknowledged.
58    pub through_seq: DeliverySeq,
59}
60
61/// Terminal participant Leave body (`0x0005`).
62#[derive(Clone, Debug, PartialEq, Eq)]
63pub struct LeaveRequest {
64    /// Conversation containing the participant.
65    pub conversation_id: ConversationId,
66    /// Permanent participant identity.
67    pub participant_id: ParticipantId,
68    /// Presented nonzero credential generation.
69    pub capability_generation: Generation,
70    /// Presented attach secret; it is never echoed in a response envelope.
71    pub attach_secret: AttachSecret,
72    /// Durable single-purpose Leave token.
73    pub leave_attempt_token: LeaveAttemptToken,
74}
75
76/// Explicit marker acknowledgement body (`0x0006`).
77#[derive(Clone, Debug, PartialEq, Eq)]
78pub struct MarkerAck {
79    /// Conversation containing the participant.
80    pub conversation_id: ConversationId,
81    /// Permanent participant identity.
82    pub participant_id: ParticipantId,
83    /// Presented nonzero credential generation.
84    pub capability_generation: Generation,
85    /// Delivered marker being accepted.
86    pub marker_delivery_seq: DeliverySeq,
87}
88
89/// Ordinary record-admission body (`0x0007`).
90#[derive(Clone, Debug, PartialEq, Eq)]
91pub struct RecordAdmission {
92    /// Conversation receiving the record.
93    pub conversation_id: ConversationId,
94    /// Verified sender participant.
95    pub participant_id: ParticipantId,
96    /// Presented nonzero credential generation.
97    pub capability_generation: Generation,
98    /// Client-selected identity of this record-admission request attempt.
99    pub record_admission_attempt_token: RecordAdmissionAttemptToken,
100    /// Opaque application payload; it is never echoed in a response envelope.
101    pub payload: Vec<u8>,
102}
103
104/// One observer refusal supplied during reconnect recovery.
105#[derive(Clone, Copy, Debug, PartialEq, Eq)]
106pub struct ObserverRefusal {
107    /// Refused conversation.
108    pub conversation_id: ConversationId,
109    /// Refusal epoch the SDK needs to arm or classify.
110    pub refused_epoch: ObserverEpoch,
111}
112
113/// One-shot observer-recovery batch body (`0x0008`).
114#[derive(Clone, Debug, PartialEq, Eq)]
115pub struct ObserverRecoveryHandshake {
116    /// Request-ordered refusal list. Its wire count is the special `u64` count.
117    pub observer_refusals: Vec<ObserverRefusal>,
118}
119
120/// Exhaustive client-to-server participant request.
121#[derive(Clone, Debug, PartialEq, Eq)]
122pub enum ClientRequest {
123    /// `0x0001` enrollment request.
124    Enrollment(EnrollmentRequest),
125    /// `0x0002` credential attach request.
126    CredentialAttach(CredentialAttachRequest),
127    /// `0x0003` explicit detach request.
128    Detach(DetachRequest),
129    /// `0x0004` continuous acknowledgement.
130    ParticipantAck(ParticipantAck),
131    /// `0x0005` terminal Leave request.
132    Leave(LeaveRequest),
133    /// `0x0006` marker acknowledgement.
134    MarkerAck(MarkerAck),
135    /// `0x0007` ordinary record admission.
136    RecordAdmission(RecordAdmission),
137    /// `0x0008` reconnect recovery batch.
138    ObserverRecovery(ObserverRecoveryHandshake),
139}
140
141impl ClientRequest {
142    /// Returns the stable request discriminant.
143    #[must_use]
144    pub const fn discriminant(&self) -> ClientDiscriminant {
145        match self {
146            Self::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
147            Self::CredentialAttach(_) => ClientDiscriminant::CredentialAttachRequest,
148            Self::Detach(_) => ClientDiscriminant::DetachRequest,
149            Self::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
150            Self::Leave(_) => ClientDiscriminant::LeaveRequest,
151            Self::MarkerAck(_) => ClientDiscriminant::MarkerAck,
152            Self::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
153            Self::ObserverRecovery(_) => ClientDiscriminant::ObserverRecoveryHandshake,
154        }
155    }
156}