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, RecordAdmissionEnvelope, ResponseEnvelope, SequenceBudget,
14 ServerDiscriminant,
15};
16
17pub use super::tags::{DetachAuthorityStateTag, LeaveAuthorityStateTag, ResourceDimensionTag};
18
19#[derive(Clone, Debug, PartialEq, Eq)]
21pub struct ParticipantTransportRejected {
22 pub reason: TransportRejectionReason,
24}
25
26#[derive(Clone, Debug, PartialEq, Eq)]
28pub enum TransportRejectionReason {
29 FrameTooLarge {
31 complete_frame_bytes: u64,
33 max_frame_bytes: u64,
35 },
36 DecodeFailed {
38 decode_class: DecodeClass,
40 },
41 UnsupportedVersion {
43 presented_version: ProtocolVersion,
45 supported_version: ProtocolVersion,
47 },
48 AuthenticationFailed,
50 ParticipantCapabilityRequired,
55}
56
57#[derive(Clone, Debug, PartialEq, Eq)]
59pub enum AttemptTokenBodyConflict {
60 CredentialAttach {
62 token: AttachAttemptToken,
64 conversation_id: ConversationId,
66 presented_participant_id: ParticipantId,
68 presented_generation: Generation,
70 presented_marker_delivery_seq: Option<DeliverySeq>,
72 conflict: AttemptConflict,
74 },
75 Leave {
77 token: LeaveAttemptToken,
79 conversation_id: ConversationId,
81 presented_participant_id: ParticipantId,
83 presented_generation: Generation,
85 },
86}
87
88#[derive(Clone, Debug, PartialEq, Eq)]
95pub enum ConnectionConversationCapacityExceeded {
96 SemanticRequest {
98 request: ResponseEnvelope,
100 limit: u64,
102 },
103 ObserverRecovery {
105 conversation_id: ConversationId,
107 limit: u64,
109 },
110}
111
112#[derive(Clone, Debug, PartialEq, Eq)]
114pub enum ConnectionConversationBindingOccupied {
115 Enrollment {
117 conversation_id: ConversationId,
119 enrollment_token: EnrollmentToken,
121 },
122 CredentialAttach {
124 conversation_id: ConversationId,
126 participant_id: ParticipantId,
128 capability_generation: Generation,
130 attach_attempt_token: AttachAttemptToken,
132 accept_marker_delivery_seq: Option<DeliverySeq>,
134 },
135}
136
137#[derive(Clone, Debug, PartialEq, Eq)]
139pub enum OrderAllocatingEnvelope {
140 Enrollment(EnrollmentEnvelope),
142 CredentialAttach(AttachEnvelope),
144 RecordAdmission(RecordAdmissionEnvelope),
146}
147
148#[derive(Clone, Debug, PartialEq, Eq)]
150pub struct ConversationOrderExhausted {
151 request: OrderAllocatingEnvelope,
153 high: u64,
155 order_remaining: u128,
157 reserved_claims: u128,
159 resulting_order_remaining: u128,
161 resulting_reserved_claims: u128,
163}
164
165impl ConversationOrderExhausted {
166 pub const REQUIRED_MAJORS: u64 = 1;
168
169 #[must_use]
175 pub const fn new(
176 request: OrderAllocatingEnvelope,
177 high: u64,
178 order_remaining: u128,
179 reserved_claims: u128,
180 resulting_order_remaining: u128,
181 resulting_reserved_claims: u128,
182 ) -> Self {
183 Self {
184 request,
185 high,
186 order_remaining,
187 reserved_claims,
188 resulting_order_remaining,
189 resulting_reserved_claims,
190 }
191 }
192
193 #[must_use]
195 pub const fn request(&self) -> &OrderAllocatingEnvelope {
196 &self.request
197 }
198
199 #[must_use]
201 pub const fn counter(&self) -> Counter {
202 let _ = self;
203 Counter::TransactionOrder
204 }
205
206 #[must_use]
208 pub const fn high(&self) -> u64 {
209 self.high
210 }
211
212 #[must_use]
214 pub const fn next_value(&self) -> Option<u64> {
215 self.high.checked_add(1)
216 }
217
218 #[must_use]
220 pub const fn order_remaining(&self) -> u128 {
221 self.order_remaining
222 }
223
224 #[must_use]
226 pub const fn reserved_claims(&self) -> u128 {
227 self.reserved_claims
228 }
229
230 #[must_use]
232 pub const fn resulting_order_remaining(&self) -> u128 {
233 self.resulting_order_remaining
234 }
235
236 #[must_use]
238 pub const fn resulting_reserved_claims(&self) -> u128 {
239 self.resulting_reserved_claims
240 }
241}
242
243#[derive(Clone, Debug, PartialEq, Eq)]
245pub enum ParticipantReferenceEnvelope {
246 CredentialAttach(AttachEnvelope),
248 Detach(DetachEnvelope),
250 ParticipantAck(ParticipantAckEnvelope),
252 Leave(LeaveEnvelope),
254 MarkerAck(MarkerAckEnvelope),
256 RecordAdmission(RecordAdmissionEnvelope),
258}
259
260#[derive(Clone, Debug, PartialEq, Eq)]
262pub enum BindingRequiredEnvelope {
263 Detach(DetachEnvelope),
265 ParticipantAck(ParticipantAckEnvelope),
267 Leave(LeaveEnvelope),
269 MarkerAck(MarkerAckEnvelope),
271 RecordAdmission(RecordAdmissionEnvelope),
273}
274
275#[derive(Clone, Debug, PartialEq, Eq)]
277pub struct ParticipantUnknown {
278 pub request: ParticipantReferenceEnvelope,
280}
281
282#[derive(Clone, Debug, PartialEq, Eq)]
284pub struct NoBinding {
285 pub request: BindingRequiredEnvelope,
287}
288
289#[derive(Clone, Copy, Debug, PartialEq, Eq)]
291pub enum BindingStateView {
292 Bound {
294 current_binding_epoch: BindingEpoch,
296 },
297 Detached,
299}
300
301impl BindingStateView {
302 #[must_use]
304 pub const fn tag(self) -> super::BindingStateTag {
305 match self {
306 Self::Bound { .. } => super::BindingStateTag::Bound,
307 Self::Detached => super::BindingStateTag::Detached,
308 }
309 }
310}
311
312#[derive(Clone, Debug, PartialEq, Eq)]
317pub struct TerminalizedDetachCell {
318 conversation_id: ConversationId,
319 participant_id: ParticipantId,
320 capability_generation: Generation,
321 detach_attempt_token: DetachAttemptToken,
322 current_generation: Generation,
323 committed_binding_epoch: BindingEpoch,
324 binding_state: BindingStateView,
325}
326
327impl TerminalizedDetachCell {
328 pub(crate) const fn from_terminalized_state<V>(
336 state: &crate::lifecycle::TerminalizedDetach<V>,
337 conversation_id: ConversationId,
338 current_generation: Generation,
339 binding_state: BindingStateView,
340 ) -> Self {
341 Self {
342 conversation_id,
343 participant_id: state.participant_id(),
344 capability_generation: state.request_generation(),
345 detach_attempt_token: state.token(),
346 current_generation,
347 committed_binding_epoch: state.committed_binding_epoch(),
348 binding_state,
349 }
350 }
351
352 #[allow(clippy::too_many_arguments)]
359 pub(super) const fn from_wire_decode(
360 _authority: super::server_codec::TerminalizedWireDecodeAuthority,
361 conversation_id: ConversationId,
362 participant_id: ParticipantId,
363 capability_generation: Generation,
364 detach_attempt_token: DetachAttemptToken,
365 current_generation: Generation,
366 committed_binding_epoch: BindingEpoch,
367 binding_state: BindingStateView,
368 ) -> Self {
369 Self {
370 conversation_id,
371 participant_id,
372 capability_generation,
373 detach_attempt_token,
374 current_generation,
375 committed_binding_epoch,
376 binding_state,
377 }
378 }
379
380 #[cfg(test)]
381 pub(crate) const fn for_client_test(
382 conversation_id: ConversationId,
383 participant_id: ParticipantId,
384 capability_generation: Generation,
385 detach_attempt_token: DetachAttemptToken,
386 current_generation: Generation,
387 committed_binding_epoch: BindingEpoch,
388 binding_state: BindingStateView,
389 ) -> Self {
390 Self {
391 conversation_id,
392 participant_id,
393 capability_generation,
394 detach_attempt_token,
395 current_generation,
396 committed_binding_epoch,
397 binding_state,
398 }
399 }
400
401 #[must_use]
403 pub const fn conversation_id(&self) -> ConversationId {
404 self.conversation_id
405 }
406
407 #[must_use]
409 pub const fn participant_id(&self) -> ParticipantId {
410 self.participant_id
411 }
412
413 #[must_use]
415 pub const fn capability_generation(&self) -> Generation {
416 self.capability_generation
417 }
418
419 #[must_use]
421 pub const fn detach_attempt_token(&self) -> DetachAttemptToken {
422 self.detach_attempt_token
423 }
424
425 #[must_use]
427 pub const fn current_generation(&self) -> Generation {
428 self.current_generation
429 }
430
431 #[must_use]
433 pub const fn committed_binding_epoch(&self) -> BindingEpoch {
434 self.committed_binding_epoch
435 }
436
437 #[must_use]
439 pub const fn binding_state(&self) -> BindingStateView {
440 self.binding_state
441 }
442}
443
444#[derive(Clone, Debug, PartialEq, Eq)]
446pub enum DetachStaleAuthority {
447 Live {
449 conversation_id: ConversationId,
451 participant_id: ParticipantId,
453 capability_generation: Generation,
455 detach_attempt_token: DetachAttemptToken,
457 current_generation: Generation,
459 },
460 TerminalizedDetachCell(TerminalizedDetachCell),
462}
463
464impl DetachStaleAuthority {
465 #[must_use]
467 pub const fn authority_state_tag(&self) -> DetachAuthorityStateTag {
468 match self {
469 Self::Live { .. } => DetachAuthorityStateTag::Live,
470 Self::TerminalizedDetachCell(_) => DetachAuthorityStateTag::TerminalizedDetachCell,
471 }
472 }
473}
474
475#[derive(Clone, Debug, PartialEq, Eq)]
477pub enum LeaveStaleAuthority {
478 Live {
480 conversation_id: ConversationId,
482 participant_id: ParticipantId,
484 presented_generation: Generation,
486 leave_attempt_token: LeaveAttemptToken,
488 current_generation: Generation,
490 },
491 CommittedLeaveTombstone {
493 conversation_id: ConversationId,
495 participant_id: ParticipantId,
497 presented_generation: Generation,
499 leave_attempt_token: LeaveAttemptToken,
501 retired_generation: Generation,
503 },
504}
505
506impl LeaveStaleAuthority {
507 #[must_use]
509 pub const fn authority_state_tag(&self) -> LeaveAuthorityStateTag {
510 match self {
511 Self::Live { .. } => LeaveAuthorityStateTag::Live,
512 Self::CommittedLeaveTombstone { .. } => LeaveAuthorityStateTag::CommittedLeaveTombstone,
513 }
514 }
515}
516
517#[derive(Clone, Debug, PartialEq, Eq)]
519pub enum CommonStaleAuthorityEnvelope {
520 CredentialAttach(AttachEnvelope),
522 ParticipantAck(ParticipantAckEnvelope),
524 MarkerAck(MarkerAckEnvelope),
526 RecordAdmission(RecordAdmissionEnvelope),
528}
529
530#[derive(Clone, Debug, PartialEq, Eq)]
532pub enum StaleAuthority {
533 Live {
535 request: CommonStaleAuthorityEnvelope,
537 current_generation: Generation,
539 },
540 Detach(DetachStaleAuthority),
542 Leave(LeaveStaleAuthority),
544}
545
546#[derive(Clone, Debug, PartialEq, Eq)]
548pub enum Retired {
549 Enrollment {
551 request: EnrollmentEnvelope,
553 participant_id: ParticipantId,
555 retired_generation: Generation,
557 },
558 Participant {
560 request: ParticipantReferenceEnvelope,
562 retired_generation: Generation,
564 },
565}
566
567#[derive(Clone, Debug, PartialEq, Eq)]
569pub struct EnrollBound {
570 conversation_id: ConversationId,
571 token: EnrollmentToken,
572 participant_id: ParticipantId,
573 attach_secret: AttachSecret,
574 origin_binding_epoch: BindingEpoch,
575 receipt_expires_at: u128,
576 provenance_expires_at: u128,
577}
578
579impl EnrollBound {
580 #[must_use]
587 pub const fn new(
588 conversation_id: ConversationId,
589 token: EnrollmentToken,
590 participant_id: ParticipantId,
591 attach_secret: AttachSecret,
592 origin_binding_epoch: BindingEpoch,
593 receipt_expires_at: u128,
594 provenance_expires_at: u128,
595 ) -> Option<Self> {
596 if origin_binding_epoch.capability_generation.get() == 1 {
597 Some(Self {
598 conversation_id,
599 token,
600 participant_id,
601 attach_secret,
602 origin_binding_epoch,
603 receipt_expires_at,
604 provenance_expires_at,
605 })
606 } else {
607 None
608 }
609 }
610
611 #[must_use]
613 pub const fn conversation_id(&self) -> ConversationId {
614 self.conversation_id
615 }
616
617 #[must_use]
619 pub const fn token(&self) -> EnrollmentToken {
620 self.token
621 }
622
623 #[must_use]
625 pub const fn participant_id(&self) -> ParticipantId {
626 self.participant_id
627 }
628
629 #[must_use]
631 pub const fn request_generation(&self) -> Option<Generation> {
632 None
633 }
634
635 #[must_use]
637 pub const fn capability_generation(&self) -> Generation {
638 self.origin_binding_epoch.capability_generation
639 }
640
641 #[must_use]
643 pub const fn attach_secret(&self) -> AttachSecret {
644 self.attach_secret
645 }
646
647 #[must_use]
649 pub const fn origin_binding_epoch(&self) -> BindingEpoch {
650 self.origin_binding_epoch
651 }
652
653 #[must_use]
655 pub const fn persisted_cursor(&self) -> DeliverySeq {
656 0
657 }
658
659 #[must_use]
661 pub const fn accepted_marker_delivery_seq(&self) -> Option<DeliverySeq> {
662 None
663 }
664
665 #[must_use]
667 pub const fn receipt_expires_at(&self) -> u128 {
668 self.receipt_expires_at
669 }
670
671 #[must_use]
673 pub const fn provenance_expires_at(&self) -> u128 {
674 self.provenance_expires_at
675 }
676}
677
678#[derive(Clone, Debug, PartialEq, Eq)]
680pub struct EnrollmentKnown {
681 pub conversation_id: ConversationId,
683 pub token: EnrollmentToken,
685 pub participant_id: ParticipantId,
687 pub current_generation: Generation,
689}
690
691#[derive(Clone, Debug, PartialEq, Eq)]
693pub enum ReceiptExpired {
694 Enrollment {
696 conversation_id: ConversationId,
698 token: EnrollmentToken,
700 participant_id: ParticipantId,
702 result_generation: Generation,
704 current_generation: Generation,
706 reason: ReceiptExpiryReason,
708 },
709 CredentialAttach {
711 conversation_id: ConversationId,
713 token: AttachAttemptToken,
715 participant_id: ParticipantId,
717 presented_generation: Generation,
719 presented_marker_delivery_seq: Option<DeliverySeq>,
721 result_generation: Generation,
723 current_generation: Generation,
725 reason: ReceiptExpiryReason,
727 },
728}
729
730#[derive(Clone, Copy, Debug, PartialEq, Eq)]
735pub enum EnrollmentReceiptCapacityScope {
736 LiveReceiptServer,
738 ProvenanceServer,
740 ProvenanceConversation,
742}
743
744impl EnrollmentReceiptCapacityScope {
745 #[must_use]
747 pub const fn wire_scope(self) -> ReceiptCapacityScope {
748 match self {
749 Self::LiveReceiptServer => ReceiptCapacityScope::LiveReceiptServer,
750 Self::ProvenanceServer => ReceiptCapacityScope::ProvenanceServer,
751 Self::ProvenanceConversation => ReceiptCapacityScope::ProvenanceConversation,
752 }
753 }
754}
755
756#[derive(Clone, Debug, PartialEq, Eq)]
758pub enum ReceiptCapacityExceeded {
759 Enrollment {
761 request: EnrollmentEnvelope,
763 scope: EnrollmentReceiptCapacityScope,
765 limit: u64,
767 occupied: u64,
769 },
770 CredentialAttach {
772 request: AttachEnvelope,
774 scope: ReceiptCapacityScope,
776 limit: u64,
778 occupied: u64,
780 },
781}
782
783impl ReceiptCapacityExceeded {
784 pub const REQUESTED: u64 = 1;
786}
787
788#[derive(Clone, Debug, PartialEq, Eq)]
790pub struct IdentityCapacityExceeded {
791 pub request: EnrollmentEnvelope,
793 pub scope: IdentityCapacityScope,
795 pub limit: u64,
797 pub occupied: u64,
799}
800
801impl IdentityCapacityExceeded {
802 pub const REQUESTED: u64 = 1;
804}
805
806#[derive(Clone, Copy, Debug, PartialEq, Eq)]
808pub struct ObserverBackpressureState {
809 backpressure_epoch: ObserverEpoch,
811 observer_progress: DeliverySeq,
813}
814
815impl ObserverBackpressureState {
816 #[must_use]
821 pub const fn initial(observer_progress: DeliverySeq) -> Self {
822 Self {
823 backpressure_epoch: observer_progress,
824 observer_progress,
825 }
826 }
827
828 #[must_use]
834 pub const fn replay(
835 backpressure_epoch: ObserverEpoch,
836 observer_progress: DeliverySeq,
837 ) -> Option<Self> {
838 if backpressure_epoch == observer_progress {
839 Some(Self {
840 backpressure_epoch,
841 observer_progress,
842 })
843 } else {
844 None
845 }
846 }
847
848 #[must_use]
850 pub const fn backpressure_epoch(self) -> ObserverEpoch {
851 self.backpressure_epoch
852 }
853
854 #[must_use]
856 pub const fn observer_progress(self) -> DeliverySeq {
857 self.observer_progress
858 }
859}
860
861#[derive(Clone, Debug, PartialEq, Eq)]
863pub enum ObserverBackpressure {
864 Enrollment {
866 request: EnrollmentEnvelope,
868 state: ObserverBackpressureState,
870 },
871 CredentialAttach {
873 request: AttachEnvelope,
875 state: ObserverBackpressureState,
877 },
878 Detach {
880 request: DetachEnvelope,
882 committed_binding_epoch: BindingEpoch,
884 state: ObserverBackpressureState,
886 },
887 Leave {
889 request: LeaveEnvelope,
891 state: ObserverBackpressureState,
893 prior_terminal_cell_exists: bool,
895 },
896 RecordAdmission {
898 request: RecordAdmissionEnvelope,
900 state: ObserverBackpressureState,
902 },
903}
904
905#[derive(Clone, Debug, PartialEq, Eq)]
907pub enum SequenceAllocatingEnvelope {
908 Enrollment(EnrollmentEnvelope),
910 CredentialAttach(AttachEnvelope),
912 RecordAdmission(RecordAdmissionEnvelope),
914}
915
916#[derive(Clone, Debug, PartialEq, Eq)]
918pub struct ConversationSequenceExhausted {
919 pub request: SequenceAllocatingEnvelope,
921 pub sequence_budget: SequenceBudget,
923}
924
925#[derive(Clone, Debug, PartialEq, Eq)]
927pub struct AttachBound {
928 conversation_id: ConversationId,
930 token: AttachAttemptToken,
932 participant_id: ParticipantId,
934 request_generation: Generation,
936 attach_secret: AttachSecret,
938 origin_binding_epoch: BindingEpoch,
940 persisted_cursor: DeliverySeq,
942 accepted_marker_delivery_seq: Option<DeliverySeq>,
944 receipt_expires_at: u128,
946 provenance_expires_at: u128,
948}
949
950impl AttachBound {
951 #[must_use]
957 #[allow(clippy::too_many_arguments)]
958 pub const fn ordinary(
959 conversation_id: ConversationId,
960 token: AttachAttemptToken,
961 participant_id: ParticipantId,
962 request_generation: Generation,
963 attach_secret: AttachSecret,
964 origin_binding_epoch: BindingEpoch,
965 persisted_cursor: DeliverySeq,
966 receipt_expires_at: u128,
967 provenance_expires_at: u128,
968 ) -> Option<Self> {
969 if !is_successor_generation(
970 request_generation,
971 origin_binding_epoch.capability_generation,
972 ) {
973 return None;
974 }
975 Some(Self {
976 conversation_id,
977 token,
978 participant_id,
979 request_generation,
980 attach_secret,
981 origin_binding_epoch,
982 persisted_cursor,
983 accepted_marker_delivery_seq: None,
984 receipt_expires_at,
985 provenance_expires_at,
986 })
987 }
988
989 #[must_use]
995 #[allow(clippy::too_many_arguments)]
996 pub const fn fenced(
997 conversation_id: ConversationId,
998 token: AttachAttemptToken,
999 participant_id: ParticipantId,
1000 request_generation: Generation,
1001 attach_secret: AttachSecret,
1002 origin_binding_epoch: BindingEpoch,
1003 accepted_marker_delivery_seq: DeliverySeq,
1004 receipt_expires_at: u128,
1005 provenance_expires_at: u128,
1006 ) -> Option<Self> {
1007 if !is_successor_generation(
1008 request_generation,
1009 origin_binding_epoch.capability_generation,
1010 ) {
1011 return None;
1012 }
1013 Some(Self {
1014 conversation_id,
1015 token,
1016 participant_id,
1017 request_generation,
1018 attach_secret,
1019 origin_binding_epoch,
1020 persisted_cursor: accepted_marker_delivery_seq,
1021 accepted_marker_delivery_seq: Some(accepted_marker_delivery_seq),
1022 receipt_expires_at,
1023 provenance_expires_at,
1024 })
1025 }
1026
1027 #[must_use]
1029 pub const fn conversation_id(&self) -> ConversationId {
1030 self.conversation_id
1031 }
1032
1033 #[must_use]
1035 pub const fn token(&self) -> AttachAttemptToken {
1036 self.token
1037 }
1038
1039 #[must_use]
1041 pub const fn participant_id(&self) -> ParticipantId {
1042 self.participant_id
1043 }
1044
1045 #[must_use]
1047 pub const fn request_generation(&self) -> Generation {
1048 self.request_generation
1049 }
1050
1051 #[must_use]
1053 pub const fn capability_generation(&self) -> Generation {
1054 self.origin_binding_epoch.capability_generation
1055 }
1056
1057 #[must_use]
1059 pub const fn attach_secret(&self) -> AttachSecret {
1060 self.attach_secret
1061 }
1062
1063 #[must_use]
1065 pub const fn origin_binding_epoch(&self) -> BindingEpoch {
1066 self.origin_binding_epoch
1067 }
1068
1069 #[must_use]
1071 pub const fn persisted_cursor(&self) -> DeliverySeq {
1072 self.persisted_cursor
1073 }
1074
1075 #[must_use]
1077 pub const fn accepted_marker_delivery_seq(&self) -> Option<DeliverySeq> {
1078 self.accepted_marker_delivery_seq
1079 }
1080
1081 #[must_use]
1083 pub const fn receipt_expires_at(&self) -> u128 {
1084 self.receipt_expires_at
1085 }
1086
1087 #[must_use]
1089 pub const fn provenance_expires_at(&self) -> u128 {
1090 self.provenance_expires_at
1091 }
1092}
1093
1094const fn is_successor_generation(previous: Generation, successor: Generation) -> bool {
1095 match previous.get().checked_add(1) {
1096 Some(expected) => successor.get() == expected,
1097 None => false,
1098 }
1099}
1100
1101#[derive(Clone, Debug, PartialEq, Eq)]
1103pub struct StaleOrUnknownReceipt {
1104 pub conversation_id: ConversationId,
1106 pub token: AttachAttemptToken,
1108 pub participant_id: ParticipantId,
1110 pub presented_generation: Generation,
1112 pub presented_marker_delivery_seq: Option<DeliverySeq>,
1114 pub current_generation: Generation,
1116}
1117
1118#[derive(Clone, Debug, PartialEq, Eq)]
1120pub struct AttachMarkerProof {
1121 pub conversation_id: ConversationId,
1123 pub token: AttachAttemptToken,
1125 pub participant_id: ParticipantId,
1127 pub capability_generation: Generation,
1129 pub requested_marker_delivery_seq: DeliverySeq,
1131}
1132
1133#[derive(Clone, Debug, PartialEq, Eq)]
1135pub struct MarkerAckProof {
1136 pub conversation_id: ConversationId,
1138 pub participant_id: ParticipantId,
1140 pub capability_generation: Generation,
1142 pub requested_marker_delivery_seq: DeliverySeq,
1144}
1145
1146#[derive(Clone, Debug, PartialEq, Eq)]
1148pub enum MarkerProofRequest {
1149 CredentialAttach(AttachMarkerProof),
1151 MarkerAck(MarkerAckProof),
1153}
1154
1155#[derive(Clone, Debug, PartialEq, Eq)]
1157pub struct MarkerNotDelivered {
1158 pub request: MarkerProofRequest,
1160 pub reason: MarkerNotDeliveredReason,
1162 pub expected_marker_delivery_seq: DeliverySeq,
1164}
1165
1166#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1168pub enum MarkerMismatchBody {
1169 BelowCursor {
1171 current_cursor: DeliverySeq,
1173 },
1174 NoMarkerExpected,
1176 ExpectedDifferentMarker {
1178 expected_marker_delivery_seq: DeliverySeq,
1180 },
1181}
1182
1183impl MarkerMismatchBody {
1184 #[must_use]
1186 pub const fn reason(self) -> MarkerMismatchReason {
1187 match self {
1188 Self::BelowCursor { .. } => MarkerMismatchReason::BelowCursor,
1189 Self::NoMarkerExpected => MarkerMismatchReason::NoMarkerExpected,
1190 Self::ExpectedDifferentMarker { .. } => MarkerMismatchReason::ExpectedDifferentMarker,
1191 }
1192 }
1193}
1194
1195#[derive(Clone, Debug, PartialEq, Eq)]
1197pub struct MarkerMismatch {
1198 pub request: MarkerProofRequest,
1200 pub mismatch: MarkerMismatchBody,
1202}
1203
1204#[derive(Clone, Debug, PartialEq, Eq)]
1206pub enum ReceiptReplay {
1207 Enrollment(EnrollBound),
1210 CredentialAttach(AttachBound),
1213}
1214
1215#[derive(Clone, Debug, PartialEq, Eq)]
1217pub struct DetachCommitted {
1218 conversation_id: ConversationId,
1220 participant_id: ParticipantId,
1222 detach_attempt_token: DetachAttemptToken,
1224 committed_binding_epoch: BindingEpoch,
1226 detached_delivery_seq: DeliverySeq,
1228}
1229
1230impl DetachCommitted {
1231 #[must_use]
1234 pub const fn new(
1235 conversation_id: ConversationId,
1236 participant_id: ParticipantId,
1237 detach_attempt_token: DetachAttemptToken,
1238 committed_binding_epoch: BindingEpoch,
1239 detached_delivery_seq: DeliverySeq,
1240 ) -> Self {
1241 Self {
1242 conversation_id,
1243 participant_id,
1244 detach_attempt_token,
1245 committed_binding_epoch,
1246 detached_delivery_seq,
1247 }
1248 }
1249
1250 #[must_use]
1252 pub const fn conversation_id(&self) -> ConversationId {
1253 self.conversation_id
1254 }
1255
1256 #[must_use]
1258 pub const fn participant_id(&self) -> ParticipantId {
1259 self.participant_id
1260 }
1261
1262 #[must_use]
1264 pub const fn capability_generation(&self) -> Generation {
1265 self.committed_binding_epoch.capability_generation
1266 }
1267
1268 #[must_use]
1270 pub const fn detach_attempt_token(&self) -> DetachAttemptToken {
1271 self.detach_attempt_token
1272 }
1273
1274 #[must_use]
1276 pub const fn committed_binding_epoch(&self) -> BindingEpoch {
1277 self.committed_binding_epoch
1278 }
1279
1280 #[must_use]
1282 pub const fn detached_delivery_seq(&self) -> DeliverySeq {
1283 self.detached_delivery_seq
1284 }
1285}
1286
1287#[derive(Clone, Debug, PartialEq, Eq)]
1289pub struct DetachInProgress {
1290 pub conversation_id: ConversationId,
1292 pub participant_id: ParticipantId,
1294 pub presented_token: DetachAttemptToken,
1296 pub presented_generation: Generation,
1298 pub committed_binding_epoch: BindingEpoch,
1300}
1301
1302#[derive(Clone, Debug, PartialEq, Eq)]
1304pub struct AckCommitted {
1305 request: ParticipantAckEnvelope,
1307}
1308
1309impl AckCommitted {
1310 #[must_use]
1313 pub const fn new(request: ParticipantAckEnvelope) -> Self {
1314 Self { request }
1315 }
1316
1317 #[must_use]
1319 pub const fn request(&self) -> &ParticipantAckEnvelope {
1320 &self.request
1321 }
1322
1323 #[must_use]
1325 pub const fn current_cursor(&self) -> DeliverySeq {
1326 self.request.through_seq
1327 }
1328}
1329
1330#[derive(Clone, Debug, PartialEq, Eq)]
1332pub enum AckNoOp {
1333 ParticipantAck(ParticipantAckEnvelope),
1335 MarkerAck(MarkerAckEnvelope),
1337}
1338
1339impl AckNoOp {
1340 #[must_use]
1343 pub const fn participant_ack(request: ParticipantAckEnvelope) -> Self {
1344 Self::ParticipantAck(request)
1345 }
1346
1347 #[must_use]
1350 pub const fn marker_ack(request: MarkerAckEnvelope) -> Self {
1351 Self::MarkerAck(request)
1352 }
1353
1354 #[must_use]
1356 pub const fn current_cursor(&self) -> DeliverySeq {
1357 match self {
1358 Self::ParticipantAck(request) => request.through_seq,
1359 Self::MarkerAck(request) => request.marker_delivery_seq,
1360 }
1361 }
1362}
1363
1364#[derive(Clone, Debug, PartialEq, Eq)]
1366pub struct AckGap {
1367 request: ParticipantAckEnvelope,
1369 current_cursor: DeliverySeq,
1371}
1372
1373impl AckGap {
1374 #[must_use]
1377 pub const fn new(request: ParticipantAckEnvelope, current_cursor: DeliverySeq) -> Option<Self> {
1378 if request.through_seq > current_cursor {
1379 Some(Self {
1380 request,
1381 current_cursor,
1382 })
1383 } else {
1384 None
1385 }
1386 }
1387
1388 #[must_use]
1390 pub const fn request(&self) -> &ParticipantAckEnvelope {
1391 &self.request
1392 }
1393
1394 #[must_use]
1396 pub const fn current_cursor(&self) -> DeliverySeq {
1397 self.current_cursor
1398 }
1399
1400 #[must_use]
1402 pub const fn reason(&self) -> AckGapReason {
1403 let _ = self;
1404 AckGapReason::NotContiguouslyAvailable
1405 }
1406}
1407
1408#[derive(Clone, Debug, PartialEq, Eq)]
1410pub struct AckRegression {
1411 request: ParticipantAckEnvelope,
1413 current_cursor: DeliverySeq,
1415}
1416
1417impl AckRegression {
1418 #[must_use]
1421 pub const fn new(request: ParticipantAckEnvelope, current_cursor: DeliverySeq) -> Option<Self> {
1422 if request.through_seq < current_cursor {
1423 Some(Self {
1424 request,
1425 current_cursor,
1426 })
1427 } else {
1428 None
1429 }
1430 }
1431
1432 #[must_use]
1434 pub const fn request(&self) -> &ParticipantAckEnvelope {
1435 &self.request
1436 }
1437
1438 #[must_use]
1440 pub const fn current_cursor(&self) -> DeliverySeq {
1441 self.current_cursor
1442 }
1443
1444 #[must_use]
1446 pub const fn reason(&self) -> AckRegressionReason {
1447 let _ = self;
1448 AckRegressionReason::BelowCursor
1449 }
1450}
1451
1452#[derive(Clone, Debug, PartialEq, Eq)]
1454pub struct LeaveCommitted {
1455 conversation_id: ConversationId,
1457 leave_attempt_token: LeaveAttemptToken,
1459 participant_id: ParticipantId,
1461 retired_generation: Generation,
1463 ended_binding_epoch: Option<BindingEpoch>,
1465 prior_terminal_delivery_seq: Option<DeliverySeq>,
1467 left_delivery_seq: DeliverySeq,
1469}
1470
1471impl LeaveCommitted {
1472 #[must_use]
1478 #[allow(clippy::too_many_arguments)]
1479 pub const fn new(
1480 conversation_id: ConversationId,
1481 leave_attempt_token: LeaveAttemptToken,
1482 participant_id: ParticipantId,
1483 retired_generation: Generation,
1484 ended_binding_epoch: Option<BindingEpoch>,
1485 prior_terminal_delivery_seq: Option<DeliverySeq>,
1486 left_delivery_seq: DeliverySeq,
1487 ) -> Option<Self> {
1488 if let Some(epoch) = ended_binding_epoch
1489 && epoch.capability_generation.get() != retired_generation.get()
1490 {
1491 return None;
1492 }
1493 if let Some(prior) = prior_terminal_delivery_seq
1494 && prior >= left_delivery_seq
1495 {
1496 return None;
1497 }
1498 Some(Self {
1499 conversation_id,
1500 leave_attempt_token,
1501 participant_id,
1502 retired_generation,
1503 ended_binding_epoch,
1504 prior_terminal_delivery_seq,
1505 left_delivery_seq,
1506 })
1507 }
1508
1509 #[must_use]
1511 pub const fn conversation_id(&self) -> ConversationId {
1512 self.conversation_id
1513 }
1514
1515 #[must_use]
1517 pub const fn leave_attempt_token(&self) -> LeaveAttemptToken {
1518 self.leave_attempt_token
1519 }
1520
1521 #[must_use]
1523 pub const fn participant_id(&self) -> ParticipantId {
1524 self.participant_id
1525 }
1526
1527 #[must_use]
1529 pub const fn presented_generation(&self) -> Generation {
1530 self.retired_generation
1531 }
1532
1533 #[must_use]
1535 pub const fn retired_generation(&self) -> Generation {
1536 self.retired_generation
1537 }
1538
1539 #[must_use]
1541 pub const fn ended_binding_epoch(&self) -> Option<BindingEpoch> {
1542 self.ended_binding_epoch
1543 }
1544
1545 #[must_use]
1547 pub const fn prior_terminal_delivery_seq(&self) -> Option<DeliverySeq> {
1548 self.prior_terminal_delivery_seq
1549 }
1550
1551 #[must_use]
1553 pub const fn left_delivery_seq(&self) -> DeliverySeq {
1554 self.left_delivery_seq
1555 }
1556}
1557
1558#[derive(Clone, Debug, PartialEq, Eq)]
1560pub struct MarkerAckCommitted {
1561 request: MarkerAckEnvelope,
1563}
1564
1565impl MarkerAckCommitted {
1566 #[must_use]
1569 pub const fn new(request: MarkerAckEnvelope) -> Self {
1570 Self { request }
1571 }
1572
1573 #[must_use]
1575 pub const fn request(&self) -> &MarkerAckEnvelope {
1576 &self.request
1577 }
1578
1579 #[must_use]
1581 pub const fn current_cursor(&self) -> DeliverySeq {
1582 self.request.marker_delivery_seq
1583 }
1584}
1585
1586#[derive(Clone, Debug, PartialEq, Eq)]
1588pub struct RecordCommitted {
1589 request: RecordAdmissionEnvelope,
1591 delivery_seq: DeliverySeq,
1593}
1594
1595impl RecordCommitted {
1596 #[must_use]
1599 pub const fn new(request: RecordAdmissionEnvelope, delivery_seq: DeliverySeq) -> Self {
1600 Self {
1601 request,
1602 delivery_seq,
1603 }
1604 }
1605
1606 #[must_use]
1608 pub const fn request(&self) -> &RecordAdmissionEnvelope {
1609 &self.request
1610 }
1611
1612 #[must_use]
1614 pub const fn sender_participant_id(&self) -> ParticipantId {
1615 self.request.participant_id
1616 }
1617
1618 #[must_use]
1620 pub const fn delivery_seq(&self) -> DeliverySeq {
1621 self.delivery_seq
1622 }
1623}
1624
1625#[derive(Clone, Debug, PartialEq, Eq)]
1627pub struct RecordTooLarge {
1628 pub request: RecordAdmissionEnvelope,
1630 pub dimension: ResourceDimension,
1632 pub encoded_record_charge: ResourceVector,
1634 pub max_ordinary_record_charge: ResourceVector,
1636}
1637
1638#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1640pub struct ObserverProgressStatus {
1641 pub conversation_id: ConversationId,
1643 pub refused_epoch: ObserverEpoch,
1645 pub current_observer_progress: DeliverySeq,
1647 pub armed: bool,
1649 pub progressed: bool,
1651}
1652
1653#[derive(Clone, Debug, PartialEq, Eq)]
1655pub struct ObserverRecoveryAccepted {
1656 pub statuses: Vec<ObserverProgressStatus>,
1658}
1659
1660#[derive(Clone, Debug, PartialEq, Eq)]
1662pub enum InvalidObserverEpoch {
1663 ConversationUnknown {
1665 conversation_id: ConversationId,
1667 presented_epoch: ObserverEpoch,
1669 },
1670 EpochAhead {
1672 conversation_id: ConversationId,
1674 presented_epoch: ObserverEpoch,
1676 current_observer_progress: DeliverySeq,
1678 },
1679}
1680
1681impl InvalidObserverEpoch {
1682 #[must_use]
1684 pub const fn reason(&self) -> InvalidObserverEpochReason {
1685 match self {
1686 Self::ConversationUnknown { .. } => InvalidObserverEpochReason::ConversationUnknown,
1687 Self::EpochAhead { .. } => InvalidObserverEpochReason::EpochAhead,
1688 }
1689 }
1690}
1691
1692#[derive(Clone, Debug, PartialEq, Eq)]
1694pub enum InvalidObserverEpochList {
1695 TooManyEntries {
1697 presented_entries: u64,
1699 max_entries: u64,
1701 },
1702 DuplicateConversation {
1704 conversation_id: ConversationId,
1706 first_index: u64,
1708 duplicate_index: u64,
1710 },
1711}
1712
1713impl InvalidObserverEpochList {
1714 #[must_use]
1716 pub const fn reason(&self) -> InvalidObserverEpochListReason {
1717 match self {
1718 Self::TooManyEntries { .. } => InvalidObserverEpochListReason::TooManyEntries,
1719 Self::DuplicateConversation { .. } => {
1720 InvalidObserverEpochListReason::DuplicateConversation
1721 }
1722 }
1723 }
1724}
1725
1726#[derive(Clone, Debug, PartialEq, Eq)]
1728pub enum ServerValue {
1729 ParticipantTransportRejected(ParticipantTransportRejected),
1731 AttemptTokenBodyConflict(AttemptTokenBodyConflict),
1733 ConnectionConversationCapacityExceeded(ConnectionConversationCapacityExceeded),
1735 ConnectionConversationBindingOccupied(ConnectionConversationBindingOccupied),
1737 ConversationOrderExhausted(Box<ConversationOrderExhausted>),
1739 ParticipantUnknown(ParticipantUnknown),
1741 NoBinding(NoBinding),
1743 StaleAuthority(StaleAuthority),
1745 Retired(Retired),
1747 MarkerClosureCapacityExceeded(Box<MarkerClosureCapacityExceeded>),
1749 EnrollBound(EnrollBound),
1751 EnrollmentKnown(EnrollmentKnown),
1753 ReceiptExpired(ReceiptExpired),
1755 ReceiptCapacityExceeded(ReceiptCapacityExceeded),
1757 IdentityCapacityExceeded(IdentityCapacityExceeded),
1759 ObserverBackpressure(ObserverBackpressure),
1761 ConversationSequenceExhausted(Box<ConversationSequenceExhausted>),
1763 AttachBound(AttachBound),
1765 StaleOrUnknownReceipt(StaleOrUnknownReceipt),
1767 MarkerNotDelivered(MarkerNotDelivered),
1769 MarkerMismatch(MarkerMismatch),
1771 Bound(ReceiptReplay),
1773 UnboundReceipt(ReceiptReplay),
1775 DetachCommitted(DetachCommitted),
1777 DetachInProgress(DetachInProgress),
1779 AckCommitted(AckCommitted),
1781 AckNoOp(AckNoOp),
1783 AckGap(AckGap),
1785 AckRegression(AckRegression),
1787 LeaveCommitted(LeaveCommitted),
1789 MarkerAckCommitted(MarkerAckCommitted),
1791 RecordCommitted(RecordCommitted),
1793 RecordTooLarge(RecordTooLarge),
1795 ObserverRecoveryAccepted(ObserverRecoveryAccepted),
1797 InvalidObserverEpoch(InvalidObserverEpoch),
1799 InvalidObserverEpochList(InvalidObserverEpochList),
1801}
1802
1803impl ServerValue {
1804 #[must_use]
1806 pub const fn discriminant(&self) -> ServerDiscriminant {
1807 match self {
1808 Self::ParticipantTransportRejected(_) => {
1809 ServerDiscriminant::ParticipantTransportRejected
1810 }
1811 Self::AttemptTokenBodyConflict(_) => ServerDiscriminant::AttemptTokenBodyConflict,
1812 Self::ConnectionConversationCapacityExceeded(value) => match value {
1813 ConnectionConversationCapacityExceeded::SemanticRequest { .. } => {
1814 ServerDiscriminant::ConnectionConversationCapacityExceeded
1815 }
1816 ConnectionConversationCapacityExceeded::ObserverRecovery { .. } => {
1817 ServerDiscriminant::ObserverRecoveryConnectionCapacityExceeded
1818 }
1819 },
1820 Self::ConnectionConversationBindingOccupied(_) => {
1821 ServerDiscriminant::ConnectionConversationBindingOccupied
1822 }
1823 Self::ConversationOrderExhausted(_) => ServerDiscriminant::ConversationOrderExhausted,
1824 Self::ParticipantUnknown(_) => ServerDiscriminant::ParticipantUnknown,
1825 Self::NoBinding(_) => ServerDiscriminant::NoBinding,
1826 Self::StaleAuthority(_) => ServerDiscriminant::StaleAuthority,
1827 Self::Retired(_) => ServerDiscriminant::Retired,
1828 Self::MarkerClosureCapacityExceeded(_) => {
1829 ServerDiscriminant::MarkerClosureCapacityExceeded
1830 }
1831 Self::EnrollBound(_) => ServerDiscriminant::EnrollBound,
1832 Self::EnrollmentKnown(_) => ServerDiscriminant::EnrollmentKnown,
1833 Self::ReceiptExpired(_) => ServerDiscriminant::ReceiptExpired,
1834 Self::ReceiptCapacityExceeded(_) => ServerDiscriminant::ReceiptCapacityExceeded,
1835 Self::IdentityCapacityExceeded(_) => ServerDiscriminant::IdentityCapacityExceeded,
1836 Self::ObserverBackpressure(_) => ServerDiscriminant::ObserverBackpressure,
1837 Self::ConversationSequenceExhausted(_) => {
1838 ServerDiscriminant::ConversationSequenceExhausted
1839 }
1840 Self::AttachBound(_) => ServerDiscriminant::AttachBound,
1841 Self::StaleOrUnknownReceipt(_) => ServerDiscriminant::StaleOrUnknownReceipt,
1842 Self::MarkerNotDelivered(_) => ServerDiscriminant::MarkerNotDelivered,
1843 Self::MarkerMismatch(_) => ServerDiscriminant::MarkerMismatch,
1844 Self::Bound(_) => ServerDiscriminant::Bound,
1845 Self::UnboundReceipt(_) => ServerDiscriminant::UnboundReceipt,
1846 Self::DetachCommitted(_) => ServerDiscriminant::DetachCommitted,
1847 Self::DetachInProgress(_) => ServerDiscriminant::DetachInProgress,
1848 Self::AckCommitted(_) => ServerDiscriminant::AckCommitted,
1849 Self::AckNoOp(_) => ServerDiscriminant::AckNoOp,
1850 Self::AckGap(_) => ServerDiscriminant::AckGap,
1851 Self::AckRegression(_) => ServerDiscriminant::AckRegression,
1852 Self::LeaveCommitted(_) => ServerDiscriminant::LeaveCommitted,
1853 Self::MarkerAckCommitted(_) => ServerDiscriminant::MarkerAckCommitted,
1854 Self::RecordCommitted(_) => ServerDiscriminant::RecordCommitted,
1855 Self::RecordTooLarge(_) => ServerDiscriminant::RecordTooLarge,
1856 Self::ObserverRecoveryAccepted(_) => ServerDiscriminant::ObserverRecoveryAccepted,
1857 Self::InvalidObserverEpoch(_) => ServerDiscriminant::InvalidObserverEpoch,
1858 Self::InvalidObserverEpochList(_) => ServerDiscriminant::InvalidObserverEpochList,
1859 }
1860 }
1861
1862 #[must_use]
1864 #[allow(clippy::too_many_lines)]
1865 pub const fn originating_request(&self) -> Option<ClientDiscriminant> {
1866 match self {
1867 Self::ParticipantTransportRejected(_)
1868 | Self::ObserverRecoveryAccepted(_)
1869 | Self::InvalidObserverEpoch(_)
1870 | Self::InvalidObserverEpochList(_) => None,
1871 Self::AttemptTokenBodyConflict(value) => Some(match value {
1872 AttemptTokenBodyConflict::CredentialAttach { .. } => {
1873 ClientDiscriminant::CredentialAttachRequest
1874 }
1875 AttemptTokenBodyConflict::Leave { .. } => ClientDiscriminant::LeaveRequest,
1876 }),
1877 Self::ConnectionConversationCapacityExceeded(value) => match value {
1878 ConnectionConversationCapacityExceeded::SemanticRequest { request, .. } => {
1879 Some(request.originating_request())
1880 }
1881 ConnectionConversationCapacityExceeded::ObserverRecovery { .. } => None,
1882 },
1883 Self::ConnectionConversationBindingOccupied(value) => Some(match value {
1884 ConnectionConversationBindingOccupied::Enrollment { .. } => {
1885 ClientDiscriminant::EnrollmentRequest
1886 }
1887 ConnectionConversationBindingOccupied::CredentialAttach { .. } => {
1888 ClientDiscriminant::CredentialAttachRequest
1889 }
1890 }),
1891 Self::ConversationOrderExhausted(value) => Some(match value.request() {
1892 OrderAllocatingEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
1893 OrderAllocatingEnvelope::CredentialAttach(_) => {
1894 ClientDiscriminant::CredentialAttachRequest
1895 }
1896 OrderAllocatingEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
1897 }),
1898 Self::ParticipantUnknown(value) => Some(participant_reference_origin(&value.request)),
1899 Self::NoBinding(value) => Some(binding_required_origin(&value.request)),
1900 Self::StaleAuthority(value) => Some(stale_authority_origin(value)),
1901 Self::Retired(value) => Some(match value {
1902 Retired::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
1903 Retired::Participant { request, .. } => participant_reference_origin(request),
1904 }),
1905 Self::MarkerClosureCapacityExceeded(value) => Some(match &value.request {
1906 ClosureCheckedEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
1907 ClosureCheckedEnvelope::CredentialAttach(_) => {
1908 ClientDiscriminant::CredentialAttachRequest
1909 }
1910 ClosureCheckedEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
1911 ClosureCheckedEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
1912 }),
1913 Self::EnrollBound(_) | Self::EnrollmentKnown(_) | Self::IdentityCapacityExceeded(_) => {
1914 Some(ClientDiscriminant::EnrollmentRequest)
1915 }
1916 Self::ReceiptExpired(value) => Some(match value {
1917 ReceiptExpired::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
1918 ReceiptExpired::CredentialAttach { .. } => {
1919 ClientDiscriminant::CredentialAttachRequest
1920 }
1921 }),
1922 Self::ReceiptCapacityExceeded(value) => Some(match value {
1923 ReceiptCapacityExceeded::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
1924 ReceiptCapacityExceeded::CredentialAttach { .. } => {
1925 ClientDiscriminant::CredentialAttachRequest
1926 }
1927 }),
1928 Self::ObserverBackpressure(value) => Some(match value {
1929 ObserverBackpressure::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
1930 ObserverBackpressure::CredentialAttach { .. } => {
1931 ClientDiscriminant::CredentialAttachRequest
1932 }
1933 ObserverBackpressure::Detach { .. } => ClientDiscriminant::DetachRequest,
1934 ObserverBackpressure::Leave { .. } => ClientDiscriminant::LeaveRequest,
1935 ObserverBackpressure::RecordAdmission { .. } => ClientDiscriminant::RecordAdmission,
1936 }),
1937 Self::ConversationSequenceExhausted(value) => Some(match &value.request {
1938 SequenceAllocatingEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
1939 SequenceAllocatingEnvelope::CredentialAttach(_) => {
1940 ClientDiscriminant::CredentialAttachRequest
1941 }
1942 SequenceAllocatingEnvelope::RecordAdmission(_) => {
1943 ClientDiscriminant::RecordAdmission
1944 }
1945 }),
1946 Self::AttachBound(_) | Self::StaleOrUnknownReceipt(_) => {
1947 Some(ClientDiscriminant::CredentialAttachRequest)
1948 }
1949 Self::MarkerNotDelivered(value) => Some(marker_proof_origin(&value.request)),
1950 Self::MarkerMismatch(value) => Some(marker_proof_origin(&value.request)),
1951 Self::Bound(value) | Self::UnboundReceipt(value) => Some(match value {
1952 ReceiptReplay::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
1953 ReceiptReplay::CredentialAttach(_) => ClientDiscriminant::CredentialAttachRequest,
1954 }),
1955 Self::DetachCommitted(_) | Self::DetachInProgress(_) => {
1956 Some(ClientDiscriminant::DetachRequest)
1957 }
1958 Self::AckCommitted(_) | Self::AckGap(_) | Self::AckRegression(_) => {
1959 Some(ClientDiscriminant::ParticipantAck)
1960 }
1961 Self::AckNoOp(value) => Some(match value {
1962 AckNoOp::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
1963 AckNoOp::MarkerAck(_) => ClientDiscriminant::MarkerAck,
1964 }),
1965 Self::LeaveCommitted(_) => Some(ClientDiscriminant::LeaveRequest),
1966 Self::MarkerAckCommitted(_) => Some(ClientDiscriminant::MarkerAck),
1967 Self::RecordCommitted(_) | Self::RecordTooLarge(_) => {
1968 Some(ClientDiscriminant::RecordAdmission)
1969 }
1970 }
1971 }
1972}
1973
1974const fn participant_reference_origin(
1975 request: &ParticipantReferenceEnvelope,
1976) -> ClientDiscriminant {
1977 match request {
1978 ParticipantReferenceEnvelope::CredentialAttach(_) => {
1979 ClientDiscriminant::CredentialAttachRequest
1980 }
1981 ParticipantReferenceEnvelope::Detach(_) => ClientDiscriminant::DetachRequest,
1982 ParticipantReferenceEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
1983 ParticipantReferenceEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
1984 ParticipantReferenceEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
1985 ParticipantReferenceEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
1986 }
1987}
1988
1989const fn binding_required_origin(request: &BindingRequiredEnvelope) -> ClientDiscriminant {
1990 match request {
1991 BindingRequiredEnvelope::Detach(_) => ClientDiscriminant::DetachRequest,
1992 BindingRequiredEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
1993 BindingRequiredEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
1994 BindingRequiredEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
1995 BindingRequiredEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
1996 }
1997}
1998
1999const fn stale_authority_origin(value: &StaleAuthority) -> ClientDiscriminant {
2000 match value {
2001 StaleAuthority::Live { request, .. } => match request {
2002 CommonStaleAuthorityEnvelope::CredentialAttach(_) => {
2003 ClientDiscriminant::CredentialAttachRequest
2004 }
2005 CommonStaleAuthorityEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2006 CommonStaleAuthorityEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2007 CommonStaleAuthorityEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2008 },
2009 StaleAuthority::Detach(_) => ClientDiscriminant::DetachRequest,
2010 StaleAuthority::Leave(_) => ClientDiscriminant::LeaveRequest,
2011 }
2012}
2013
2014const fn marker_proof_origin(request: &MarkerProofRequest) -> ClientDiscriminant {
2015 match request {
2016 MarkerProofRequest::CredentialAttach(_) => ClientDiscriminant::CredentialAttachRequest,
2017 MarkerProofRequest::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2018 }
2019}
2020
2021pub const PARTICIPANT_CAPABILITY: &str = "participant-v1";
2023
2024#[must_use]
2026pub const fn attempt_operation(value: &AttemptTokenBodyConflict) -> super::AttemptOperation {
2027 match value {
2028 AttemptTokenBodyConflict::CredentialAttach { .. } => {
2029 super::AttemptOperation::CredentialAttachRequest
2030 }
2031 AttemptTokenBodyConflict::Leave { .. } => super::AttemptOperation::LeaveRequest,
2032 }
2033}
2034
2035#[must_use]
2037pub fn capability_string() -> String {
2038 String::from(PARTICIPANT_CAPABILITY)
2039}