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 EnrollmentNotPermitted,
58 EnrollmentConversationOutOfScope,
60 CredentialAttachConversationOutOfScope,
62}
63
64#[derive(Clone, Debug, PartialEq, Eq)]
69pub enum AttemptTokenBodyConflict {
70 CredentialAttach {
72 token: AttachAttemptToken,
74 conversation_id: ConversationId,
76 presented_participant_id: ParticipantId,
78 presented_generation: Generation,
80 presented_marker_delivery_seq: Option<DeliverySeq>,
82 conflict: AttemptConflict,
84 },
85 Leave {
87 token: LeaveAttemptToken,
89 conversation_id: ConversationId,
91 presented_participant_id: ParticipantId,
93 presented_generation: Generation,
95 },
96 RecordAdmission {
106 token: RecordAdmissionAttemptToken,
108 conversation_id: ConversationId,
110 presented_participant_id: ParticipantId,
112 presented_generation: Generation,
114 },
115}
116
117#[derive(Clone, Debug, PartialEq, Eq)]
124pub enum ConnectionConversationCapacityExceeded {
125 SemanticRequest {
127 request: ResponseEnvelope,
129 limit: u64,
131 },
132 ObserverRecovery {
134 conversation_id: ConversationId,
136 limit: u64,
138 },
139}
140
141#[derive(Clone, Debug, PartialEq, Eq)]
143pub enum ConnectionConversationBindingOccupied {
144 Enrollment {
146 conversation_id: ConversationId,
148 enrollment_token: EnrollmentToken,
150 },
151 CredentialAttach {
153 conversation_id: ConversationId,
155 participant_id: ParticipantId,
157 capability_generation: Generation,
159 attach_attempt_token: AttachAttemptToken,
161 accept_marker_delivery_seq: Option<DeliverySeq>,
163 },
164}
165
166#[derive(Clone, Debug, PartialEq, Eq)]
168pub enum OrderAllocatingEnvelope {
169 Enrollment(EnrollmentEnvelope),
171 CredentialAttach(AttachEnvelope),
173 RecordAdmission(RecordAdmissionEnvelope),
175}
176
177#[derive(Clone, Debug, PartialEq, Eq)]
179pub struct ConversationOrderExhausted {
180 request: OrderAllocatingEnvelope,
182 high: u64,
184 order_remaining: u128,
186 reserved_claims: u128,
188 resulting_order_remaining: u128,
190 resulting_reserved_claims: u128,
192}
193
194impl ConversationOrderExhausted {
195 pub const REQUIRED_MAJORS: u64 = 1;
197
198 #[must_use]
204 pub const fn new(
205 request: OrderAllocatingEnvelope,
206 high: u64,
207 order_remaining: u128,
208 reserved_claims: u128,
209 resulting_order_remaining: u128,
210 resulting_reserved_claims: u128,
211 ) -> Self {
212 Self {
213 request,
214 high,
215 order_remaining,
216 reserved_claims,
217 resulting_order_remaining,
218 resulting_reserved_claims,
219 }
220 }
221
222 #[must_use]
224 pub const fn request(&self) -> &OrderAllocatingEnvelope {
225 &self.request
226 }
227
228 #[must_use]
230 pub const fn counter(&self) -> Counter {
231 let _ = self;
232 Counter::TransactionOrder
233 }
234
235 #[must_use]
237 pub const fn high(&self) -> u64 {
238 self.high
239 }
240
241 #[must_use]
243 pub const fn next_value(&self) -> Option<u64> {
244 self.high.checked_add(1)
245 }
246
247 #[must_use]
249 pub const fn order_remaining(&self) -> u128 {
250 self.order_remaining
251 }
252
253 #[must_use]
255 pub const fn reserved_claims(&self) -> u128 {
256 self.reserved_claims
257 }
258
259 #[must_use]
261 pub const fn resulting_order_remaining(&self) -> u128 {
262 self.resulting_order_remaining
263 }
264
265 #[must_use]
267 pub const fn resulting_reserved_claims(&self) -> u128 {
268 self.resulting_reserved_claims
269 }
270}
271
272#[derive(Clone, Debug, PartialEq, Eq)]
274pub enum ParticipantReferenceEnvelope {
275 CredentialAttach(AttachEnvelope),
277 Detach(DetachEnvelope),
279 ParticipantAck(ParticipantAckEnvelope),
281 Leave(LeaveEnvelope),
283 MarkerAck(MarkerAckEnvelope),
285 RecordAdmission(RecordAdmissionEnvelope),
287}
288
289#[derive(Clone, Debug, PartialEq, Eq)]
291pub enum BindingRequiredEnvelope {
292 Detach(DetachEnvelope),
294 ParticipantAck(ParticipantAckEnvelope),
296 Leave(LeaveEnvelope),
298 MarkerAck(MarkerAckEnvelope),
300 RecordAdmission(RecordAdmissionEnvelope),
302}
303
304#[derive(Clone, Debug, PartialEq, Eq)]
306pub struct ParticipantUnknown {
307 pub request: ParticipantReferenceEnvelope,
309}
310
311#[derive(Clone, Debug, PartialEq, Eq)]
313pub struct NoBinding {
314 pub request: BindingRequiredEnvelope,
316}
317
318#[derive(Clone, Copy, Debug, PartialEq, Eq)]
320pub enum BindingStateView {
321 Bound {
323 current_binding_epoch: BindingEpoch,
325 },
326 Detached,
328}
329
330impl BindingStateView {
331 #[must_use]
333 pub const fn tag(self) -> super::BindingStateTag {
334 match self {
335 Self::Bound { .. } => super::BindingStateTag::Bound,
336 Self::Detached => super::BindingStateTag::Detached,
337 }
338 }
339}
340
341#[derive(Clone, Debug, PartialEq, Eq)]
346pub struct TerminalizedDetachCell {
347 conversation_id: ConversationId,
348 participant_id: ParticipantId,
349 capability_generation: Generation,
350 detach_attempt_token: DetachAttemptToken,
351 current_generation: Generation,
352 committed_binding_epoch: BindingEpoch,
353 binding_state: BindingStateView,
354}
355
356impl TerminalizedDetachCell {
357 pub(crate) const fn from_terminalized_state<V>(
365 state: &crate::lifecycle::TerminalizedDetach<V>,
366 conversation_id: ConversationId,
367 current_generation: Generation,
368 binding_state: BindingStateView,
369 ) -> Self {
370 Self {
371 conversation_id,
372 participant_id: state.participant_id(),
373 capability_generation: state.request_generation(),
374 detach_attempt_token: state.token(),
375 current_generation,
376 committed_binding_epoch: state.committed_binding_epoch(),
377 binding_state,
378 }
379 }
380
381 #[allow(clippy::too_many_arguments)]
388 pub(super) const fn from_wire_decode(
389 _authority: super::server_codec::TerminalizedWireDecodeAuthority,
390 conversation_id: ConversationId,
391 participant_id: ParticipantId,
392 capability_generation: Generation,
393 detach_attempt_token: DetachAttemptToken,
394 current_generation: Generation,
395 committed_binding_epoch: BindingEpoch,
396 binding_state: BindingStateView,
397 ) -> Self {
398 Self {
399 conversation_id,
400 participant_id,
401 capability_generation,
402 detach_attempt_token,
403 current_generation,
404 committed_binding_epoch,
405 binding_state,
406 }
407 }
408
409 #[cfg(test)]
410 pub(crate) const fn for_client_test(
411 conversation_id: ConversationId,
412 participant_id: ParticipantId,
413 capability_generation: Generation,
414 detach_attempt_token: DetachAttemptToken,
415 current_generation: Generation,
416 committed_binding_epoch: BindingEpoch,
417 binding_state: BindingStateView,
418 ) -> Self {
419 Self {
420 conversation_id,
421 participant_id,
422 capability_generation,
423 detach_attempt_token,
424 current_generation,
425 committed_binding_epoch,
426 binding_state,
427 }
428 }
429
430 #[must_use]
432 pub const fn conversation_id(&self) -> ConversationId {
433 self.conversation_id
434 }
435
436 #[must_use]
438 pub const fn participant_id(&self) -> ParticipantId {
439 self.participant_id
440 }
441
442 #[must_use]
444 pub const fn capability_generation(&self) -> Generation {
445 self.capability_generation
446 }
447
448 #[must_use]
450 pub const fn detach_attempt_token(&self) -> DetachAttemptToken {
451 self.detach_attempt_token
452 }
453
454 #[must_use]
456 pub const fn current_generation(&self) -> Generation {
457 self.current_generation
458 }
459
460 #[must_use]
462 pub const fn committed_binding_epoch(&self) -> BindingEpoch {
463 self.committed_binding_epoch
464 }
465
466 #[must_use]
468 pub const fn binding_state(&self) -> BindingStateView {
469 self.binding_state
470 }
471}
472
473#[derive(Clone, Debug, PartialEq, Eq)]
475pub enum DetachStaleAuthority {
476 Live {
478 conversation_id: ConversationId,
480 participant_id: ParticipantId,
482 capability_generation: Generation,
484 detach_attempt_token: DetachAttemptToken,
486 current_generation: Generation,
488 },
489 TerminalizedDetachCell(TerminalizedDetachCell),
491}
492
493impl DetachStaleAuthority {
494 #[must_use]
496 pub const fn authority_state_tag(&self) -> DetachAuthorityStateTag {
497 match self {
498 Self::Live { .. } => DetachAuthorityStateTag::Live,
499 Self::TerminalizedDetachCell(_) => DetachAuthorityStateTag::TerminalizedDetachCell,
500 }
501 }
502}
503
504#[derive(Clone, Debug, PartialEq, Eq)]
506pub enum LeaveStaleAuthority {
507 Live {
509 conversation_id: ConversationId,
511 participant_id: ParticipantId,
513 presented_generation: Generation,
515 leave_attempt_token: LeaveAttemptToken,
517 current_generation: Generation,
519 },
520 CommittedLeaveTombstone {
522 conversation_id: ConversationId,
524 participant_id: ParticipantId,
526 presented_generation: Generation,
528 leave_attempt_token: LeaveAttemptToken,
530 retired_generation: Generation,
532 },
533}
534
535impl LeaveStaleAuthority {
536 #[must_use]
538 pub const fn authority_state_tag(&self) -> LeaveAuthorityStateTag {
539 match self {
540 Self::Live { .. } => LeaveAuthorityStateTag::Live,
541 Self::CommittedLeaveTombstone { .. } => LeaveAuthorityStateTag::CommittedLeaveTombstone,
542 }
543 }
544}
545
546#[derive(Clone, Debug, PartialEq, Eq)]
548pub enum CommonStaleAuthorityEnvelope {
549 CredentialAttach(AttachEnvelope),
551 ParticipantAck(ParticipantAckEnvelope),
553 MarkerAck(MarkerAckEnvelope),
555 RecordAdmission(RecordAdmissionEnvelope),
557}
558
559#[derive(Clone, Debug, PartialEq, Eq)]
561pub enum StaleAuthority {
562 Live {
564 request: CommonStaleAuthorityEnvelope,
566 current_generation: Generation,
568 },
569 Detach(DetachStaleAuthority),
571 Leave(LeaveStaleAuthority),
573}
574
575#[derive(Clone, Debug, PartialEq, Eq)]
577pub enum Retired {
578 Enrollment {
580 request: EnrollmentEnvelope,
582 participant_id: ParticipantId,
584 retired_generation: Generation,
586 },
587 Participant {
589 request: ParticipantReferenceEnvelope,
591 retired_generation: Generation,
593 },
594}
595
596#[derive(Clone, Debug, PartialEq, Eq)]
598pub struct EnrollBound {
599 conversation_id: ConversationId,
600 token: EnrollmentToken,
601 participant_id: ParticipantId,
602 attach_secret: AttachSecret,
603 origin_binding_epoch: BindingEpoch,
604 receipt_expires_at: u128,
605 provenance_expires_at: u128,
606}
607
608impl EnrollBound {
609 #[must_use]
616 pub const fn new(
617 conversation_id: ConversationId,
618 token: EnrollmentToken,
619 participant_id: ParticipantId,
620 attach_secret: AttachSecret,
621 origin_binding_epoch: BindingEpoch,
622 receipt_expires_at: u128,
623 provenance_expires_at: u128,
624 ) -> Option<Self> {
625 if origin_binding_epoch.capability_generation.get() == 1 {
626 Some(Self {
627 conversation_id,
628 token,
629 participant_id,
630 attach_secret,
631 origin_binding_epoch,
632 receipt_expires_at,
633 provenance_expires_at,
634 })
635 } else {
636 None
637 }
638 }
639
640 #[must_use]
642 pub const fn conversation_id(&self) -> ConversationId {
643 self.conversation_id
644 }
645
646 #[must_use]
648 pub const fn token(&self) -> EnrollmentToken {
649 self.token
650 }
651
652 #[must_use]
654 pub const fn participant_id(&self) -> ParticipantId {
655 self.participant_id
656 }
657
658 #[must_use]
660 pub const fn request_generation(&self) -> Option<Generation> {
661 None
662 }
663
664 #[must_use]
666 pub const fn capability_generation(&self) -> Generation {
667 self.origin_binding_epoch.capability_generation
668 }
669
670 #[must_use]
672 pub const fn attach_secret(&self) -> AttachSecret {
673 self.attach_secret
674 }
675
676 #[must_use]
678 pub const fn origin_binding_epoch(&self) -> BindingEpoch {
679 self.origin_binding_epoch
680 }
681
682 #[must_use]
684 pub const fn persisted_cursor(&self) -> DeliverySeq {
685 0
686 }
687
688 #[must_use]
690 pub const fn accepted_marker_delivery_seq(&self) -> Option<DeliverySeq> {
691 None
692 }
693
694 #[must_use]
696 pub const fn receipt_expires_at(&self) -> u128 {
697 self.receipt_expires_at
698 }
699
700 #[must_use]
702 pub const fn provenance_expires_at(&self) -> u128 {
703 self.provenance_expires_at
704 }
705}
706
707#[derive(Clone, Debug, PartialEq, Eq)]
709pub struct EnrollmentKnown {
710 pub conversation_id: ConversationId,
712 pub token: EnrollmentToken,
714 pub participant_id: ParticipantId,
716 pub current_generation: Generation,
718}
719
720#[derive(Clone, Debug, PartialEq, Eq)]
722pub enum ReceiptExpired {
723 Enrollment {
725 conversation_id: ConversationId,
727 token: EnrollmentToken,
729 participant_id: ParticipantId,
731 result_generation: Generation,
733 current_generation: Generation,
735 reason: ReceiptExpiryReason,
737 },
738 CredentialAttach {
740 conversation_id: ConversationId,
742 token: AttachAttemptToken,
744 participant_id: ParticipantId,
746 presented_generation: Generation,
748 presented_marker_delivery_seq: Option<DeliverySeq>,
750 result_generation: Generation,
752 current_generation: Generation,
754 reason: ReceiptExpiryReason,
756 },
757}
758
759#[derive(Clone, Copy, Debug, PartialEq, Eq)]
764pub enum EnrollmentReceiptCapacityScope {
765 LiveReceiptServer,
767 ProvenanceServer,
769 ProvenanceConversation,
771}
772
773impl EnrollmentReceiptCapacityScope {
774 #[must_use]
776 pub const fn wire_scope(self) -> ReceiptCapacityScope {
777 match self {
778 Self::LiveReceiptServer => ReceiptCapacityScope::LiveReceiptServer,
779 Self::ProvenanceServer => ReceiptCapacityScope::ProvenanceServer,
780 Self::ProvenanceConversation => ReceiptCapacityScope::ProvenanceConversation,
781 }
782 }
783}
784
785#[derive(Clone, Debug, PartialEq, Eq)]
787pub enum ReceiptCapacityExceeded {
788 Enrollment {
790 request: EnrollmentEnvelope,
792 scope: EnrollmentReceiptCapacityScope,
794 limit: u64,
796 occupied: u64,
798 },
799 CredentialAttach {
801 request: AttachEnvelope,
803 scope: ReceiptCapacityScope,
805 limit: u64,
807 occupied: u64,
809 },
810}
811
812impl ReceiptCapacityExceeded {
813 pub const REQUESTED: u64 = 1;
815}
816
817#[derive(Clone, Debug, PartialEq, Eq)]
819pub struct IdentityCapacityExceeded {
820 pub request: EnrollmentEnvelope,
822 pub scope: IdentityCapacityScope,
824 pub limit: u64,
826 pub occupied: u64,
828}
829
830impl IdentityCapacityExceeded {
831 pub const REQUESTED: u64 = 1;
833}
834
835#[derive(Clone, Copy, Debug, PartialEq, Eq)]
837pub struct ObserverBackpressureState {
838 backpressure_epoch: ObserverEpoch,
840 observer_progress: DeliverySeq,
842}
843
844impl ObserverBackpressureState {
845 #[must_use]
850 pub const fn initial(observer_progress: DeliverySeq) -> Self {
851 Self {
852 backpressure_epoch: observer_progress,
853 observer_progress,
854 }
855 }
856
857 #[must_use]
863 pub const fn replay(
864 backpressure_epoch: ObserverEpoch,
865 observer_progress: DeliverySeq,
866 ) -> Option<Self> {
867 if backpressure_epoch == observer_progress {
868 Some(Self {
869 backpressure_epoch,
870 observer_progress,
871 })
872 } else {
873 None
874 }
875 }
876
877 #[must_use]
879 pub const fn backpressure_epoch(self) -> ObserverEpoch {
880 self.backpressure_epoch
881 }
882
883 #[must_use]
885 pub const fn observer_progress(self) -> DeliverySeq {
886 self.observer_progress
887 }
888}
889
890#[derive(Clone, Debug, PartialEq, Eq)]
892pub enum ObserverBackpressure {
893 Enrollment {
895 request: EnrollmentEnvelope,
897 state: ObserverBackpressureState,
899 },
900 CredentialAttach {
902 request: AttachEnvelope,
904 state: ObserverBackpressureState,
906 },
907 Detach {
909 request: DetachEnvelope,
911 committed_binding_epoch: BindingEpoch,
913 state: ObserverBackpressureState,
915 },
916 Leave {
918 request: LeaveEnvelope,
920 state: ObserverBackpressureState,
922 prior_terminal_cell_exists: bool,
924 },
925 RecordAdmission {
927 request: RecordAdmissionEnvelope,
929 state: ObserverBackpressureState,
931 },
932}
933
934#[derive(Clone, Copy, Debug, PartialEq, Eq)]
948pub enum MarkerSettlementBackpressure {
949 CredentialAttach {
951 conversation_id: ConversationId,
953 refused_epoch: SettlementEpoch,
955 },
956 Detach {
958 conversation_id: ConversationId,
960 refused_epoch: SettlementEpoch,
962 },
963}
964
965#[derive(Clone, Copy, Debug, PartialEq, Eq)]
976pub struct EnrollmentSettlementBackpressure {
977 pub conversation_id: ConversationId,
979}
980
981#[derive(Clone, Copy, Debug, PartialEq, Eq)]
991pub enum RecordAdmissionFaultClass {
992 Projection,
994 Order,
996 Sequence,
998 RequiredCapacity,
1000 RefusalInvariant,
1002}
1003
1004impl RecordAdmissionFaultClass {
1005 #[must_use]
1007 pub const fn tag(self) -> RecordAdmissionFaultClassTag {
1008 match self {
1009 Self::Projection => RecordAdmissionFaultClassTag::Projection,
1010 Self::Order => RecordAdmissionFaultClassTag::Order,
1011 Self::Sequence => RecordAdmissionFaultClassTag::Sequence,
1012 Self::RequiredCapacity => RecordAdmissionFaultClassTag::RequiredCapacity,
1013 Self::RefusalInvariant => RecordAdmissionFaultClassTag::RefusalInvariant,
1014 }
1015 }
1016}
1017
1018impl From<RecordAdmissionFaultClassTag> for RecordAdmissionFaultClass {
1019 fn from(tag: RecordAdmissionFaultClassTag) -> Self {
1020 match tag {
1021 RecordAdmissionFaultClassTag::Projection => Self::Projection,
1022 RecordAdmissionFaultClassTag::Order => Self::Order,
1023 RecordAdmissionFaultClassTag::Sequence => Self::Sequence,
1024 RecordAdmissionFaultClassTag::RequiredCapacity => Self::RequiredCapacity,
1025 RecordAdmissionFaultClassTag::RefusalInvariant => Self::RefusalInvariant,
1026 }
1027 }
1028}
1029
1030#[derive(Clone, Debug, PartialEq, Eq)]
1049pub struct RecordAdmissionProtocolFault {
1050 pub request: RecordAdmissionEnvelope,
1052 pub class: RecordAdmissionFaultClass,
1054}
1055
1056#[derive(Clone, Debug, PartialEq, Eq)]
1058pub enum SequenceAllocatingEnvelope {
1059 Enrollment(EnrollmentEnvelope),
1061 CredentialAttach(AttachEnvelope),
1063 RecordAdmission(RecordAdmissionEnvelope),
1065}
1066
1067#[derive(Clone, Debug, PartialEq, Eq)]
1069pub struct ConversationSequenceExhausted {
1070 pub request: SequenceAllocatingEnvelope,
1072 pub sequence_budget: SequenceBudget,
1074}
1075
1076#[derive(Clone, Debug, PartialEq, Eq)]
1078pub struct AttachBound {
1079 conversation_id: ConversationId,
1081 token: AttachAttemptToken,
1083 participant_id: ParticipantId,
1085 request_generation: Generation,
1087 attach_secret: AttachSecret,
1089 origin_binding_epoch: BindingEpoch,
1091 persisted_cursor: DeliverySeq,
1093 accepted_marker_delivery_seq: Option<DeliverySeq>,
1095 receipt_expires_at: u128,
1097 provenance_expires_at: u128,
1099}
1100
1101impl AttachBound {
1102 #[must_use]
1108 #[allow(clippy::too_many_arguments)]
1109 pub const fn ordinary(
1110 conversation_id: ConversationId,
1111 token: AttachAttemptToken,
1112 participant_id: ParticipantId,
1113 request_generation: Generation,
1114 attach_secret: AttachSecret,
1115 origin_binding_epoch: BindingEpoch,
1116 persisted_cursor: DeliverySeq,
1117 receipt_expires_at: u128,
1118 provenance_expires_at: u128,
1119 ) -> Option<Self> {
1120 if !is_successor_generation(
1121 request_generation,
1122 origin_binding_epoch.capability_generation,
1123 ) {
1124 return None;
1125 }
1126 Some(Self {
1127 conversation_id,
1128 token,
1129 participant_id,
1130 request_generation,
1131 attach_secret,
1132 origin_binding_epoch,
1133 persisted_cursor,
1134 accepted_marker_delivery_seq: None,
1135 receipt_expires_at,
1136 provenance_expires_at,
1137 })
1138 }
1139
1140 #[must_use]
1146 #[allow(clippy::too_many_arguments)]
1147 pub const fn fenced(
1148 conversation_id: ConversationId,
1149 token: AttachAttemptToken,
1150 participant_id: ParticipantId,
1151 request_generation: Generation,
1152 attach_secret: AttachSecret,
1153 origin_binding_epoch: BindingEpoch,
1154 accepted_marker_delivery_seq: DeliverySeq,
1155 receipt_expires_at: u128,
1156 provenance_expires_at: u128,
1157 ) -> Option<Self> {
1158 if !is_successor_generation(
1159 request_generation,
1160 origin_binding_epoch.capability_generation,
1161 ) {
1162 return None;
1163 }
1164 Some(Self {
1165 conversation_id,
1166 token,
1167 participant_id,
1168 request_generation,
1169 attach_secret,
1170 origin_binding_epoch,
1171 persisted_cursor: accepted_marker_delivery_seq,
1172 accepted_marker_delivery_seq: Some(accepted_marker_delivery_seq),
1173 receipt_expires_at,
1174 provenance_expires_at,
1175 })
1176 }
1177
1178 #[must_use]
1180 pub const fn conversation_id(&self) -> ConversationId {
1181 self.conversation_id
1182 }
1183
1184 #[must_use]
1186 pub const fn token(&self) -> AttachAttemptToken {
1187 self.token
1188 }
1189
1190 #[must_use]
1192 pub const fn participant_id(&self) -> ParticipantId {
1193 self.participant_id
1194 }
1195
1196 #[must_use]
1198 pub const fn request_generation(&self) -> Generation {
1199 self.request_generation
1200 }
1201
1202 #[must_use]
1204 pub const fn capability_generation(&self) -> Generation {
1205 self.origin_binding_epoch.capability_generation
1206 }
1207
1208 #[must_use]
1210 pub const fn attach_secret(&self) -> AttachSecret {
1211 self.attach_secret
1212 }
1213
1214 #[must_use]
1216 pub const fn origin_binding_epoch(&self) -> BindingEpoch {
1217 self.origin_binding_epoch
1218 }
1219
1220 #[must_use]
1222 pub const fn persisted_cursor(&self) -> DeliverySeq {
1223 self.persisted_cursor
1224 }
1225
1226 #[must_use]
1228 pub const fn accepted_marker_delivery_seq(&self) -> Option<DeliverySeq> {
1229 self.accepted_marker_delivery_seq
1230 }
1231
1232 #[must_use]
1234 pub const fn receipt_expires_at(&self) -> u128 {
1235 self.receipt_expires_at
1236 }
1237
1238 #[must_use]
1240 pub const fn provenance_expires_at(&self) -> u128 {
1241 self.provenance_expires_at
1242 }
1243}
1244
1245const fn is_successor_generation(previous: Generation, successor: Generation) -> bool {
1246 match previous.get().checked_add(1) {
1247 Some(expected) => successor.get() == expected,
1248 None => false,
1249 }
1250}
1251
1252#[derive(Clone, Debug, PartialEq, Eq)]
1254pub struct StaleOrUnknownReceipt {
1255 pub conversation_id: ConversationId,
1257 pub token: AttachAttemptToken,
1259 pub participant_id: ParticipantId,
1261 pub presented_generation: Generation,
1263 pub presented_marker_delivery_seq: Option<DeliverySeq>,
1265 pub current_generation: Generation,
1267}
1268
1269#[derive(Clone, Debug, PartialEq, Eq)]
1271pub struct AttachMarkerProof {
1272 pub conversation_id: ConversationId,
1274 pub token: AttachAttemptToken,
1276 pub participant_id: ParticipantId,
1278 pub capability_generation: Generation,
1280 pub requested_marker_delivery_seq: DeliverySeq,
1282}
1283
1284#[derive(Clone, Debug, PartialEq, Eq)]
1286pub struct MarkerAckProof {
1287 pub conversation_id: ConversationId,
1289 pub participant_id: ParticipantId,
1291 pub capability_generation: Generation,
1293 pub requested_marker_delivery_seq: DeliverySeq,
1295}
1296
1297#[derive(Clone, Debug, PartialEq, Eq)]
1299pub enum MarkerProofRequest {
1300 CredentialAttach(AttachMarkerProof),
1302 MarkerAck(MarkerAckProof),
1304}
1305
1306#[derive(Clone, Debug, PartialEq, Eq)]
1308pub struct MarkerNotDelivered {
1309 pub request: MarkerProofRequest,
1311 pub reason: MarkerNotDeliveredReason,
1313 pub expected_marker_delivery_seq: DeliverySeq,
1315}
1316
1317#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1319pub enum MarkerMismatchBody {
1320 BelowCursor {
1322 current_cursor: DeliverySeq,
1324 },
1325 NoMarkerExpected,
1327 ExpectedDifferentMarker {
1329 expected_marker_delivery_seq: DeliverySeq,
1331 },
1332}
1333
1334impl MarkerMismatchBody {
1335 #[must_use]
1337 pub const fn reason(self) -> MarkerMismatchReason {
1338 match self {
1339 Self::BelowCursor { .. } => MarkerMismatchReason::BelowCursor,
1340 Self::NoMarkerExpected => MarkerMismatchReason::NoMarkerExpected,
1341 Self::ExpectedDifferentMarker { .. } => MarkerMismatchReason::ExpectedDifferentMarker,
1342 }
1343 }
1344}
1345
1346#[derive(Clone, Debug, PartialEq, Eq)]
1348pub struct MarkerMismatch {
1349 pub request: MarkerProofRequest,
1351 pub mismatch: MarkerMismatchBody,
1353}
1354
1355#[derive(Clone, Debug, PartialEq, Eq)]
1357pub enum ReceiptReplay {
1358 Enrollment(EnrollBound),
1361 CredentialAttach(AttachBound),
1364}
1365
1366#[derive(Clone, Debug, PartialEq, Eq)]
1368pub struct DetachCommitted {
1369 conversation_id: ConversationId,
1371 participant_id: ParticipantId,
1373 detach_attempt_token: DetachAttemptToken,
1375 committed_binding_epoch: BindingEpoch,
1377 detached_delivery_seq: DeliverySeq,
1379}
1380
1381impl DetachCommitted {
1382 #[must_use]
1385 pub const fn new(
1386 conversation_id: ConversationId,
1387 participant_id: ParticipantId,
1388 detach_attempt_token: DetachAttemptToken,
1389 committed_binding_epoch: BindingEpoch,
1390 detached_delivery_seq: DeliverySeq,
1391 ) -> Self {
1392 Self {
1393 conversation_id,
1394 participant_id,
1395 detach_attempt_token,
1396 committed_binding_epoch,
1397 detached_delivery_seq,
1398 }
1399 }
1400
1401 #[must_use]
1403 pub const fn conversation_id(&self) -> ConversationId {
1404 self.conversation_id
1405 }
1406
1407 #[must_use]
1409 pub const fn participant_id(&self) -> ParticipantId {
1410 self.participant_id
1411 }
1412
1413 #[must_use]
1415 pub const fn capability_generation(&self) -> Generation {
1416 self.committed_binding_epoch.capability_generation
1417 }
1418
1419 #[must_use]
1421 pub const fn detach_attempt_token(&self) -> DetachAttemptToken {
1422 self.detach_attempt_token
1423 }
1424
1425 #[must_use]
1427 pub const fn committed_binding_epoch(&self) -> BindingEpoch {
1428 self.committed_binding_epoch
1429 }
1430
1431 #[must_use]
1433 pub const fn detached_delivery_seq(&self) -> DeliverySeq {
1434 self.detached_delivery_seq
1435 }
1436}
1437
1438#[derive(Clone, Debug, PartialEq, Eq)]
1440pub struct DetachInProgress {
1441 pub conversation_id: ConversationId,
1443 pub participant_id: ParticipantId,
1445 pub presented_token: DetachAttemptToken,
1447 pub presented_generation: Generation,
1449 pub committed_binding_epoch: BindingEpoch,
1451}
1452
1453#[derive(Clone, Debug, PartialEq, Eq)]
1455pub struct AckCommitted {
1456 request: ParticipantAckEnvelope,
1458}
1459
1460impl AckCommitted {
1461 #[must_use]
1464 pub const fn new(request: ParticipantAckEnvelope) -> Self {
1465 Self { request }
1466 }
1467
1468 #[must_use]
1470 pub const fn request(&self) -> &ParticipantAckEnvelope {
1471 &self.request
1472 }
1473
1474 #[must_use]
1476 pub const fn current_cursor(&self) -> DeliverySeq {
1477 self.request.through_seq
1478 }
1479}
1480
1481#[derive(Clone, Debug, PartialEq, Eq)]
1483pub enum AckNoOp {
1484 ParticipantAck(ParticipantAckEnvelope),
1486 MarkerAck(MarkerAckEnvelope),
1488}
1489
1490impl AckNoOp {
1491 #[must_use]
1494 pub const fn participant_ack(request: ParticipantAckEnvelope) -> Self {
1495 Self::ParticipantAck(request)
1496 }
1497
1498 #[must_use]
1501 pub const fn marker_ack(request: MarkerAckEnvelope) -> Self {
1502 Self::MarkerAck(request)
1503 }
1504
1505 #[must_use]
1507 pub const fn current_cursor(&self) -> DeliverySeq {
1508 match self {
1509 Self::ParticipantAck(request) => request.through_seq,
1510 Self::MarkerAck(request) => request.marker_delivery_seq,
1511 }
1512 }
1513}
1514
1515#[derive(Clone, Debug, PartialEq, Eq)]
1517pub struct AckGap {
1518 request: ParticipantAckEnvelope,
1520 current_cursor: DeliverySeq,
1522}
1523
1524impl AckGap {
1525 #[must_use]
1528 pub const fn new(request: ParticipantAckEnvelope, current_cursor: DeliverySeq) -> Option<Self> {
1529 if request.through_seq > current_cursor {
1530 Some(Self {
1531 request,
1532 current_cursor,
1533 })
1534 } else {
1535 None
1536 }
1537 }
1538
1539 #[must_use]
1541 pub const fn request(&self) -> &ParticipantAckEnvelope {
1542 &self.request
1543 }
1544
1545 #[must_use]
1547 pub const fn current_cursor(&self) -> DeliverySeq {
1548 self.current_cursor
1549 }
1550
1551 #[must_use]
1553 pub const fn reason(&self) -> AckGapReason {
1554 let _ = self;
1555 AckGapReason::NotContiguouslyAvailable
1556 }
1557}
1558
1559#[derive(Clone, Debug, PartialEq, Eq)]
1561pub struct AckRegression {
1562 request: ParticipantAckEnvelope,
1564 current_cursor: DeliverySeq,
1566}
1567
1568impl AckRegression {
1569 #[must_use]
1572 pub const fn new(request: ParticipantAckEnvelope, current_cursor: DeliverySeq) -> Option<Self> {
1573 if request.through_seq < current_cursor {
1574 Some(Self {
1575 request,
1576 current_cursor,
1577 })
1578 } else {
1579 None
1580 }
1581 }
1582
1583 #[must_use]
1585 pub const fn request(&self) -> &ParticipantAckEnvelope {
1586 &self.request
1587 }
1588
1589 #[must_use]
1591 pub const fn current_cursor(&self) -> DeliverySeq {
1592 self.current_cursor
1593 }
1594
1595 #[must_use]
1597 pub const fn reason(&self) -> AckRegressionReason {
1598 let _ = self;
1599 AckRegressionReason::BelowCursor
1600 }
1601}
1602
1603#[derive(Clone, Debug, PartialEq, Eq)]
1605pub struct LeaveCommitted {
1606 conversation_id: ConversationId,
1608 leave_attempt_token: LeaveAttemptToken,
1610 participant_id: ParticipantId,
1612 retired_generation: Generation,
1614 ended_binding_epoch: Option<BindingEpoch>,
1616 prior_terminal_delivery_seq: Option<DeliverySeq>,
1618 left_delivery_seq: DeliverySeq,
1620}
1621
1622impl LeaveCommitted {
1623 #[must_use]
1629 #[allow(clippy::too_many_arguments)]
1630 pub const fn new(
1631 conversation_id: ConversationId,
1632 leave_attempt_token: LeaveAttemptToken,
1633 participant_id: ParticipantId,
1634 retired_generation: Generation,
1635 ended_binding_epoch: Option<BindingEpoch>,
1636 prior_terminal_delivery_seq: Option<DeliverySeq>,
1637 left_delivery_seq: DeliverySeq,
1638 ) -> Option<Self> {
1639 if let Some(epoch) = ended_binding_epoch
1640 && epoch.capability_generation.get() != retired_generation.get()
1641 {
1642 return None;
1643 }
1644 if let Some(prior) = prior_terminal_delivery_seq
1645 && prior >= left_delivery_seq
1646 {
1647 return None;
1648 }
1649 Some(Self {
1650 conversation_id,
1651 leave_attempt_token,
1652 participant_id,
1653 retired_generation,
1654 ended_binding_epoch,
1655 prior_terminal_delivery_seq,
1656 left_delivery_seq,
1657 })
1658 }
1659
1660 #[must_use]
1662 pub const fn conversation_id(&self) -> ConversationId {
1663 self.conversation_id
1664 }
1665
1666 #[must_use]
1668 pub const fn leave_attempt_token(&self) -> LeaveAttemptToken {
1669 self.leave_attempt_token
1670 }
1671
1672 #[must_use]
1674 pub const fn participant_id(&self) -> ParticipantId {
1675 self.participant_id
1676 }
1677
1678 #[must_use]
1680 pub const fn presented_generation(&self) -> Generation {
1681 self.retired_generation
1682 }
1683
1684 #[must_use]
1686 pub const fn retired_generation(&self) -> Generation {
1687 self.retired_generation
1688 }
1689
1690 #[must_use]
1692 pub const fn ended_binding_epoch(&self) -> Option<BindingEpoch> {
1693 self.ended_binding_epoch
1694 }
1695
1696 #[must_use]
1698 pub const fn prior_terminal_delivery_seq(&self) -> Option<DeliverySeq> {
1699 self.prior_terminal_delivery_seq
1700 }
1701
1702 #[must_use]
1704 pub const fn left_delivery_seq(&self) -> DeliverySeq {
1705 self.left_delivery_seq
1706 }
1707}
1708
1709#[derive(Clone, Debug, PartialEq, Eq)]
1711pub struct MarkerAckCommitted {
1712 request: MarkerAckEnvelope,
1714}
1715
1716impl MarkerAckCommitted {
1717 #[must_use]
1720 pub const fn new(request: MarkerAckEnvelope) -> Self {
1721 Self { request }
1722 }
1723
1724 #[must_use]
1726 pub const fn request(&self) -> &MarkerAckEnvelope {
1727 &self.request
1728 }
1729
1730 #[must_use]
1732 pub const fn current_cursor(&self) -> DeliverySeq {
1733 self.request.marker_delivery_seq
1734 }
1735}
1736
1737#[derive(Clone, Debug, PartialEq, Eq)]
1739pub struct RecordCommitted {
1740 request: RecordAdmissionEnvelope,
1742 delivery_seq: DeliverySeq,
1744}
1745
1746impl RecordCommitted {
1747 #[must_use]
1750 pub const fn new(request: RecordAdmissionEnvelope, delivery_seq: DeliverySeq) -> Self {
1751 Self {
1752 request,
1753 delivery_seq,
1754 }
1755 }
1756
1757 #[must_use]
1759 pub const fn request(&self) -> &RecordAdmissionEnvelope {
1760 &self.request
1761 }
1762
1763 #[must_use]
1765 pub const fn sender_participant_id(&self) -> ParticipantId {
1766 self.request.participant_id
1767 }
1768
1769 #[must_use]
1771 pub const fn delivery_seq(&self) -> DeliverySeq {
1772 self.delivery_seq
1773 }
1774}
1775
1776#[derive(Clone, Debug, PartialEq, Eq)]
1778pub struct RecordTooLarge {
1779 pub request: RecordAdmissionEnvelope,
1781 pub dimension: ResourceDimension,
1783 pub encoded_record_charge: ResourceVector,
1785 pub max_ordinary_record_charge: ResourceVector,
1787}
1788
1789#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1791pub struct ObserverProgressStatus {
1792 pub conversation_id: ConversationId,
1794 pub refused_epoch: ObserverEpoch,
1796 pub current_observer_progress: DeliverySeq,
1798 pub armed: bool,
1800 pub progressed: bool,
1802}
1803
1804#[derive(Clone, Debug, PartialEq, Eq)]
1806pub struct ObserverRecoveryAccepted {
1807 pub statuses: Vec<ObserverProgressStatus>,
1809}
1810
1811#[derive(Clone, Debug, PartialEq, Eq)]
1813pub enum InvalidObserverEpoch {
1814 ConversationUnknown {
1816 conversation_id: ConversationId,
1818 presented_epoch: ObserverEpoch,
1820 },
1821 EpochAhead {
1823 conversation_id: ConversationId,
1825 presented_epoch: ObserverEpoch,
1827 current_observer_progress: DeliverySeq,
1829 },
1830}
1831
1832impl InvalidObserverEpoch {
1833 #[must_use]
1835 pub const fn reason(&self) -> InvalidObserverEpochReason {
1836 match self {
1837 Self::ConversationUnknown { .. } => InvalidObserverEpochReason::ConversationUnknown,
1838 Self::EpochAhead { .. } => InvalidObserverEpochReason::EpochAhead,
1839 }
1840 }
1841}
1842
1843#[derive(Clone, Debug, PartialEq, Eq)]
1845pub enum InvalidObserverEpochList {
1846 TooManyEntries {
1848 presented_entries: u64,
1850 max_entries: u64,
1852 },
1853 DuplicateConversation {
1855 conversation_id: ConversationId,
1857 first_index: u64,
1859 duplicate_index: u64,
1861 },
1862}
1863
1864impl InvalidObserverEpochList {
1865 #[must_use]
1867 pub const fn reason(&self) -> InvalidObserverEpochListReason {
1868 match self {
1869 Self::TooManyEntries { .. } => InvalidObserverEpochListReason::TooManyEntries,
1870 Self::DuplicateConversation { .. } => {
1871 InvalidObserverEpochListReason::DuplicateConversation
1872 }
1873 }
1874 }
1875}
1876
1877#[derive(Clone, Debug, PartialEq, Eq)]
1879pub enum ServerValue {
1880 ParticipantTransportRejected(ParticipantTransportRejected),
1882 AttemptTokenBodyConflict(AttemptTokenBodyConflict),
1884 ConnectionConversationCapacityExceeded(ConnectionConversationCapacityExceeded),
1886 ConnectionConversationBindingOccupied(ConnectionConversationBindingOccupied),
1888 ConversationOrderExhausted(Box<ConversationOrderExhausted>),
1890 ParticipantUnknown(ParticipantUnknown),
1892 NoBinding(NoBinding),
1894 StaleAuthority(StaleAuthority),
1896 Retired(Retired),
1898 MarkerClosureCapacityExceeded(Box<MarkerClosureCapacityExceeded>),
1900 EnrollBound(EnrollBound),
1902 EnrollmentKnown(EnrollmentKnown),
1904 ReceiptExpired(ReceiptExpired),
1906 ReceiptCapacityExceeded(ReceiptCapacityExceeded),
1908 IdentityCapacityExceeded(IdentityCapacityExceeded),
1910 ObserverBackpressure(ObserverBackpressure),
1912 ConversationSequenceExhausted(Box<ConversationSequenceExhausted>),
1914 AttachBound(AttachBound),
1916 StaleOrUnknownReceipt(StaleOrUnknownReceipt),
1918 MarkerNotDelivered(MarkerNotDelivered),
1920 MarkerMismatch(MarkerMismatch),
1922 Bound(ReceiptReplay),
1924 UnboundReceipt(ReceiptReplay),
1926 DetachCommitted(DetachCommitted),
1928 DetachInProgress(DetachInProgress),
1930 AckCommitted(AckCommitted),
1932 AckNoOp(AckNoOp),
1934 AckGap(AckGap),
1936 AckRegression(AckRegression),
1938 LeaveCommitted(LeaveCommitted),
1940 MarkerAckCommitted(MarkerAckCommitted),
1942 RecordCommitted(RecordCommitted),
1944 RecordTooLarge(RecordTooLarge),
1946 ObserverRecoveryAccepted(ObserverRecoveryAccepted),
1948 InvalidObserverEpoch(InvalidObserverEpoch),
1950 InvalidObserverEpochList(InvalidObserverEpochList),
1952 MarkerSettlementBackpressure(MarkerSettlementBackpressure),
1954 EnrollmentSettlementBackpressure(EnrollmentSettlementBackpressure),
1956 RecordAdmissionProtocolFault(RecordAdmissionProtocolFault),
1958}
1959
1960impl ServerValue {
1961 #[must_use]
1963 pub const fn discriminant(&self) -> ServerDiscriminant {
1964 match self {
1965 Self::ParticipantTransportRejected(_) => {
1966 ServerDiscriminant::ParticipantTransportRejected
1967 }
1968 Self::AttemptTokenBodyConflict(_) => ServerDiscriminant::AttemptTokenBodyConflict,
1969 Self::ConnectionConversationCapacityExceeded(value) => match value {
1970 ConnectionConversationCapacityExceeded::SemanticRequest { .. } => {
1971 ServerDiscriminant::ConnectionConversationCapacityExceeded
1972 }
1973 ConnectionConversationCapacityExceeded::ObserverRecovery { .. } => {
1974 ServerDiscriminant::ObserverRecoveryConnectionCapacityExceeded
1975 }
1976 },
1977 Self::ConnectionConversationBindingOccupied(_) => {
1978 ServerDiscriminant::ConnectionConversationBindingOccupied
1979 }
1980 Self::ConversationOrderExhausted(_) => ServerDiscriminant::ConversationOrderExhausted,
1981 Self::ParticipantUnknown(_) => ServerDiscriminant::ParticipantUnknown,
1982 Self::NoBinding(_) => ServerDiscriminant::NoBinding,
1983 Self::StaleAuthority(_) => ServerDiscriminant::StaleAuthority,
1984 Self::Retired(_) => ServerDiscriminant::Retired,
1985 Self::MarkerClosureCapacityExceeded(_) => {
1986 ServerDiscriminant::MarkerClosureCapacityExceeded
1987 }
1988 Self::EnrollBound(_) => ServerDiscriminant::EnrollBound,
1989 Self::EnrollmentKnown(_) => ServerDiscriminant::EnrollmentKnown,
1990 Self::ReceiptExpired(_) => ServerDiscriminant::ReceiptExpired,
1991 Self::ReceiptCapacityExceeded(_) => ServerDiscriminant::ReceiptCapacityExceeded,
1992 Self::IdentityCapacityExceeded(_) => ServerDiscriminant::IdentityCapacityExceeded,
1993 Self::ObserverBackpressure(_) => ServerDiscriminant::ObserverBackpressure,
1994 Self::ConversationSequenceExhausted(_) => {
1995 ServerDiscriminant::ConversationSequenceExhausted
1996 }
1997 Self::AttachBound(_) => ServerDiscriminant::AttachBound,
1998 Self::StaleOrUnknownReceipt(_) => ServerDiscriminant::StaleOrUnknownReceipt,
1999 Self::MarkerNotDelivered(_) => ServerDiscriminant::MarkerNotDelivered,
2000 Self::MarkerMismatch(_) => ServerDiscriminant::MarkerMismatch,
2001 Self::Bound(_) => ServerDiscriminant::Bound,
2002 Self::UnboundReceipt(_) => ServerDiscriminant::UnboundReceipt,
2003 Self::DetachCommitted(_) => ServerDiscriminant::DetachCommitted,
2004 Self::DetachInProgress(_) => ServerDiscriminant::DetachInProgress,
2005 Self::AckCommitted(_) => ServerDiscriminant::AckCommitted,
2006 Self::AckNoOp(_) => ServerDiscriminant::AckNoOp,
2007 Self::AckGap(_) => ServerDiscriminant::AckGap,
2008 Self::AckRegression(_) => ServerDiscriminant::AckRegression,
2009 Self::LeaveCommitted(_) => ServerDiscriminant::LeaveCommitted,
2010 Self::MarkerAckCommitted(_) => ServerDiscriminant::MarkerAckCommitted,
2011 Self::RecordCommitted(_) => ServerDiscriminant::RecordCommitted,
2012 Self::RecordTooLarge(_) => ServerDiscriminant::RecordTooLarge,
2013 Self::ObserverRecoveryAccepted(_) => ServerDiscriminant::ObserverRecoveryAccepted,
2014 Self::InvalidObserverEpoch(_) => ServerDiscriminant::InvalidObserverEpoch,
2015 Self::InvalidObserverEpochList(_) => ServerDiscriminant::InvalidObserverEpochList,
2016 Self::MarkerSettlementBackpressure(_) => {
2017 ServerDiscriminant::MarkerSettlementBackpressure
2018 }
2019 Self::EnrollmentSettlementBackpressure(_) => {
2020 ServerDiscriminant::EnrollmentSettlementBackpressure
2021 }
2022 Self::RecordAdmissionProtocolFault(_) => {
2023 ServerDiscriminant::RecordAdmissionProtocolFault
2024 }
2025 }
2026 }
2027
2028 #[must_use]
2030 #[allow(clippy::too_many_lines)]
2031 pub const fn originating_request(&self) -> Option<ClientDiscriminant> {
2032 match self {
2033 Self::ParticipantTransportRejected(_)
2034 | Self::ObserverRecoveryAccepted(_)
2035 | Self::InvalidObserverEpoch(_)
2036 | Self::InvalidObserverEpochList(_) => None,
2037 Self::AttemptTokenBodyConflict(value) => Some(match value {
2038 AttemptTokenBodyConflict::CredentialAttach { .. } => {
2039 ClientDiscriminant::CredentialAttachRequest
2040 }
2041 AttemptTokenBodyConflict::Leave { .. } => ClientDiscriminant::LeaveRequest,
2042 AttemptTokenBodyConflict::RecordAdmission { .. } => {
2043 ClientDiscriminant::RecordAdmission
2044 }
2045 }),
2046 Self::ConnectionConversationCapacityExceeded(value) => match value {
2047 ConnectionConversationCapacityExceeded::SemanticRequest { request, .. } => {
2048 Some(request.originating_request())
2049 }
2050 ConnectionConversationCapacityExceeded::ObserverRecovery { .. } => None,
2051 },
2052 Self::ConnectionConversationBindingOccupied(value) => Some(match value {
2053 ConnectionConversationBindingOccupied::Enrollment { .. } => {
2054 ClientDiscriminant::EnrollmentRequest
2055 }
2056 ConnectionConversationBindingOccupied::CredentialAttach { .. } => {
2057 ClientDiscriminant::CredentialAttachRequest
2058 }
2059 }),
2060 Self::ConversationOrderExhausted(value) => Some(match value.request() {
2061 OrderAllocatingEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2062 OrderAllocatingEnvelope::CredentialAttach(_) => {
2063 ClientDiscriminant::CredentialAttachRequest
2064 }
2065 OrderAllocatingEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2066 }),
2067 Self::ParticipantUnknown(value) => Some(participant_reference_origin(&value.request)),
2068 Self::NoBinding(value) => Some(binding_required_origin(&value.request)),
2069 Self::StaleAuthority(value) => Some(stale_authority_origin(value)),
2070 Self::Retired(value) => Some(match value {
2071 Retired::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2072 Retired::Participant { request, .. } => participant_reference_origin(request),
2073 }),
2074 Self::MarkerClosureCapacityExceeded(value) => Some(match &value.request {
2075 ClosureCheckedEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2076 ClosureCheckedEnvelope::CredentialAttach(_) => {
2077 ClientDiscriminant::CredentialAttachRequest
2078 }
2079 ClosureCheckedEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
2080 ClosureCheckedEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2081 }),
2082 Self::EnrollBound(_)
2083 | Self::EnrollmentKnown(_)
2084 | Self::IdentityCapacityExceeded(_)
2085 | Self::EnrollmentSettlementBackpressure(_) => {
2086 Some(ClientDiscriminant::EnrollmentRequest)
2087 }
2088 Self::ReceiptExpired(value) => Some(match value {
2089 ReceiptExpired::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2090 ReceiptExpired::CredentialAttach { .. } => {
2091 ClientDiscriminant::CredentialAttachRequest
2092 }
2093 }),
2094 Self::ReceiptCapacityExceeded(value) => Some(match value {
2095 ReceiptCapacityExceeded::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2096 ReceiptCapacityExceeded::CredentialAttach { .. } => {
2097 ClientDiscriminant::CredentialAttachRequest
2098 }
2099 }),
2100 Self::ObserverBackpressure(value) => Some(match value {
2101 ObserverBackpressure::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2102 ObserverBackpressure::CredentialAttach { .. } => {
2103 ClientDiscriminant::CredentialAttachRequest
2104 }
2105 ObserverBackpressure::Detach { .. } => ClientDiscriminant::DetachRequest,
2106 ObserverBackpressure::Leave { .. } => ClientDiscriminant::LeaveRequest,
2107 ObserverBackpressure::RecordAdmission { .. } => ClientDiscriminant::RecordAdmission,
2108 }),
2109 Self::ConversationSequenceExhausted(value) => Some(match &value.request {
2110 SequenceAllocatingEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2111 SequenceAllocatingEnvelope::CredentialAttach(_) => {
2112 ClientDiscriminant::CredentialAttachRequest
2113 }
2114 SequenceAllocatingEnvelope::RecordAdmission(_) => {
2115 ClientDiscriminant::RecordAdmission
2116 }
2117 }),
2118 Self::AttachBound(_) | Self::StaleOrUnknownReceipt(_) => {
2119 Some(ClientDiscriminant::CredentialAttachRequest)
2120 }
2121 Self::MarkerNotDelivered(value) => Some(marker_proof_origin(&value.request)),
2122 Self::MarkerMismatch(value) => Some(marker_proof_origin(&value.request)),
2123 Self::Bound(value) | Self::UnboundReceipt(value) => Some(match value {
2124 ReceiptReplay::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2125 ReceiptReplay::CredentialAttach(_) => ClientDiscriminant::CredentialAttachRequest,
2126 }),
2127 Self::DetachCommitted(_) | Self::DetachInProgress(_) => {
2128 Some(ClientDiscriminant::DetachRequest)
2129 }
2130 Self::AckCommitted(_) | Self::AckGap(_) | Self::AckRegression(_) => {
2131 Some(ClientDiscriminant::ParticipantAck)
2132 }
2133 Self::AckNoOp(value) => Some(match value {
2134 AckNoOp::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2135 AckNoOp::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2136 }),
2137 Self::LeaveCommitted(_) => Some(ClientDiscriminant::LeaveRequest),
2138 Self::MarkerAckCommitted(_) => Some(ClientDiscriminant::MarkerAck),
2139 Self::RecordCommitted(_)
2140 | Self::RecordTooLarge(_)
2141 | Self::RecordAdmissionProtocolFault(_) => Some(ClientDiscriminant::RecordAdmission),
2142 Self::MarkerSettlementBackpressure(value) => Some(match value {
2143 MarkerSettlementBackpressure::CredentialAttach { .. } => {
2144 ClientDiscriminant::CredentialAttachRequest
2145 }
2146 MarkerSettlementBackpressure::Detach { .. } => ClientDiscriminant::DetachRequest,
2147 }),
2148 }
2149 }
2150}
2151
2152const fn participant_reference_origin(
2153 request: &ParticipantReferenceEnvelope,
2154) -> ClientDiscriminant {
2155 match request {
2156 ParticipantReferenceEnvelope::CredentialAttach(_) => {
2157 ClientDiscriminant::CredentialAttachRequest
2158 }
2159 ParticipantReferenceEnvelope::Detach(_) => ClientDiscriminant::DetachRequest,
2160 ParticipantReferenceEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2161 ParticipantReferenceEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
2162 ParticipantReferenceEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2163 ParticipantReferenceEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2164 }
2165}
2166
2167const fn binding_required_origin(request: &BindingRequiredEnvelope) -> ClientDiscriminant {
2168 match request {
2169 BindingRequiredEnvelope::Detach(_) => ClientDiscriminant::DetachRequest,
2170 BindingRequiredEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2171 BindingRequiredEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
2172 BindingRequiredEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2173 BindingRequiredEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2174 }
2175}
2176
2177const fn stale_authority_origin(value: &StaleAuthority) -> ClientDiscriminant {
2178 match value {
2179 StaleAuthority::Live { request, .. } => match request {
2180 CommonStaleAuthorityEnvelope::CredentialAttach(_) => {
2181 ClientDiscriminant::CredentialAttachRequest
2182 }
2183 CommonStaleAuthorityEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2184 CommonStaleAuthorityEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2185 CommonStaleAuthorityEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2186 },
2187 StaleAuthority::Detach(_) => ClientDiscriminant::DetachRequest,
2188 StaleAuthority::Leave(_) => ClientDiscriminant::LeaveRequest,
2189 }
2190}
2191
2192const fn marker_proof_origin(request: &MarkerProofRequest) -> ClientDiscriminant {
2193 match request {
2194 MarkerProofRequest::CredentialAttach(_) => ClientDiscriminant::CredentialAttachRequest,
2195 MarkerProofRequest::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2196 }
2197}
2198
2199pub const PARTICIPANT_CAPABILITY: &str = "participant-v1";
2201
2202#[must_use]
2204pub const fn attempt_operation(value: &AttemptTokenBodyConflict) -> super::AttemptOperation {
2205 match value {
2206 AttemptTokenBodyConflict::CredentialAttach { .. } => {
2207 super::AttemptOperation::CredentialAttachRequest
2208 }
2209 AttemptTokenBodyConflict::Leave { .. } => super::AttemptOperation::LeaveRequest,
2210 AttemptTokenBodyConflict::RecordAdmission { .. } => {
2211 super::AttemptOperation::RecordAdmission
2212 }
2213 }
2214}
2215
2216#[must_use]
2218pub fn capability_string() -> String {
2219 String::from(PARTICIPANT_CAPABILITY)
2220}