1use alloc::{boxed::Box, string::String, vec::Vec};
2
3use crate::algebra::{ResourceDimension, ResourceVector};
4
5use super::{
6 AckGapReason, AckRegressionReason, AttachAttemptToken, AttachEnvelope, AttachSecret,
7 AttemptConflict, BindingEpoch, ClientDiscriminant, ClosureCheckedEnvelope, ConversationId,
8 Counter, DecodeClass, DeliverySeq, DetachAttemptToken, DetachEnvelope, EnrollmentEnvelope,
9 EnrollmentToken, Generation, IdentityCapacityScope, InvalidObserverEpochListReason,
10 InvalidObserverEpochReason, LeaveAttemptToken, LeaveEnvelope, MarkerAckEnvelope,
11 MarkerClosureCapacityExceeded, MarkerMismatchReason, MarkerNotDeliveredReason, ObserverEpoch,
12 ParticipantAckEnvelope, ParticipantId, ProtocolVersion, ReceiptCapacityScope,
13 ReceiptExpiryReason, RecordAdmissionAttemptToken, RecordAdmissionEnvelope,
14 RecordAdmissionFaultClassTag, ResponseEnvelope, SequenceBudget, ServerDiscriminant,
15 SettlementEpoch,
16};
17
18pub use super::tags::{DetachAuthorityStateTag, LeaveAuthorityStateTag, ResourceDimensionTag};
19
20#[derive(Clone, Debug, PartialEq, Eq)]
22pub struct ParticipantTransportRejected {
23 pub reason: TransportRejectionReason,
25}
26
27#[derive(Clone, Debug, PartialEq, Eq)]
29pub enum TransportRejectionReason {
30 FrameTooLarge {
32 complete_frame_bytes: u64,
34 max_frame_bytes: u64,
36 },
37 DecodeFailed {
39 decode_class: DecodeClass,
41 },
42 UnsupportedVersion {
44 presented_version: ProtocolVersion,
46 supported_version: ProtocolVersion,
48 },
49 AuthenticationFailed,
51 ParticipantCapabilityRequired,
56}
57
58#[derive(Clone, Debug, PartialEq, Eq)]
63pub enum AttemptTokenBodyConflict {
64 CredentialAttach {
66 token: AttachAttemptToken,
68 conversation_id: ConversationId,
70 presented_participant_id: ParticipantId,
72 presented_generation: Generation,
74 presented_marker_delivery_seq: Option<DeliverySeq>,
76 conflict: AttemptConflict,
78 },
79 Leave {
81 token: LeaveAttemptToken,
83 conversation_id: ConversationId,
85 presented_participant_id: ParticipantId,
87 presented_generation: Generation,
89 },
90 RecordAdmission {
100 token: RecordAdmissionAttemptToken,
102 conversation_id: ConversationId,
104 presented_participant_id: ParticipantId,
106 presented_generation: Generation,
108 },
109}
110
111#[derive(Clone, Debug, PartialEq, Eq)]
118pub enum ConnectionConversationCapacityExceeded {
119 SemanticRequest {
121 request: ResponseEnvelope,
123 limit: u64,
125 },
126 ObserverRecovery {
128 conversation_id: ConversationId,
130 limit: u64,
132 },
133}
134
135#[derive(Clone, Debug, PartialEq, Eq)]
137pub enum ConnectionConversationBindingOccupied {
138 Enrollment {
140 conversation_id: ConversationId,
142 enrollment_token: EnrollmentToken,
144 },
145 CredentialAttach {
147 conversation_id: ConversationId,
149 participant_id: ParticipantId,
151 capability_generation: Generation,
153 attach_attempt_token: AttachAttemptToken,
155 accept_marker_delivery_seq: Option<DeliverySeq>,
157 },
158}
159
160#[derive(Clone, Debug, PartialEq, Eq)]
162pub enum OrderAllocatingEnvelope {
163 Enrollment(EnrollmentEnvelope),
165 CredentialAttach(AttachEnvelope),
167 RecordAdmission(RecordAdmissionEnvelope),
169}
170
171#[derive(Clone, Debug, PartialEq, Eq)]
173pub struct ConversationOrderExhausted {
174 request: OrderAllocatingEnvelope,
176 high: u64,
178 order_remaining: u128,
180 reserved_claims: u128,
182 resulting_order_remaining: u128,
184 resulting_reserved_claims: u128,
186}
187
188impl ConversationOrderExhausted {
189 pub const REQUIRED_MAJORS: u64 = 1;
191
192 #[must_use]
198 pub const fn new(
199 request: OrderAllocatingEnvelope,
200 high: u64,
201 order_remaining: u128,
202 reserved_claims: u128,
203 resulting_order_remaining: u128,
204 resulting_reserved_claims: u128,
205 ) -> Self {
206 Self {
207 request,
208 high,
209 order_remaining,
210 reserved_claims,
211 resulting_order_remaining,
212 resulting_reserved_claims,
213 }
214 }
215
216 #[must_use]
218 pub const fn request(&self) -> &OrderAllocatingEnvelope {
219 &self.request
220 }
221
222 #[must_use]
224 pub const fn counter(&self) -> Counter {
225 let _ = self;
226 Counter::TransactionOrder
227 }
228
229 #[must_use]
231 pub const fn high(&self) -> u64 {
232 self.high
233 }
234
235 #[must_use]
237 pub const fn next_value(&self) -> Option<u64> {
238 self.high.checked_add(1)
239 }
240
241 #[must_use]
243 pub const fn order_remaining(&self) -> u128 {
244 self.order_remaining
245 }
246
247 #[must_use]
249 pub const fn reserved_claims(&self) -> u128 {
250 self.reserved_claims
251 }
252
253 #[must_use]
255 pub const fn resulting_order_remaining(&self) -> u128 {
256 self.resulting_order_remaining
257 }
258
259 #[must_use]
261 pub const fn resulting_reserved_claims(&self) -> u128 {
262 self.resulting_reserved_claims
263 }
264}
265
266#[derive(Clone, Debug, PartialEq, Eq)]
268pub enum ParticipantReferenceEnvelope {
269 CredentialAttach(AttachEnvelope),
271 Detach(DetachEnvelope),
273 ParticipantAck(ParticipantAckEnvelope),
275 Leave(LeaveEnvelope),
277 MarkerAck(MarkerAckEnvelope),
279 RecordAdmission(RecordAdmissionEnvelope),
281}
282
283#[derive(Clone, Debug, PartialEq, Eq)]
285pub enum BindingRequiredEnvelope {
286 Detach(DetachEnvelope),
288 ParticipantAck(ParticipantAckEnvelope),
290 Leave(LeaveEnvelope),
292 MarkerAck(MarkerAckEnvelope),
294 RecordAdmission(RecordAdmissionEnvelope),
296}
297
298#[derive(Clone, Debug, PartialEq, Eq)]
300pub struct ParticipantUnknown {
301 pub request: ParticipantReferenceEnvelope,
303}
304
305#[derive(Clone, Debug, PartialEq, Eq)]
307pub struct NoBinding {
308 pub request: BindingRequiredEnvelope,
310}
311
312#[derive(Clone, Copy, Debug, PartialEq, Eq)]
314pub enum BindingStateView {
315 Bound {
317 current_binding_epoch: BindingEpoch,
319 },
320 Detached,
322}
323
324impl BindingStateView {
325 #[must_use]
327 pub const fn tag(self) -> super::BindingStateTag {
328 match self {
329 Self::Bound { .. } => super::BindingStateTag::Bound,
330 Self::Detached => super::BindingStateTag::Detached,
331 }
332 }
333}
334
335#[derive(Clone, Debug, PartialEq, Eq)]
340pub struct TerminalizedDetachCell {
341 conversation_id: ConversationId,
342 participant_id: ParticipantId,
343 capability_generation: Generation,
344 detach_attempt_token: DetachAttemptToken,
345 current_generation: Generation,
346 committed_binding_epoch: BindingEpoch,
347 binding_state: BindingStateView,
348}
349
350impl TerminalizedDetachCell {
351 pub(crate) const fn from_terminalized_state<V>(
359 state: &crate::lifecycle::TerminalizedDetach<V>,
360 conversation_id: ConversationId,
361 current_generation: Generation,
362 binding_state: BindingStateView,
363 ) -> Self {
364 Self {
365 conversation_id,
366 participant_id: state.participant_id(),
367 capability_generation: state.request_generation(),
368 detach_attempt_token: state.token(),
369 current_generation,
370 committed_binding_epoch: state.committed_binding_epoch(),
371 binding_state,
372 }
373 }
374
375 #[allow(clippy::too_many_arguments)]
382 pub(super) const fn from_wire_decode(
383 _authority: super::server_codec::TerminalizedWireDecodeAuthority,
384 conversation_id: ConversationId,
385 participant_id: ParticipantId,
386 capability_generation: Generation,
387 detach_attempt_token: DetachAttemptToken,
388 current_generation: Generation,
389 committed_binding_epoch: BindingEpoch,
390 binding_state: BindingStateView,
391 ) -> Self {
392 Self {
393 conversation_id,
394 participant_id,
395 capability_generation,
396 detach_attempt_token,
397 current_generation,
398 committed_binding_epoch,
399 binding_state,
400 }
401 }
402
403 #[cfg(test)]
404 pub(crate) const fn for_client_test(
405 conversation_id: ConversationId,
406 participant_id: ParticipantId,
407 capability_generation: Generation,
408 detach_attempt_token: DetachAttemptToken,
409 current_generation: Generation,
410 committed_binding_epoch: BindingEpoch,
411 binding_state: BindingStateView,
412 ) -> Self {
413 Self {
414 conversation_id,
415 participant_id,
416 capability_generation,
417 detach_attempt_token,
418 current_generation,
419 committed_binding_epoch,
420 binding_state,
421 }
422 }
423
424 #[must_use]
426 pub const fn conversation_id(&self) -> ConversationId {
427 self.conversation_id
428 }
429
430 #[must_use]
432 pub const fn participant_id(&self) -> ParticipantId {
433 self.participant_id
434 }
435
436 #[must_use]
438 pub const fn capability_generation(&self) -> Generation {
439 self.capability_generation
440 }
441
442 #[must_use]
444 pub const fn detach_attempt_token(&self) -> DetachAttemptToken {
445 self.detach_attempt_token
446 }
447
448 #[must_use]
450 pub const fn current_generation(&self) -> Generation {
451 self.current_generation
452 }
453
454 #[must_use]
456 pub const fn committed_binding_epoch(&self) -> BindingEpoch {
457 self.committed_binding_epoch
458 }
459
460 #[must_use]
462 pub const fn binding_state(&self) -> BindingStateView {
463 self.binding_state
464 }
465}
466
467#[derive(Clone, Debug, PartialEq, Eq)]
469pub enum DetachStaleAuthority {
470 Live {
472 conversation_id: ConversationId,
474 participant_id: ParticipantId,
476 capability_generation: Generation,
478 detach_attempt_token: DetachAttemptToken,
480 current_generation: Generation,
482 },
483 TerminalizedDetachCell(TerminalizedDetachCell),
485}
486
487impl DetachStaleAuthority {
488 #[must_use]
490 pub const fn authority_state_tag(&self) -> DetachAuthorityStateTag {
491 match self {
492 Self::Live { .. } => DetachAuthorityStateTag::Live,
493 Self::TerminalizedDetachCell(_) => DetachAuthorityStateTag::TerminalizedDetachCell,
494 }
495 }
496}
497
498#[derive(Clone, Debug, PartialEq, Eq)]
500pub enum LeaveStaleAuthority {
501 Live {
503 conversation_id: ConversationId,
505 participant_id: ParticipantId,
507 presented_generation: Generation,
509 leave_attempt_token: LeaveAttemptToken,
511 current_generation: Generation,
513 },
514 CommittedLeaveTombstone {
516 conversation_id: ConversationId,
518 participant_id: ParticipantId,
520 presented_generation: Generation,
522 leave_attempt_token: LeaveAttemptToken,
524 retired_generation: Generation,
526 },
527}
528
529impl LeaveStaleAuthority {
530 #[must_use]
532 pub const fn authority_state_tag(&self) -> LeaveAuthorityStateTag {
533 match self {
534 Self::Live { .. } => LeaveAuthorityStateTag::Live,
535 Self::CommittedLeaveTombstone { .. } => LeaveAuthorityStateTag::CommittedLeaveTombstone,
536 }
537 }
538}
539
540#[derive(Clone, Debug, PartialEq, Eq)]
542pub enum CommonStaleAuthorityEnvelope {
543 CredentialAttach(AttachEnvelope),
545 ParticipantAck(ParticipantAckEnvelope),
547 MarkerAck(MarkerAckEnvelope),
549 RecordAdmission(RecordAdmissionEnvelope),
551}
552
553#[derive(Clone, Debug, PartialEq, Eq)]
555pub enum StaleAuthority {
556 Live {
558 request: CommonStaleAuthorityEnvelope,
560 current_generation: Generation,
562 },
563 Detach(DetachStaleAuthority),
565 Leave(LeaveStaleAuthority),
567}
568
569#[derive(Clone, Debug, PartialEq, Eq)]
571pub enum Retired {
572 Enrollment {
574 request: EnrollmentEnvelope,
576 participant_id: ParticipantId,
578 retired_generation: Generation,
580 },
581 Participant {
583 request: ParticipantReferenceEnvelope,
585 retired_generation: Generation,
587 },
588}
589
590#[derive(Clone, Debug, PartialEq, Eq)]
592pub struct EnrollBound {
593 conversation_id: ConversationId,
594 token: EnrollmentToken,
595 participant_id: ParticipantId,
596 attach_secret: AttachSecret,
597 origin_binding_epoch: BindingEpoch,
598 receipt_expires_at: u128,
599 provenance_expires_at: u128,
600}
601
602impl EnrollBound {
603 #[must_use]
610 pub const fn new(
611 conversation_id: ConversationId,
612 token: EnrollmentToken,
613 participant_id: ParticipantId,
614 attach_secret: AttachSecret,
615 origin_binding_epoch: BindingEpoch,
616 receipt_expires_at: u128,
617 provenance_expires_at: u128,
618 ) -> Option<Self> {
619 if origin_binding_epoch.capability_generation.get() == 1 {
620 Some(Self {
621 conversation_id,
622 token,
623 participant_id,
624 attach_secret,
625 origin_binding_epoch,
626 receipt_expires_at,
627 provenance_expires_at,
628 })
629 } else {
630 None
631 }
632 }
633
634 #[must_use]
636 pub const fn conversation_id(&self) -> ConversationId {
637 self.conversation_id
638 }
639
640 #[must_use]
642 pub const fn token(&self) -> EnrollmentToken {
643 self.token
644 }
645
646 #[must_use]
648 pub const fn participant_id(&self) -> ParticipantId {
649 self.participant_id
650 }
651
652 #[must_use]
654 pub const fn request_generation(&self) -> Option<Generation> {
655 None
656 }
657
658 #[must_use]
660 pub const fn capability_generation(&self) -> Generation {
661 self.origin_binding_epoch.capability_generation
662 }
663
664 #[must_use]
666 pub const fn attach_secret(&self) -> AttachSecret {
667 self.attach_secret
668 }
669
670 #[must_use]
672 pub const fn origin_binding_epoch(&self) -> BindingEpoch {
673 self.origin_binding_epoch
674 }
675
676 #[must_use]
678 pub const fn persisted_cursor(&self) -> DeliverySeq {
679 0
680 }
681
682 #[must_use]
684 pub const fn accepted_marker_delivery_seq(&self) -> Option<DeliverySeq> {
685 None
686 }
687
688 #[must_use]
690 pub const fn receipt_expires_at(&self) -> u128 {
691 self.receipt_expires_at
692 }
693
694 #[must_use]
696 pub const fn provenance_expires_at(&self) -> u128 {
697 self.provenance_expires_at
698 }
699}
700
701#[derive(Clone, Debug, PartialEq, Eq)]
703pub struct EnrollmentKnown {
704 pub conversation_id: ConversationId,
706 pub token: EnrollmentToken,
708 pub participant_id: ParticipantId,
710 pub current_generation: Generation,
712}
713
714#[derive(Clone, Debug, PartialEq, Eq)]
716pub enum ReceiptExpired {
717 Enrollment {
719 conversation_id: ConversationId,
721 token: EnrollmentToken,
723 participant_id: ParticipantId,
725 result_generation: Generation,
727 current_generation: Generation,
729 reason: ReceiptExpiryReason,
731 },
732 CredentialAttach {
734 conversation_id: ConversationId,
736 token: AttachAttemptToken,
738 participant_id: ParticipantId,
740 presented_generation: Generation,
742 presented_marker_delivery_seq: Option<DeliverySeq>,
744 result_generation: Generation,
746 current_generation: Generation,
748 reason: ReceiptExpiryReason,
750 },
751}
752
753#[derive(Clone, Copy, Debug, PartialEq, Eq)]
758pub enum EnrollmentReceiptCapacityScope {
759 LiveReceiptServer,
761 ProvenanceServer,
763 ProvenanceConversation,
765}
766
767impl EnrollmentReceiptCapacityScope {
768 #[must_use]
770 pub const fn wire_scope(self) -> ReceiptCapacityScope {
771 match self {
772 Self::LiveReceiptServer => ReceiptCapacityScope::LiveReceiptServer,
773 Self::ProvenanceServer => ReceiptCapacityScope::ProvenanceServer,
774 Self::ProvenanceConversation => ReceiptCapacityScope::ProvenanceConversation,
775 }
776 }
777}
778
779#[derive(Clone, Debug, PartialEq, Eq)]
781pub enum ReceiptCapacityExceeded {
782 Enrollment {
784 request: EnrollmentEnvelope,
786 scope: EnrollmentReceiptCapacityScope,
788 limit: u64,
790 occupied: u64,
792 },
793 CredentialAttach {
795 request: AttachEnvelope,
797 scope: ReceiptCapacityScope,
799 limit: u64,
801 occupied: u64,
803 },
804}
805
806impl ReceiptCapacityExceeded {
807 pub const REQUESTED: u64 = 1;
809}
810
811#[derive(Clone, Debug, PartialEq, Eq)]
813pub struct IdentityCapacityExceeded {
814 pub request: EnrollmentEnvelope,
816 pub scope: IdentityCapacityScope,
818 pub limit: u64,
820 pub occupied: u64,
822}
823
824impl IdentityCapacityExceeded {
825 pub const REQUESTED: u64 = 1;
827}
828
829#[derive(Clone, Copy, Debug, PartialEq, Eq)]
831pub struct ObserverBackpressureState {
832 backpressure_epoch: ObserverEpoch,
834 observer_progress: DeliverySeq,
836}
837
838impl ObserverBackpressureState {
839 #[must_use]
844 pub const fn initial(observer_progress: DeliverySeq) -> Self {
845 Self {
846 backpressure_epoch: observer_progress,
847 observer_progress,
848 }
849 }
850
851 #[must_use]
857 pub const fn replay(
858 backpressure_epoch: ObserverEpoch,
859 observer_progress: DeliverySeq,
860 ) -> Option<Self> {
861 if backpressure_epoch == observer_progress {
862 Some(Self {
863 backpressure_epoch,
864 observer_progress,
865 })
866 } else {
867 None
868 }
869 }
870
871 #[must_use]
873 pub const fn backpressure_epoch(self) -> ObserverEpoch {
874 self.backpressure_epoch
875 }
876
877 #[must_use]
879 pub const fn observer_progress(self) -> DeliverySeq {
880 self.observer_progress
881 }
882}
883
884#[derive(Clone, Debug, PartialEq, Eq)]
886pub enum ObserverBackpressure {
887 Enrollment {
889 request: EnrollmentEnvelope,
891 state: ObserverBackpressureState,
893 },
894 CredentialAttach {
896 request: AttachEnvelope,
898 state: ObserverBackpressureState,
900 },
901 Detach {
903 request: DetachEnvelope,
905 committed_binding_epoch: BindingEpoch,
907 state: ObserverBackpressureState,
909 },
910 Leave {
912 request: LeaveEnvelope,
914 state: ObserverBackpressureState,
916 prior_terminal_cell_exists: bool,
918 },
919 RecordAdmission {
921 request: RecordAdmissionEnvelope,
923 state: ObserverBackpressureState,
925 },
926}
927
928#[derive(Clone, Copy, Debug, PartialEq, Eq)]
942pub enum MarkerSettlementBackpressure {
943 CredentialAttach {
945 conversation_id: ConversationId,
947 refused_epoch: SettlementEpoch,
949 },
950 Detach {
952 conversation_id: ConversationId,
954 refused_epoch: SettlementEpoch,
956 },
957}
958
959#[derive(Clone, Copy, Debug, PartialEq, Eq)]
970pub struct EnrollmentSettlementBackpressure {
971 pub conversation_id: ConversationId,
973}
974
975#[derive(Clone, Copy, Debug, PartialEq, Eq)]
985pub enum RecordAdmissionFaultClass {
986 Projection,
988 Order,
990 Sequence,
992 RequiredCapacity,
994 RefusalInvariant,
996}
997
998impl RecordAdmissionFaultClass {
999 #[must_use]
1001 pub const fn tag(self) -> RecordAdmissionFaultClassTag {
1002 match self {
1003 Self::Projection => RecordAdmissionFaultClassTag::Projection,
1004 Self::Order => RecordAdmissionFaultClassTag::Order,
1005 Self::Sequence => RecordAdmissionFaultClassTag::Sequence,
1006 Self::RequiredCapacity => RecordAdmissionFaultClassTag::RequiredCapacity,
1007 Self::RefusalInvariant => RecordAdmissionFaultClassTag::RefusalInvariant,
1008 }
1009 }
1010}
1011
1012impl From<RecordAdmissionFaultClassTag> for RecordAdmissionFaultClass {
1013 fn from(tag: RecordAdmissionFaultClassTag) -> Self {
1014 match tag {
1015 RecordAdmissionFaultClassTag::Projection => Self::Projection,
1016 RecordAdmissionFaultClassTag::Order => Self::Order,
1017 RecordAdmissionFaultClassTag::Sequence => Self::Sequence,
1018 RecordAdmissionFaultClassTag::RequiredCapacity => Self::RequiredCapacity,
1019 RecordAdmissionFaultClassTag::RefusalInvariant => Self::RefusalInvariant,
1020 }
1021 }
1022}
1023
1024#[derive(Clone, Debug, PartialEq, Eq)]
1043pub struct RecordAdmissionProtocolFault {
1044 pub request: RecordAdmissionEnvelope,
1046 pub class: RecordAdmissionFaultClass,
1048}
1049
1050#[derive(Clone, Debug, PartialEq, Eq)]
1052pub enum SequenceAllocatingEnvelope {
1053 Enrollment(EnrollmentEnvelope),
1055 CredentialAttach(AttachEnvelope),
1057 RecordAdmission(RecordAdmissionEnvelope),
1059}
1060
1061#[derive(Clone, Debug, PartialEq, Eq)]
1063pub struct ConversationSequenceExhausted {
1064 pub request: SequenceAllocatingEnvelope,
1066 pub sequence_budget: SequenceBudget,
1068}
1069
1070#[derive(Clone, Debug, PartialEq, Eq)]
1072pub struct AttachBound {
1073 conversation_id: ConversationId,
1075 token: AttachAttemptToken,
1077 participant_id: ParticipantId,
1079 request_generation: Generation,
1081 attach_secret: AttachSecret,
1083 origin_binding_epoch: BindingEpoch,
1085 persisted_cursor: DeliverySeq,
1087 accepted_marker_delivery_seq: Option<DeliverySeq>,
1089 receipt_expires_at: u128,
1091 provenance_expires_at: u128,
1093}
1094
1095impl AttachBound {
1096 #[must_use]
1102 #[allow(clippy::too_many_arguments)]
1103 pub const fn ordinary(
1104 conversation_id: ConversationId,
1105 token: AttachAttemptToken,
1106 participant_id: ParticipantId,
1107 request_generation: Generation,
1108 attach_secret: AttachSecret,
1109 origin_binding_epoch: BindingEpoch,
1110 persisted_cursor: DeliverySeq,
1111 receipt_expires_at: u128,
1112 provenance_expires_at: u128,
1113 ) -> Option<Self> {
1114 if !is_successor_generation(
1115 request_generation,
1116 origin_binding_epoch.capability_generation,
1117 ) {
1118 return None;
1119 }
1120 Some(Self {
1121 conversation_id,
1122 token,
1123 participant_id,
1124 request_generation,
1125 attach_secret,
1126 origin_binding_epoch,
1127 persisted_cursor,
1128 accepted_marker_delivery_seq: None,
1129 receipt_expires_at,
1130 provenance_expires_at,
1131 })
1132 }
1133
1134 #[must_use]
1140 #[allow(clippy::too_many_arguments)]
1141 pub const fn fenced(
1142 conversation_id: ConversationId,
1143 token: AttachAttemptToken,
1144 participant_id: ParticipantId,
1145 request_generation: Generation,
1146 attach_secret: AttachSecret,
1147 origin_binding_epoch: BindingEpoch,
1148 accepted_marker_delivery_seq: DeliverySeq,
1149 receipt_expires_at: u128,
1150 provenance_expires_at: u128,
1151 ) -> Option<Self> {
1152 if !is_successor_generation(
1153 request_generation,
1154 origin_binding_epoch.capability_generation,
1155 ) {
1156 return None;
1157 }
1158 Some(Self {
1159 conversation_id,
1160 token,
1161 participant_id,
1162 request_generation,
1163 attach_secret,
1164 origin_binding_epoch,
1165 persisted_cursor: accepted_marker_delivery_seq,
1166 accepted_marker_delivery_seq: Some(accepted_marker_delivery_seq),
1167 receipt_expires_at,
1168 provenance_expires_at,
1169 })
1170 }
1171
1172 #[must_use]
1174 pub const fn conversation_id(&self) -> ConversationId {
1175 self.conversation_id
1176 }
1177
1178 #[must_use]
1180 pub const fn token(&self) -> AttachAttemptToken {
1181 self.token
1182 }
1183
1184 #[must_use]
1186 pub const fn participant_id(&self) -> ParticipantId {
1187 self.participant_id
1188 }
1189
1190 #[must_use]
1192 pub const fn request_generation(&self) -> Generation {
1193 self.request_generation
1194 }
1195
1196 #[must_use]
1198 pub const fn capability_generation(&self) -> Generation {
1199 self.origin_binding_epoch.capability_generation
1200 }
1201
1202 #[must_use]
1204 pub const fn attach_secret(&self) -> AttachSecret {
1205 self.attach_secret
1206 }
1207
1208 #[must_use]
1210 pub const fn origin_binding_epoch(&self) -> BindingEpoch {
1211 self.origin_binding_epoch
1212 }
1213
1214 #[must_use]
1216 pub const fn persisted_cursor(&self) -> DeliverySeq {
1217 self.persisted_cursor
1218 }
1219
1220 #[must_use]
1222 pub const fn accepted_marker_delivery_seq(&self) -> Option<DeliverySeq> {
1223 self.accepted_marker_delivery_seq
1224 }
1225
1226 #[must_use]
1228 pub const fn receipt_expires_at(&self) -> u128 {
1229 self.receipt_expires_at
1230 }
1231
1232 #[must_use]
1234 pub const fn provenance_expires_at(&self) -> u128 {
1235 self.provenance_expires_at
1236 }
1237}
1238
1239const fn is_successor_generation(previous: Generation, successor: Generation) -> bool {
1240 match previous.get().checked_add(1) {
1241 Some(expected) => successor.get() == expected,
1242 None => false,
1243 }
1244}
1245
1246#[derive(Clone, Debug, PartialEq, Eq)]
1248pub struct StaleOrUnknownReceipt {
1249 pub conversation_id: ConversationId,
1251 pub token: AttachAttemptToken,
1253 pub participant_id: ParticipantId,
1255 pub presented_generation: Generation,
1257 pub presented_marker_delivery_seq: Option<DeliverySeq>,
1259 pub current_generation: Generation,
1261}
1262
1263#[derive(Clone, Debug, PartialEq, Eq)]
1265pub struct AttachMarkerProof {
1266 pub conversation_id: ConversationId,
1268 pub token: AttachAttemptToken,
1270 pub participant_id: ParticipantId,
1272 pub capability_generation: Generation,
1274 pub requested_marker_delivery_seq: DeliverySeq,
1276}
1277
1278#[derive(Clone, Debug, PartialEq, Eq)]
1280pub struct MarkerAckProof {
1281 pub conversation_id: ConversationId,
1283 pub participant_id: ParticipantId,
1285 pub capability_generation: Generation,
1287 pub requested_marker_delivery_seq: DeliverySeq,
1289}
1290
1291#[derive(Clone, Debug, PartialEq, Eq)]
1293pub enum MarkerProofRequest {
1294 CredentialAttach(AttachMarkerProof),
1296 MarkerAck(MarkerAckProof),
1298}
1299
1300#[derive(Clone, Debug, PartialEq, Eq)]
1302pub struct MarkerNotDelivered {
1303 pub request: MarkerProofRequest,
1305 pub reason: MarkerNotDeliveredReason,
1307 pub expected_marker_delivery_seq: DeliverySeq,
1309}
1310
1311#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1313pub enum MarkerMismatchBody {
1314 BelowCursor {
1316 current_cursor: DeliverySeq,
1318 },
1319 NoMarkerExpected,
1321 ExpectedDifferentMarker {
1323 expected_marker_delivery_seq: DeliverySeq,
1325 },
1326}
1327
1328impl MarkerMismatchBody {
1329 #[must_use]
1331 pub const fn reason(self) -> MarkerMismatchReason {
1332 match self {
1333 Self::BelowCursor { .. } => MarkerMismatchReason::BelowCursor,
1334 Self::NoMarkerExpected => MarkerMismatchReason::NoMarkerExpected,
1335 Self::ExpectedDifferentMarker { .. } => MarkerMismatchReason::ExpectedDifferentMarker,
1336 }
1337 }
1338}
1339
1340#[derive(Clone, Debug, PartialEq, Eq)]
1342pub struct MarkerMismatch {
1343 pub request: MarkerProofRequest,
1345 pub mismatch: MarkerMismatchBody,
1347}
1348
1349#[derive(Clone, Debug, PartialEq, Eq)]
1351pub enum ReceiptReplay {
1352 Enrollment(EnrollBound),
1355 CredentialAttach(AttachBound),
1358}
1359
1360#[derive(Clone, Debug, PartialEq, Eq)]
1362pub struct DetachCommitted {
1363 conversation_id: ConversationId,
1365 participant_id: ParticipantId,
1367 detach_attempt_token: DetachAttemptToken,
1369 committed_binding_epoch: BindingEpoch,
1371 detached_delivery_seq: DeliverySeq,
1373}
1374
1375impl DetachCommitted {
1376 #[must_use]
1379 pub const fn new(
1380 conversation_id: ConversationId,
1381 participant_id: ParticipantId,
1382 detach_attempt_token: DetachAttemptToken,
1383 committed_binding_epoch: BindingEpoch,
1384 detached_delivery_seq: DeliverySeq,
1385 ) -> Self {
1386 Self {
1387 conversation_id,
1388 participant_id,
1389 detach_attempt_token,
1390 committed_binding_epoch,
1391 detached_delivery_seq,
1392 }
1393 }
1394
1395 #[must_use]
1397 pub const fn conversation_id(&self) -> ConversationId {
1398 self.conversation_id
1399 }
1400
1401 #[must_use]
1403 pub const fn participant_id(&self) -> ParticipantId {
1404 self.participant_id
1405 }
1406
1407 #[must_use]
1409 pub const fn capability_generation(&self) -> Generation {
1410 self.committed_binding_epoch.capability_generation
1411 }
1412
1413 #[must_use]
1415 pub const fn detach_attempt_token(&self) -> DetachAttemptToken {
1416 self.detach_attempt_token
1417 }
1418
1419 #[must_use]
1421 pub const fn committed_binding_epoch(&self) -> BindingEpoch {
1422 self.committed_binding_epoch
1423 }
1424
1425 #[must_use]
1427 pub const fn detached_delivery_seq(&self) -> DeliverySeq {
1428 self.detached_delivery_seq
1429 }
1430}
1431
1432#[derive(Clone, Debug, PartialEq, Eq)]
1434pub struct DetachInProgress {
1435 pub conversation_id: ConversationId,
1437 pub participant_id: ParticipantId,
1439 pub presented_token: DetachAttemptToken,
1441 pub presented_generation: Generation,
1443 pub committed_binding_epoch: BindingEpoch,
1445}
1446
1447#[derive(Clone, Debug, PartialEq, Eq)]
1449pub struct AckCommitted {
1450 request: ParticipantAckEnvelope,
1452}
1453
1454impl AckCommitted {
1455 #[must_use]
1458 pub const fn new(request: ParticipantAckEnvelope) -> Self {
1459 Self { request }
1460 }
1461
1462 #[must_use]
1464 pub const fn request(&self) -> &ParticipantAckEnvelope {
1465 &self.request
1466 }
1467
1468 #[must_use]
1470 pub const fn current_cursor(&self) -> DeliverySeq {
1471 self.request.through_seq
1472 }
1473}
1474
1475#[derive(Clone, Debug, PartialEq, Eq)]
1477pub enum AckNoOp {
1478 ParticipantAck(ParticipantAckEnvelope),
1480 MarkerAck(MarkerAckEnvelope),
1482}
1483
1484impl AckNoOp {
1485 #[must_use]
1488 pub const fn participant_ack(request: ParticipantAckEnvelope) -> Self {
1489 Self::ParticipantAck(request)
1490 }
1491
1492 #[must_use]
1495 pub const fn marker_ack(request: MarkerAckEnvelope) -> Self {
1496 Self::MarkerAck(request)
1497 }
1498
1499 #[must_use]
1501 pub const fn current_cursor(&self) -> DeliverySeq {
1502 match self {
1503 Self::ParticipantAck(request) => request.through_seq,
1504 Self::MarkerAck(request) => request.marker_delivery_seq,
1505 }
1506 }
1507}
1508
1509#[derive(Clone, Debug, PartialEq, Eq)]
1511pub struct AckGap {
1512 request: ParticipantAckEnvelope,
1514 current_cursor: DeliverySeq,
1516}
1517
1518impl AckGap {
1519 #[must_use]
1522 pub const fn new(request: ParticipantAckEnvelope, current_cursor: DeliverySeq) -> Option<Self> {
1523 if request.through_seq > current_cursor {
1524 Some(Self {
1525 request,
1526 current_cursor,
1527 })
1528 } else {
1529 None
1530 }
1531 }
1532
1533 #[must_use]
1535 pub const fn request(&self) -> &ParticipantAckEnvelope {
1536 &self.request
1537 }
1538
1539 #[must_use]
1541 pub const fn current_cursor(&self) -> DeliverySeq {
1542 self.current_cursor
1543 }
1544
1545 #[must_use]
1547 pub const fn reason(&self) -> AckGapReason {
1548 let _ = self;
1549 AckGapReason::NotContiguouslyAvailable
1550 }
1551}
1552
1553#[derive(Clone, Debug, PartialEq, Eq)]
1555pub struct AckRegression {
1556 request: ParticipantAckEnvelope,
1558 current_cursor: DeliverySeq,
1560}
1561
1562impl AckRegression {
1563 #[must_use]
1566 pub const fn new(request: ParticipantAckEnvelope, current_cursor: DeliverySeq) -> Option<Self> {
1567 if request.through_seq < current_cursor {
1568 Some(Self {
1569 request,
1570 current_cursor,
1571 })
1572 } else {
1573 None
1574 }
1575 }
1576
1577 #[must_use]
1579 pub const fn request(&self) -> &ParticipantAckEnvelope {
1580 &self.request
1581 }
1582
1583 #[must_use]
1585 pub const fn current_cursor(&self) -> DeliverySeq {
1586 self.current_cursor
1587 }
1588
1589 #[must_use]
1591 pub const fn reason(&self) -> AckRegressionReason {
1592 let _ = self;
1593 AckRegressionReason::BelowCursor
1594 }
1595}
1596
1597#[derive(Clone, Debug, PartialEq, Eq)]
1599pub struct LeaveCommitted {
1600 conversation_id: ConversationId,
1602 leave_attempt_token: LeaveAttemptToken,
1604 participant_id: ParticipantId,
1606 retired_generation: Generation,
1608 ended_binding_epoch: Option<BindingEpoch>,
1610 prior_terminal_delivery_seq: Option<DeliverySeq>,
1612 left_delivery_seq: DeliverySeq,
1614}
1615
1616impl LeaveCommitted {
1617 #[must_use]
1623 #[allow(clippy::too_many_arguments)]
1624 pub const fn new(
1625 conversation_id: ConversationId,
1626 leave_attempt_token: LeaveAttemptToken,
1627 participant_id: ParticipantId,
1628 retired_generation: Generation,
1629 ended_binding_epoch: Option<BindingEpoch>,
1630 prior_terminal_delivery_seq: Option<DeliverySeq>,
1631 left_delivery_seq: DeliverySeq,
1632 ) -> Option<Self> {
1633 if let Some(epoch) = ended_binding_epoch
1634 && epoch.capability_generation.get() != retired_generation.get()
1635 {
1636 return None;
1637 }
1638 if let Some(prior) = prior_terminal_delivery_seq
1639 && prior >= left_delivery_seq
1640 {
1641 return None;
1642 }
1643 Some(Self {
1644 conversation_id,
1645 leave_attempt_token,
1646 participant_id,
1647 retired_generation,
1648 ended_binding_epoch,
1649 prior_terminal_delivery_seq,
1650 left_delivery_seq,
1651 })
1652 }
1653
1654 #[must_use]
1656 pub const fn conversation_id(&self) -> ConversationId {
1657 self.conversation_id
1658 }
1659
1660 #[must_use]
1662 pub const fn leave_attempt_token(&self) -> LeaveAttemptToken {
1663 self.leave_attempt_token
1664 }
1665
1666 #[must_use]
1668 pub const fn participant_id(&self) -> ParticipantId {
1669 self.participant_id
1670 }
1671
1672 #[must_use]
1674 pub const fn presented_generation(&self) -> Generation {
1675 self.retired_generation
1676 }
1677
1678 #[must_use]
1680 pub const fn retired_generation(&self) -> Generation {
1681 self.retired_generation
1682 }
1683
1684 #[must_use]
1686 pub const fn ended_binding_epoch(&self) -> Option<BindingEpoch> {
1687 self.ended_binding_epoch
1688 }
1689
1690 #[must_use]
1692 pub const fn prior_terminal_delivery_seq(&self) -> Option<DeliverySeq> {
1693 self.prior_terminal_delivery_seq
1694 }
1695
1696 #[must_use]
1698 pub const fn left_delivery_seq(&self) -> DeliverySeq {
1699 self.left_delivery_seq
1700 }
1701}
1702
1703#[derive(Clone, Debug, PartialEq, Eq)]
1705pub struct MarkerAckCommitted {
1706 request: MarkerAckEnvelope,
1708}
1709
1710impl MarkerAckCommitted {
1711 #[must_use]
1714 pub const fn new(request: MarkerAckEnvelope) -> Self {
1715 Self { request }
1716 }
1717
1718 #[must_use]
1720 pub const fn request(&self) -> &MarkerAckEnvelope {
1721 &self.request
1722 }
1723
1724 #[must_use]
1726 pub const fn current_cursor(&self) -> DeliverySeq {
1727 self.request.marker_delivery_seq
1728 }
1729}
1730
1731#[derive(Clone, Debug, PartialEq, Eq)]
1733pub struct RecordCommitted {
1734 request: RecordAdmissionEnvelope,
1736 delivery_seq: DeliverySeq,
1738}
1739
1740impl RecordCommitted {
1741 #[must_use]
1744 pub const fn new(request: RecordAdmissionEnvelope, delivery_seq: DeliverySeq) -> Self {
1745 Self {
1746 request,
1747 delivery_seq,
1748 }
1749 }
1750
1751 #[must_use]
1753 pub const fn request(&self) -> &RecordAdmissionEnvelope {
1754 &self.request
1755 }
1756
1757 #[must_use]
1759 pub const fn sender_participant_id(&self) -> ParticipantId {
1760 self.request.participant_id
1761 }
1762
1763 #[must_use]
1765 pub const fn delivery_seq(&self) -> DeliverySeq {
1766 self.delivery_seq
1767 }
1768}
1769
1770#[derive(Clone, Debug, PartialEq, Eq)]
1772pub struct RecordTooLarge {
1773 pub request: RecordAdmissionEnvelope,
1775 pub dimension: ResourceDimension,
1777 pub encoded_record_charge: ResourceVector,
1779 pub max_ordinary_record_charge: ResourceVector,
1781}
1782
1783#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1785pub struct ObserverProgressStatus {
1786 pub conversation_id: ConversationId,
1788 pub refused_epoch: ObserverEpoch,
1790 pub current_observer_progress: DeliverySeq,
1792 pub armed: bool,
1794 pub progressed: bool,
1796}
1797
1798#[derive(Clone, Debug, PartialEq, Eq)]
1800pub struct ObserverRecoveryAccepted {
1801 pub statuses: Vec<ObserverProgressStatus>,
1803}
1804
1805#[derive(Clone, Debug, PartialEq, Eq)]
1807pub enum InvalidObserverEpoch {
1808 ConversationUnknown {
1810 conversation_id: ConversationId,
1812 presented_epoch: ObserverEpoch,
1814 },
1815 EpochAhead {
1817 conversation_id: ConversationId,
1819 presented_epoch: ObserverEpoch,
1821 current_observer_progress: DeliverySeq,
1823 },
1824}
1825
1826impl InvalidObserverEpoch {
1827 #[must_use]
1829 pub const fn reason(&self) -> InvalidObserverEpochReason {
1830 match self {
1831 Self::ConversationUnknown { .. } => InvalidObserverEpochReason::ConversationUnknown,
1832 Self::EpochAhead { .. } => InvalidObserverEpochReason::EpochAhead,
1833 }
1834 }
1835}
1836
1837#[derive(Clone, Debug, PartialEq, Eq)]
1839pub enum InvalidObserverEpochList {
1840 TooManyEntries {
1842 presented_entries: u64,
1844 max_entries: u64,
1846 },
1847 DuplicateConversation {
1849 conversation_id: ConversationId,
1851 first_index: u64,
1853 duplicate_index: u64,
1855 },
1856}
1857
1858impl InvalidObserverEpochList {
1859 #[must_use]
1861 pub const fn reason(&self) -> InvalidObserverEpochListReason {
1862 match self {
1863 Self::TooManyEntries { .. } => InvalidObserverEpochListReason::TooManyEntries,
1864 Self::DuplicateConversation { .. } => {
1865 InvalidObserverEpochListReason::DuplicateConversation
1866 }
1867 }
1868 }
1869}
1870
1871#[derive(Clone, Debug, PartialEq, Eq)]
1873pub enum ServerValue {
1874 ParticipantTransportRejected(ParticipantTransportRejected),
1876 AttemptTokenBodyConflict(AttemptTokenBodyConflict),
1878 ConnectionConversationCapacityExceeded(ConnectionConversationCapacityExceeded),
1880 ConnectionConversationBindingOccupied(ConnectionConversationBindingOccupied),
1882 ConversationOrderExhausted(Box<ConversationOrderExhausted>),
1884 ParticipantUnknown(ParticipantUnknown),
1886 NoBinding(NoBinding),
1888 StaleAuthority(StaleAuthority),
1890 Retired(Retired),
1892 MarkerClosureCapacityExceeded(Box<MarkerClosureCapacityExceeded>),
1894 EnrollBound(EnrollBound),
1896 EnrollmentKnown(EnrollmentKnown),
1898 ReceiptExpired(ReceiptExpired),
1900 ReceiptCapacityExceeded(ReceiptCapacityExceeded),
1902 IdentityCapacityExceeded(IdentityCapacityExceeded),
1904 ObserverBackpressure(ObserverBackpressure),
1906 ConversationSequenceExhausted(Box<ConversationSequenceExhausted>),
1908 AttachBound(AttachBound),
1910 StaleOrUnknownReceipt(StaleOrUnknownReceipt),
1912 MarkerNotDelivered(MarkerNotDelivered),
1914 MarkerMismatch(MarkerMismatch),
1916 Bound(ReceiptReplay),
1918 UnboundReceipt(ReceiptReplay),
1920 DetachCommitted(DetachCommitted),
1922 DetachInProgress(DetachInProgress),
1924 AckCommitted(AckCommitted),
1926 AckNoOp(AckNoOp),
1928 AckGap(AckGap),
1930 AckRegression(AckRegression),
1932 LeaveCommitted(LeaveCommitted),
1934 MarkerAckCommitted(MarkerAckCommitted),
1936 RecordCommitted(RecordCommitted),
1938 RecordTooLarge(RecordTooLarge),
1940 ObserverRecoveryAccepted(ObserverRecoveryAccepted),
1942 InvalidObserverEpoch(InvalidObserverEpoch),
1944 InvalidObserverEpochList(InvalidObserverEpochList),
1946 MarkerSettlementBackpressure(MarkerSettlementBackpressure),
1948 EnrollmentSettlementBackpressure(EnrollmentSettlementBackpressure),
1950 RecordAdmissionProtocolFault(RecordAdmissionProtocolFault),
1952}
1953
1954impl ServerValue {
1955 #[must_use]
1957 pub const fn discriminant(&self) -> ServerDiscriminant {
1958 match self {
1959 Self::ParticipantTransportRejected(_) => {
1960 ServerDiscriminant::ParticipantTransportRejected
1961 }
1962 Self::AttemptTokenBodyConflict(_) => ServerDiscriminant::AttemptTokenBodyConflict,
1963 Self::ConnectionConversationCapacityExceeded(value) => match value {
1964 ConnectionConversationCapacityExceeded::SemanticRequest { .. } => {
1965 ServerDiscriminant::ConnectionConversationCapacityExceeded
1966 }
1967 ConnectionConversationCapacityExceeded::ObserverRecovery { .. } => {
1968 ServerDiscriminant::ObserverRecoveryConnectionCapacityExceeded
1969 }
1970 },
1971 Self::ConnectionConversationBindingOccupied(_) => {
1972 ServerDiscriminant::ConnectionConversationBindingOccupied
1973 }
1974 Self::ConversationOrderExhausted(_) => ServerDiscriminant::ConversationOrderExhausted,
1975 Self::ParticipantUnknown(_) => ServerDiscriminant::ParticipantUnknown,
1976 Self::NoBinding(_) => ServerDiscriminant::NoBinding,
1977 Self::StaleAuthority(_) => ServerDiscriminant::StaleAuthority,
1978 Self::Retired(_) => ServerDiscriminant::Retired,
1979 Self::MarkerClosureCapacityExceeded(_) => {
1980 ServerDiscriminant::MarkerClosureCapacityExceeded
1981 }
1982 Self::EnrollBound(_) => ServerDiscriminant::EnrollBound,
1983 Self::EnrollmentKnown(_) => ServerDiscriminant::EnrollmentKnown,
1984 Self::ReceiptExpired(_) => ServerDiscriminant::ReceiptExpired,
1985 Self::ReceiptCapacityExceeded(_) => ServerDiscriminant::ReceiptCapacityExceeded,
1986 Self::IdentityCapacityExceeded(_) => ServerDiscriminant::IdentityCapacityExceeded,
1987 Self::ObserverBackpressure(_) => ServerDiscriminant::ObserverBackpressure,
1988 Self::ConversationSequenceExhausted(_) => {
1989 ServerDiscriminant::ConversationSequenceExhausted
1990 }
1991 Self::AttachBound(_) => ServerDiscriminant::AttachBound,
1992 Self::StaleOrUnknownReceipt(_) => ServerDiscriminant::StaleOrUnknownReceipt,
1993 Self::MarkerNotDelivered(_) => ServerDiscriminant::MarkerNotDelivered,
1994 Self::MarkerMismatch(_) => ServerDiscriminant::MarkerMismatch,
1995 Self::Bound(_) => ServerDiscriminant::Bound,
1996 Self::UnboundReceipt(_) => ServerDiscriminant::UnboundReceipt,
1997 Self::DetachCommitted(_) => ServerDiscriminant::DetachCommitted,
1998 Self::DetachInProgress(_) => ServerDiscriminant::DetachInProgress,
1999 Self::AckCommitted(_) => ServerDiscriminant::AckCommitted,
2000 Self::AckNoOp(_) => ServerDiscriminant::AckNoOp,
2001 Self::AckGap(_) => ServerDiscriminant::AckGap,
2002 Self::AckRegression(_) => ServerDiscriminant::AckRegression,
2003 Self::LeaveCommitted(_) => ServerDiscriminant::LeaveCommitted,
2004 Self::MarkerAckCommitted(_) => ServerDiscriminant::MarkerAckCommitted,
2005 Self::RecordCommitted(_) => ServerDiscriminant::RecordCommitted,
2006 Self::RecordTooLarge(_) => ServerDiscriminant::RecordTooLarge,
2007 Self::ObserverRecoveryAccepted(_) => ServerDiscriminant::ObserverRecoveryAccepted,
2008 Self::InvalidObserverEpoch(_) => ServerDiscriminant::InvalidObserverEpoch,
2009 Self::InvalidObserverEpochList(_) => ServerDiscriminant::InvalidObserverEpochList,
2010 Self::MarkerSettlementBackpressure(_) => {
2011 ServerDiscriminant::MarkerSettlementBackpressure
2012 }
2013 Self::EnrollmentSettlementBackpressure(_) => {
2014 ServerDiscriminant::EnrollmentSettlementBackpressure
2015 }
2016 Self::RecordAdmissionProtocolFault(_) => {
2017 ServerDiscriminant::RecordAdmissionProtocolFault
2018 }
2019 }
2020 }
2021
2022 #[must_use]
2024 #[allow(clippy::too_many_lines)]
2025 pub const fn originating_request(&self) -> Option<ClientDiscriminant> {
2026 match self {
2027 Self::ParticipantTransportRejected(_)
2028 | Self::ObserverRecoveryAccepted(_)
2029 | Self::InvalidObserverEpoch(_)
2030 | Self::InvalidObserverEpochList(_) => None,
2031 Self::AttemptTokenBodyConflict(value) => Some(match value {
2032 AttemptTokenBodyConflict::CredentialAttach { .. } => {
2033 ClientDiscriminant::CredentialAttachRequest
2034 }
2035 AttemptTokenBodyConflict::Leave { .. } => ClientDiscriminant::LeaveRequest,
2036 AttemptTokenBodyConflict::RecordAdmission { .. } => {
2037 ClientDiscriminant::RecordAdmission
2038 }
2039 }),
2040 Self::ConnectionConversationCapacityExceeded(value) => match value {
2041 ConnectionConversationCapacityExceeded::SemanticRequest { request, .. } => {
2042 Some(request.originating_request())
2043 }
2044 ConnectionConversationCapacityExceeded::ObserverRecovery { .. } => None,
2045 },
2046 Self::ConnectionConversationBindingOccupied(value) => Some(match value {
2047 ConnectionConversationBindingOccupied::Enrollment { .. } => {
2048 ClientDiscriminant::EnrollmentRequest
2049 }
2050 ConnectionConversationBindingOccupied::CredentialAttach { .. } => {
2051 ClientDiscriminant::CredentialAttachRequest
2052 }
2053 }),
2054 Self::ConversationOrderExhausted(value) => Some(match value.request() {
2055 OrderAllocatingEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2056 OrderAllocatingEnvelope::CredentialAttach(_) => {
2057 ClientDiscriminant::CredentialAttachRequest
2058 }
2059 OrderAllocatingEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2060 }),
2061 Self::ParticipantUnknown(value) => Some(participant_reference_origin(&value.request)),
2062 Self::NoBinding(value) => Some(binding_required_origin(&value.request)),
2063 Self::StaleAuthority(value) => Some(stale_authority_origin(value)),
2064 Self::Retired(value) => Some(match value {
2065 Retired::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2066 Retired::Participant { request, .. } => participant_reference_origin(request),
2067 }),
2068 Self::MarkerClosureCapacityExceeded(value) => Some(match &value.request {
2069 ClosureCheckedEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2070 ClosureCheckedEnvelope::CredentialAttach(_) => {
2071 ClientDiscriminant::CredentialAttachRequest
2072 }
2073 ClosureCheckedEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
2074 ClosureCheckedEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2075 }),
2076 Self::EnrollBound(_)
2077 | Self::EnrollmentKnown(_)
2078 | Self::IdentityCapacityExceeded(_)
2079 | Self::EnrollmentSettlementBackpressure(_) => {
2080 Some(ClientDiscriminant::EnrollmentRequest)
2081 }
2082 Self::ReceiptExpired(value) => Some(match value {
2083 ReceiptExpired::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2084 ReceiptExpired::CredentialAttach { .. } => {
2085 ClientDiscriminant::CredentialAttachRequest
2086 }
2087 }),
2088 Self::ReceiptCapacityExceeded(value) => Some(match value {
2089 ReceiptCapacityExceeded::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2090 ReceiptCapacityExceeded::CredentialAttach { .. } => {
2091 ClientDiscriminant::CredentialAttachRequest
2092 }
2093 }),
2094 Self::ObserverBackpressure(value) => Some(match value {
2095 ObserverBackpressure::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2096 ObserverBackpressure::CredentialAttach { .. } => {
2097 ClientDiscriminant::CredentialAttachRequest
2098 }
2099 ObserverBackpressure::Detach { .. } => ClientDiscriminant::DetachRequest,
2100 ObserverBackpressure::Leave { .. } => ClientDiscriminant::LeaveRequest,
2101 ObserverBackpressure::RecordAdmission { .. } => ClientDiscriminant::RecordAdmission,
2102 }),
2103 Self::ConversationSequenceExhausted(value) => Some(match &value.request {
2104 SequenceAllocatingEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2105 SequenceAllocatingEnvelope::CredentialAttach(_) => {
2106 ClientDiscriminant::CredentialAttachRequest
2107 }
2108 SequenceAllocatingEnvelope::RecordAdmission(_) => {
2109 ClientDiscriminant::RecordAdmission
2110 }
2111 }),
2112 Self::AttachBound(_) | Self::StaleOrUnknownReceipt(_) => {
2113 Some(ClientDiscriminant::CredentialAttachRequest)
2114 }
2115 Self::MarkerNotDelivered(value) => Some(marker_proof_origin(&value.request)),
2116 Self::MarkerMismatch(value) => Some(marker_proof_origin(&value.request)),
2117 Self::Bound(value) | Self::UnboundReceipt(value) => Some(match value {
2118 ReceiptReplay::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2119 ReceiptReplay::CredentialAttach(_) => ClientDiscriminant::CredentialAttachRequest,
2120 }),
2121 Self::DetachCommitted(_) | Self::DetachInProgress(_) => {
2122 Some(ClientDiscriminant::DetachRequest)
2123 }
2124 Self::AckCommitted(_) | Self::AckGap(_) | Self::AckRegression(_) => {
2125 Some(ClientDiscriminant::ParticipantAck)
2126 }
2127 Self::AckNoOp(value) => Some(match value {
2128 AckNoOp::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2129 AckNoOp::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2130 }),
2131 Self::LeaveCommitted(_) => Some(ClientDiscriminant::LeaveRequest),
2132 Self::MarkerAckCommitted(_) => Some(ClientDiscriminant::MarkerAck),
2133 Self::RecordCommitted(_)
2134 | Self::RecordTooLarge(_)
2135 | Self::RecordAdmissionProtocolFault(_) => Some(ClientDiscriminant::RecordAdmission),
2136 Self::MarkerSettlementBackpressure(value) => Some(match value {
2137 MarkerSettlementBackpressure::CredentialAttach { .. } => {
2138 ClientDiscriminant::CredentialAttachRequest
2139 }
2140 MarkerSettlementBackpressure::Detach { .. } => ClientDiscriminant::DetachRequest,
2141 }),
2142 }
2143 }
2144}
2145
2146const fn participant_reference_origin(
2147 request: &ParticipantReferenceEnvelope,
2148) -> ClientDiscriminant {
2149 match request {
2150 ParticipantReferenceEnvelope::CredentialAttach(_) => {
2151 ClientDiscriminant::CredentialAttachRequest
2152 }
2153 ParticipantReferenceEnvelope::Detach(_) => ClientDiscriminant::DetachRequest,
2154 ParticipantReferenceEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2155 ParticipantReferenceEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
2156 ParticipantReferenceEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2157 ParticipantReferenceEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2158 }
2159}
2160
2161const fn binding_required_origin(request: &BindingRequiredEnvelope) -> ClientDiscriminant {
2162 match request {
2163 BindingRequiredEnvelope::Detach(_) => ClientDiscriminant::DetachRequest,
2164 BindingRequiredEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2165 BindingRequiredEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
2166 BindingRequiredEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2167 BindingRequiredEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2168 }
2169}
2170
2171const fn stale_authority_origin(value: &StaleAuthority) -> ClientDiscriminant {
2172 match value {
2173 StaleAuthority::Live { request, .. } => match request {
2174 CommonStaleAuthorityEnvelope::CredentialAttach(_) => {
2175 ClientDiscriminant::CredentialAttachRequest
2176 }
2177 CommonStaleAuthorityEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2178 CommonStaleAuthorityEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2179 CommonStaleAuthorityEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2180 },
2181 StaleAuthority::Detach(_) => ClientDiscriminant::DetachRequest,
2182 StaleAuthority::Leave(_) => ClientDiscriminant::LeaveRequest,
2183 }
2184}
2185
2186const fn marker_proof_origin(request: &MarkerProofRequest) -> ClientDiscriminant {
2187 match request {
2188 MarkerProofRequest::CredentialAttach(_) => ClientDiscriminant::CredentialAttachRequest,
2189 MarkerProofRequest::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2190 }
2191}
2192
2193pub const PARTICIPANT_CAPABILITY: &str = "participant-v1";
2195
2196#[must_use]
2198pub const fn attempt_operation(value: &AttemptTokenBodyConflict) -> super::AttemptOperation {
2199 match value {
2200 AttemptTokenBodyConflict::CredentialAttach { .. } => {
2201 super::AttemptOperation::CredentialAttachRequest
2202 }
2203 AttemptTokenBodyConflict::Leave { .. } => super::AttemptOperation::LeaveRequest,
2204 AttemptTokenBodyConflict::RecordAdmission { .. } => {
2205 super::AttemptOperation::RecordAdmission
2206 }
2207 }
2208}
2209
2210#[must_use]
2212pub fn capability_string() -> String {
2213 String::from(PARTICIPANT_CAPABILITY)
2214}