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)]
1072pub enum WriteOutcomeUnknown {
1073 Enrollment {
1075 request: EnrollmentEnvelope,
1077 },
1078 CredentialAttach {
1080 request: AttachEnvelope,
1082 },
1083 Detach {
1085 request: DetachEnvelope,
1087 },
1088 Leave {
1090 request: LeaveEnvelope,
1092 },
1093 RecordAdmission {
1095 request: RecordAdmissionEnvelope,
1097 },
1098}
1099
1100#[derive(Clone, Debug, PartialEq, Eq)]
1102pub enum SequenceAllocatingEnvelope {
1103 Enrollment(EnrollmentEnvelope),
1105 CredentialAttach(AttachEnvelope),
1107 RecordAdmission(RecordAdmissionEnvelope),
1109}
1110
1111#[derive(Clone, Debug, PartialEq, Eq)]
1113pub struct ConversationSequenceExhausted {
1114 pub request: SequenceAllocatingEnvelope,
1116 pub sequence_budget: SequenceBudget,
1118}
1119
1120#[derive(Clone, Debug, PartialEq, Eq)]
1122pub struct AttachBound {
1123 conversation_id: ConversationId,
1125 token: AttachAttemptToken,
1127 participant_id: ParticipantId,
1129 request_generation: Generation,
1131 attach_secret: AttachSecret,
1133 origin_binding_epoch: BindingEpoch,
1135 persisted_cursor: DeliverySeq,
1137 accepted_marker_delivery_seq: Option<DeliverySeq>,
1139 receipt_expires_at: u128,
1141 provenance_expires_at: u128,
1143}
1144
1145impl AttachBound {
1146 #[must_use]
1152 #[allow(clippy::too_many_arguments)]
1153 pub const fn ordinary(
1154 conversation_id: ConversationId,
1155 token: AttachAttemptToken,
1156 participant_id: ParticipantId,
1157 request_generation: Generation,
1158 attach_secret: AttachSecret,
1159 origin_binding_epoch: BindingEpoch,
1160 persisted_cursor: DeliverySeq,
1161 receipt_expires_at: u128,
1162 provenance_expires_at: u128,
1163 ) -> Option<Self> {
1164 if !is_successor_generation(
1165 request_generation,
1166 origin_binding_epoch.capability_generation,
1167 ) {
1168 return None;
1169 }
1170 Some(Self {
1171 conversation_id,
1172 token,
1173 participant_id,
1174 request_generation,
1175 attach_secret,
1176 origin_binding_epoch,
1177 persisted_cursor,
1178 accepted_marker_delivery_seq: None,
1179 receipt_expires_at,
1180 provenance_expires_at,
1181 })
1182 }
1183
1184 #[must_use]
1190 #[allow(clippy::too_many_arguments)]
1191 pub const fn fenced(
1192 conversation_id: ConversationId,
1193 token: AttachAttemptToken,
1194 participant_id: ParticipantId,
1195 request_generation: Generation,
1196 attach_secret: AttachSecret,
1197 origin_binding_epoch: BindingEpoch,
1198 accepted_marker_delivery_seq: DeliverySeq,
1199 receipt_expires_at: u128,
1200 provenance_expires_at: u128,
1201 ) -> Option<Self> {
1202 if !is_successor_generation(
1203 request_generation,
1204 origin_binding_epoch.capability_generation,
1205 ) {
1206 return None;
1207 }
1208 Some(Self {
1209 conversation_id,
1210 token,
1211 participant_id,
1212 request_generation,
1213 attach_secret,
1214 origin_binding_epoch,
1215 persisted_cursor: accepted_marker_delivery_seq,
1216 accepted_marker_delivery_seq: Some(accepted_marker_delivery_seq),
1217 receipt_expires_at,
1218 provenance_expires_at,
1219 })
1220 }
1221
1222 #[must_use]
1224 pub const fn conversation_id(&self) -> ConversationId {
1225 self.conversation_id
1226 }
1227
1228 #[must_use]
1230 pub const fn token(&self) -> AttachAttemptToken {
1231 self.token
1232 }
1233
1234 #[must_use]
1236 pub const fn participant_id(&self) -> ParticipantId {
1237 self.participant_id
1238 }
1239
1240 #[must_use]
1242 pub const fn request_generation(&self) -> Generation {
1243 self.request_generation
1244 }
1245
1246 #[must_use]
1248 pub const fn capability_generation(&self) -> Generation {
1249 self.origin_binding_epoch.capability_generation
1250 }
1251
1252 #[must_use]
1254 pub const fn attach_secret(&self) -> AttachSecret {
1255 self.attach_secret
1256 }
1257
1258 #[must_use]
1260 pub const fn origin_binding_epoch(&self) -> BindingEpoch {
1261 self.origin_binding_epoch
1262 }
1263
1264 #[must_use]
1266 pub const fn persisted_cursor(&self) -> DeliverySeq {
1267 self.persisted_cursor
1268 }
1269
1270 #[must_use]
1272 pub const fn accepted_marker_delivery_seq(&self) -> Option<DeliverySeq> {
1273 self.accepted_marker_delivery_seq
1274 }
1275
1276 #[must_use]
1278 pub const fn receipt_expires_at(&self) -> u128 {
1279 self.receipt_expires_at
1280 }
1281
1282 #[must_use]
1284 pub const fn provenance_expires_at(&self) -> u128 {
1285 self.provenance_expires_at
1286 }
1287}
1288
1289const fn is_successor_generation(previous: Generation, successor: Generation) -> bool {
1290 match previous.get().checked_add(1) {
1291 Some(expected) => successor.get() == expected,
1292 None => false,
1293 }
1294}
1295
1296#[derive(Clone, Debug, PartialEq, Eq)]
1298pub struct StaleOrUnknownReceipt {
1299 pub conversation_id: ConversationId,
1301 pub token: AttachAttemptToken,
1303 pub participant_id: ParticipantId,
1305 pub presented_generation: Generation,
1307 pub presented_marker_delivery_seq: Option<DeliverySeq>,
1309 pub current_generation: Generation,
1311}
1312
1313#[derive(Clone, Debug, PartialEq, Eq)]
1315pub struct AttachMarkerProof {
1316 pub conversation_id: ConversationId,
1318 pub token: AttachAttemptToken,
1320 pub participant_id: ParticipantId,
1322 pub capability_generation: Generation,
1324 pub requested_marker_delivery_seq: DeliverySeq,
1326}
1327
1328#[derive(Clone, Debug, PartialEq, Eq)]
1330pub struct MarkerAckProof {
1331 pub conversation_id: ConversationId,
1333 pub participant_id: ParticipantId,
1335 pub capability_generation: Generation,
1337 pub requested_marker_delivery_seq: DeliverySeq,
1339}
1340
1341#[derive(Clone, Debug, PartialEq, Eq)]
1343pub enum MarkerProofRequest {
1344 CredentialAttach(AttachMarkerProof),
1346 MarkerAck(MarkerAckProof),
1348}
1349
1350#[derive(Clone, Debug, PartialEq, Eq)]
1352pub struct MarkerNotDelivered {
1353 pub request: MarkerProofRequest,
1355 pub reason: MarkerNotDeliveredReason,
1357 pub expected_marker_delivery_seq: DeliverySeq,
1359}
1360
1361#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1363pub enum MarkerMismatchBody {
1364 BelowCursor {
1366 current_cursor: DeliverySeq,
1368 },
1369 NoMarkerExpected,
1371 ExpectedDifferentMarker {
1373 expected_marker_delivery_seq: DeliverySeq,
1375 },
1376}
1377
1378impl MarkerMismatchBody {
1379 #[must_use]
1381 pub const fn reason(self) -> MarkerMismatchReason {
1382 match self {
1383 Self::BelowCursor { .. } => MarkerMismatchReason::BelowCursor,
1384 Self::NoMarkerExpected => MarkerMismatchReason::NoMarkerExpected,
1385 Self::ExpectedDifferentMarker { .. } => MarkerMismatchReason::ExpectedDifferentMarker,
1386 }
1387 }
1388}
1389
1390#[derive(Clone, Debug, PartialEq, Eq)]
1392pub struct MarkerMismatch {
1393 pub request: MarkerProofRequest,
1395 pub mismatch: MarkerMismatchBody,
1397}
1398
1399#[derive(Clone, Debug, PartialEq, Eq)]
1401pub enum ReceiptReplay {
1402 Enrollment(EnrollBound),
1405 CredentialAttach(AttachBound),
1408}
1409
1410#[derive(Clone, Debug, PartialEq, Eq)]
1412pub struct DetachCommitted {
1413 conversation_id: ConversationId,
1415 participant_id: ParticipantId,
1417 detach_attempt_token: DetachAttemptToken,
1419 committed_binding_epoch: BindingEpoch,
1421 detached_delivery_seq: DeliverySeq,
1423}
1424
1425impl DetachCommitted {
1426 #[must_use]
1429 pub const fn new(
1430 conversation_id: ConversationId,
1431 participant_id: ParticipantId,
1432 detach_attempt_token: DetachAttemptToken,
1433 committed_binding_epoch: BindingEpoch,
1434 detached_delivery_seq: DeliverySeq,
1435 ) -> Self {
1436 Self {
1437 conversation_id,
1438 participant_id,
1439 detach_attempt_token,
1440 committed_binding_epoch,
1441 detached_delivery_seq,
1442 }
1443 }
1444
1445 #[must_use]
1447 pub const fn conversation_id(&self) -> ConversationId {
1448 self.conversation_id
1449 }
1450
1451 #[must_use]
1453 pub const fn participant_id(&self) -> ParticipantId {
1454 self.participant_id
1455 }
1456
1457 #[must_use]
1459 pub const fn capability_generation(&self) -> Generation {
1460 self.committed_binding_epoch.capability_generation
1461 }
1462
1463 #[must_use]
1465 pub const fn detach_attempt_token(&self) -> DetachAttemptToken {
1466 self.detach_attempt_token
1467 }
1468
1469 #[must_use]
1471 pub const fn committed_binding_epoch(&self) -> BindingEpoch {
1472 self.committed_binding_epoch
1473 }
1474
1475 #[must_use]
1477 pub const fn detached_delivery_seq(&self) -> DeliverySeq {
1478 self.detached_delivery_seq
1479 }
1480}
1481
1482#[derive(Clone, Debug, PartialEq, Eq)]
1484pub struct DetachInProgress {
1485 pub conversation_id: ConversationId,
1487 pub participant_id: ParticipantId,
1489 pub presented_token: DetachAttemptToken,
1491 pub presented_generation: Generation,
1493 pub committed_binding_epoch: BindingEpoch,
1495}
1496
1497#[derive(Clone, Debug, PartialEq, Eq)]
1499pub struct AckCommitted {
1500 request: ParticipantAckEnvelope,
1502}
1503
1504impl AckCommitted {
1505 #[must_use]
1508 pub const fn new(request: ParticipantAckEnvelope) -> Self {
1509 Self { request }
1510 }
1511
1512 #[must_use]
1514 pub const fn request(&self) -> &ParticipantAckEnvelope {
1515 &self.request
1516 }
1517
1518 #[must_use]
1520 pub const fn current_cursor(&self) -> DeliverySeq {
1521 self.request.through_seq
1522 }
1523}
1524
1525#[derive(Clone, Debug, PartialEq, Eq)]
1527pub enum AckNoOp {
1528 ParticipantAck(ParticipantAckEnvelope),
1530 MarkerAck(MarkerAckEnvelope),
1532}
1533
1534impl AckNoOp {
1535 #[must_use]
1538 pub const fn participant_ack(request: ParticipantAckEnvelope) -> Self {
1539 Self::ParticipantAck(request)
1540 }
1541
1542 #[must_use]
1545 pub const fn marker_ack(request: MarkerAckEnvelope) -> Self {
1546 Self::MarkerAck(request)
1547 }
1548
1549 #[must_use]
1551 pub const fn current_cursor(&self) -> DeliverySeq {
1552 match self {
1553 Self::ParticipantAck(request) => request.through_seq,
1554 Self::MarkerAck(request) => request.marker_delivery_seq,
1555 }
1556 }
1557}
1558
1559#[derive(Clone, Debug, PartialEq, Eq)]
1561pub struct AckGap {
1562 request: ParticipantAckEnvelope,
1564 current_cursor: DeliverySeq,
1566}
1567
1568impl AckGap {
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) -> AckGapReason {
1598 let _ = self;
1599 AckGapReason::NotContiguouslyAvailable
1600 }
1601}
1602
1603#[derive(Clone, Debug, PartialEq, Eq)]
1605pub struct AckRegression {
1606 request: ParticipantAckEnvelope,
1608 current_cursor: DeliverySeq,
1610}
1611
1612impl AckRegression {
1613 #[must_use]
1616 pub const fn new(request: ParticipantAckEnvelope, current_cursor: DeliverySeq) -> Option<Self> {
1617 if request.through_seq < current_cursor {
1618 Some(Self {
1619 request,
1620 current_cursor,
1621 })
1622 } else {
1623 None
1624 }
1625 }
1626
1627 #[must_use]
1629 pub const fn request(&self) -> &ParticipantAckEnvelope {
1630 &self.request
1631 }
1632
1633 #[must_use]
1635 pub const fn current_cursor(&self) -> DeliverySeq {
1636 self.current_cursor
1637 }
1638
1639 #[must_use]
1641 pub const fn reason(&self) -> AckRegressionReason {
1642 let _ = self;
1643 AckRegressionReason::BelowCursor
1644 }
1645}
1646
1647#[derive(Clone, Debug, PartialEq, Eq)]
1649pub struct LeaveCommitted {
1650 conversation_id: ConversationId,
1652 leave_attempt_token: LeaveAttemptToken,
1654 participant_id: ParticipantId,
1656 retired_generation: Generation,
1658 ended_binding_epoch: Option<BindingEpoch>,
1660 prior_terminal_delivery_seq: Option<DeliverySeq>,
1662 left_delivery_seq: DeliverySeq,
1664}
1665
1666impl LeaveCommitted {
1667 #[must_use]
1673 #[allow(clippy::too_many_arguments)]
1674 pub const fn new(
1675 conversation_id: ConversationId,
1676 leave_attempt_token: LeaveAttemptToken,
1677 participant_id: ParticipantId,
1678 retired_generation: Generation,
1679 ended_binding_epoch: Option<BindingEpoch>,
1680 prior_terminal_delivery_seq: Option<DeliverySeq>,
1681 left_delivery_seq: DeliverySeq,
1682 ) -> Option<Self> {
1683 if let Some(epoch) = ended_binding_epoch
1684 && epoch.capability_generation.get() != retired_generation.get()
1685 {
1686 return None;
1687 }
1688 if let Some(prior) = prior_terminal_delivery_seq
1689 && prior >= left_delivery_seq
1690 {
1691 return None;
1692 }
1693 Some(Self {
1694 conversation_id,
1695 leave_attempt_token,
1696 participant_id,
1697 retired_generation,
1698 ended_binding_epoch,
1699 prior_terminal_delivery_seq,
1700 left_delivery_seq,
1701 })
1702 }
1703
1704 #[must_use]
1706 pub const fn conversation_id(&self) -> ConversationId {
1707 self.conversation_id
1708 }
1709
1710 #[must_use]
1712 pub const fn leave_attempt_token(&self) -> LeaveAttemptToken {
1713 self.leave_attempt_token
1714 }
1715
1716 #[must_use]
1718 pub const fn participant_id(&self) -> ParticipantId {
1719 self.participant_id
1720 }
1721
1722 #[must_use]
1724 pub const fn presented_generation(&self) -> Generation {
1725 self.retired_generation
1726 }
1727
1728 #[must_use]
1730 pub const fn retired_generation(&self) -> Generation {
1731 self.retired_generation
1732 }
1733
1734 #[must_use]
1736 pub const fn ended_binding_epoch(&self) -> Option<BindingEpoch> {
1737 self.ended_binding_epoch
1738 }
1739
1740 #[must_use]
1742 pub const fn prior_terminal_delivery_seq(&self) -> Option<DeliverySeq> {
1743 self.prior_terminal_delivery_seq
1744 }
1745
1746 #[must_use]
1748 pub const fn left_delivery_seq(&self) -> DeliverySeq {
1749 self.left_delivery_seq
1750 }
1751}
1752
1753#[derive(Clone, Debug, PartialEq, Eq)]
1755pub struct MarkerAckCommitted {
1756 request: MarkerAckEnvelope,
1758}
1759
1760impl MarkerAckCommitted {
1761 #[must_use]
1764 pub const fn new(request: MarkerAckEnvelope) -> Self {
1765 Self { request }
1766 }
1767
1768 #[must_use]
1770 pub const fn request(&self) -> &MarkerAckEnvelope {
1771 &self.request
1772 }
1773
1774 #[must_use]
1776 pub const fn current_cursor(&self) -> DeliverySeq {
1777 self.request.marker_delivery_seq
1778 }
1779}
1780
1781#[derive(Clone, Debug, PartialEq, Eq)]
1783pub struct RecordCommitted {
1784 request: RecordAdmissionEnvelope,
1786 delivery_seq: DeliverySeq,
1788}
1789
1790impl RecordCommitted {
1791 #[must_use]
1794 pub const fn new(request: RecordAdmissionEnvelope, delivery_seq: DeliverySeq) -> Self {
1795 Self {
1796 request,
1797 delivery_seq,
1798 }
1799 }
1800
1801 #[must_use]
1803 pub const fn request(&self) -> &RecordAdmissionEnvelope {
1804 &self.request
1805 }
1806
1807 #[must_use]
1809 pub const fn sender_participant_id(&self) -> ParticipantId {
1810 self.request.participant_id
1811 }
1812
1813 #[must_use]
1815 pub const fn delivery_seq(&self) -> DeliverySeq {
1816 self.delivery_seq
1817 }
1818}
1819
1820#[derive(Clone, Debug, PartialEq, Eq)]
1822pub struct RecordTooLarge {
1823 pub request: RecordAdmissionEnvelope,
1825 pub dimension: ResourceDimension,
1827 pub encoded_record_charge: ResourceVector,
1829 pub max_ordinary_record_charge: ResourceVector,
1831}
1832
1833#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1835pub struct ObserverProgressStatus {
1836 pub conversation_id: ConversationId,
1838 pub refused_epoch: ObserverEpoch,
1840 pub current_observer_progress: DeliverySeq,
1842 pub armed: bool,
1844 pub progressed: bool,
1846}
1847
1848#[derive(Clone, Debug, PartialEq, Eq)]
1850pub struct ObserverRecoveryAccepted {
1851 pub statuses: Vec<ObserverProgressStatus>,
1853}
1854
1855#[derive(Clone, Debug, PartialEq, Eq)]
1857pub enum InvalidObserverEpoch {
1858 ConversationUnknown {
1860 conversation_id: ConversationId,
1862 presented_epoch: ObserverEpoch,
1864 },
1865 EpochAhead {
1867 conversation_id: ConversationId,
1869 presented_epoch: ObserverEpoch,
1871 current_observer_progress: DeliverySeq,
1873 },
1874}
1875
1876impl InvalidObserverEpoch {
1877 #[must_use]
1879 pub const fn reason(&self) -> InvalidObserverEpochReason {
1880 match self {
1881 Self::ConversationUnknown { .. } => InvalidObserverEpochReason::ConversationUnknown,
1882 Self::EpochAhead { .. } => InvalidObserverEpochReason::EpochAhead,
1883 }
1884 }
1885}
1886
1887#[derive(Clone, Debug, PartialEq, Eq)]
1889pub enum InvalidObserverEpochList {
1890 TooManyEntries {
1892 presented_entries: u64,
1894 max_entries: u64,
1896 },
1897 DuplicateConversation {
1899 conversation_id: ConversationId,
1901 first_index: u64,
1903 duplicate_index: u64,
1905 },
1906}
1907
1908impl InvalidObserverEpochList {
1909 #[must_use]
1911 pub const fn reason(&self) -> InvalidObserverEpochListReason {
1912 match self {
1913 Self::TooManyEntries { .. } => InvalidObserverEpochListReason::TooManyEntries,
1914 Self::DuplicateConversation { .. } => {
1915 InvalidObserverEpochListReason::DuplicateConversation
1916 }
1917 }
1918 }
1919}
1920
1921#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1923pub enum SettlementOutcome {
1924 Committed {
1926 delivery_seq: DeliverySeq,
1928 },
1929 Withdrawn,
1931 Expired,
1933 NotCommitted,
1935 Unknown,
1937}
1938
1939#[derive(Clone, Debug, PartialEq, Eq)]
1941pub struct SettlementAnswer {
1942 pub conversation_id: ConversationId,
1944 pub participant_id: ParticipantId,
1946 pub record_admission_attempt_token: RecordAdmissionAttemptToken,
1948 pub outcome: SettlementOutcome,
1950}
1951
1952#[derive(Clone, Debug, PartialEq, Eq)]
1954pub enum ServerValue {
1955 ParticipantTransportRejected(ParticipantTransportRejected),
1957 AttemptTokenBodyConflict(AttemptTokenBodyConflict),
1959 ConnectionConversationCapacityExceeded(ConnectionConversationCapacityExceeded),
1961 ConnectionConversationBindingOccupied(ConnectionConversationBindingOccupied),
1963 ConversationOrderExhausted(Box<ConversationOrderExhausted>),
1965 ParticipantUnknown(ParticipantUnknown),
1967 NoBinding(NoBinding),
1969 StaleAuthority(StaleAuthority),
1971 Retired(Retired),
1973 MarkerClosureCapacityExceeded(Box<MarkerClosureCapacityExceeded>),
1975 EnrollBound(EnrollBound),
1977 EnrollmentKnown(EnrollmentKnown),
1979 ReceiptExpired(ReceiptExpired),
1981 ReceiptCapacityExceeded(ReceiptCapacityExceeded),
1983 IdentityCapacityExceeded(IdentityCapacityExceeded),
1985 ObserverBackpressure(ObserverBackpressure),
1987 ConversationSequenceExhausted(Box<ConversationSequenceExhausted>),
1989 AttachBound(AttachBound),
1991 StaleOrUnknownReceipt(StaleOrUnknownReceipt),
1993 MarkerNotDelivered(MarkerNotDelivered),
1995 MarkerMismatch(MarkerMismatch),
1997 Bound(ReceiptReplay),
1999 UnboundReceipt(ReceiptReplay),
2001 DetachCommitted(DetachCommitted),
2003 DetachInProgress(DetachInProgress),
2005 AckCommitted(AckCommitted),
2007 AckNoOp(AckNoOp),
2009 AckGap(AckGap),
2011 AckRegression(AckRegression),
2013 LeaveCommitted(LeaveCommitted),
2015 MarkerAckCommitted(MarkerAckCommitted),
2017 RecordCommitted(RecordCommitted),
2019 RecordTooLarge(RecordTooLarge),
2021 ObserverRecoveryAccepted(ObserverRecoveryAccepted),
2023 InvalidObserverEpoch(InvalidObserverEpoch),
2025 InvalidObserverEpochList(InvalidObserverEpochList),
2027 MarkerSettlementBackpressure(MarkerSettlementBackpressure),
2029 EnrollmentSettlementBackpressure(EnrollmentSettlementBackpressure),
2031 RecordAdmissionProtocolFault(RecordAdmissionProtocolFault),
2033 WriteOutcomeUnknown(WriteOutcomeUnknown),
2035 SettlementAnswer(SettlementAnswer),
2037}
2038
2039impl ServerValue {
2040 #[must_use]
2042 pub const fn discriminant(&self) -> ServerDiscriminant {
2043 match self {
2044 Self::ParticipantTransportRejected(_) => {
2045 ServerDiscriminant::ParticipantTransportRejected
2046 }
2047 Self::AttemptTokenBodyConflict(_) => ServerDiscriminant::AttemptTokenBodyConflict,
2048 Self::ConnectionConversationCapacityExceeded(value) => match value {
2049 ConnectionConversationCapacityExceeded::SemanticRequest { .. } => {
2050 ServerDiscriminant::ConnectionConversationCapacityExceeded
2051 }
2052 ConnectionConversationCapacityExceeded::ObserverRecovery { .. } => {
2053 ServerDiscriminant::ObserverRecoveryConnectionCapacityExceeded
2054 }
2055 },
2056 Self::ConnectionConversationBindingOccupied(_) => {
2057 ServerDiscriminant::ConnectionConversationBindingOccupied
2058 }
2059 Self::ConversationOrderExhausted(_) => ServerDiscriminant::ConversationOrderExhausted,
2060 Self::ParticipantUnknown(_) => ServerDiscriminant::ParticipantUnknown,
2061 Self::NoBinding(_) => ServerDiscriminant::NoBinding,
2062 Self::StaleAuthority(_) => ServerDiscriminant::StaleAuthority,
2063 Self::Retired(_) => ServerDiscriminant::Retired,
2064 Self::MarkerClosureCapacityExceeded(_) => {
2065 ServerDiscriminant::MarkerClosureCapacityExceeded
2066 }
2067 Self::EnrollBound(_) => ServerDiscriminant::EnrollBound,
2068 Self::EnrollmentKnown(_) => ServerDiscriminant::EnrollmentKnown,
2069 Self::ReceiptExpired(_) => ServerDiscriminant::ReceiptExpired,
2070 Self::ReceiptCapacityExceeded(_) => ServerDiscriminant::ReceiptCapacityExceeded,
2071 Self::IdentityCapacityExceeded(_) => ServerDiscriminant::IdentityCapacityExceeded,
2072 Self::ObserverBackpressure(_) => ServerDiscriminant::ObserverBackpressure,
2073 Self::ConversationSequenceExhausted(_) => {
2074 ServerDiscriminant::ConversationSequenceExhausted
2075 }
2076 Self::AttachBound(_) => ServerDiscriminant::AttachBound,
2077 Self::StaleOrUnknownReceipt(_) => ServerDiscriminant::StaleOrUnknownReceipt,
2078 Self::MarkerNotDelivered(_) => ServerDiscriminant::MarkerNotDelivered,
2079 Self::MarkerMismatch(_) => ServerDiscriminant::MarkerMismatch,
2080 Self::Bound(_) => ServerDiscriminant::Bound,
2081 Self::UnboundReceipt(_) => ServerDiscriminant::UnboundReceipt,
2082 Self::DetachCommitted(_) => ServerDiscriminant::DetachCommitted,
2083 Self::DetachInProgress(_) => ServerDiscriminant::DetachInProgress,
2084 Self::AckCommitted(_) => ServerDiscriminant::AckCommitted,
2085 Self::AckNoOp(_) => ServerDiscriminant::AckNoOp,
2086 Self::AckGap(_) => ServerDiscriminant::AckGap,
2087 Self::AckRegression(_) => ServerDiscriminant::AckRegression,
2088 Self::LeaveCommitted(_) => ServerDiscriminant::LeaveCommitted,
2089 Self::MarkerAckCommitted(_) => ServerDiscriminant::MarkerAckCommitted,
2090 Self::RecordCommitted(_) => ServerDiscriminant::RecordCommitted,
2091 Self::RecordTooLarge(_) => ServerDiscriminant::RecordTooLarge,
2092 Self::ObserverRecoveryAccepted(_) => ServerDiscriminant::ObserverRecoveryAccepted,
2093 Self::InvalidObserverEpoch(_) => ServerDiscriminant::InvalidObserverEpoch,
2094 Self::InvalidObserverEpochList(_) => ServerDiscriminant::InvalidObserverEpochList,
2095 Self::MarkerSettlementBackpressure(_) => {
2096 ServerDiscriminant::MarkerSettlementBackpressure
2097 }
2098 Self::EnrollmentSettlementBackpressure(_) => {
2099 ServerDiscriminant::EnrollmentSettlementBackpressure
2100 }
2101 Self::RecordAdmissionProtocolFault(_) => {
2102 ServerDiscriminant::RecordAdmissionProtocolFault
2103 }
2104 Self::WriteOutcomeUnknown(_) => ServerDiscriminant::WriteOutcomeUnknown,
2105 Self::SettlementAnswer(_) => ServerDiscriminant::SettlementAnswer,
2106 }
2107 }
2108
2109 #[must_use]
2111 #[allow(clippy::too_many_lines)]
2112 pub const fn originating_request(&self) -> Option<ClientDiscriminant> {
2113 match self {
2114 Self::ParticipantTransportRejected(_)
2115 | Self::ObserverRecoveryAccepted(_)
2116 | Self::InvalidObserverEpoch(_)
2117 | Self::InvalidObserverEpochList(_) => None,
2118 Self::AttemptTokenBodyConflict(value) => Some(match value {
2119 AttemptTokenBodyConflict::CredentialAttach { .. } => {
2120 ClientDiscriminant::CredentialAttachRequest
2121 }
2122 AttemptTokenBodyConflict::Leave { .. } => ClientDiscriminant::LeaveRequest,
2123 AttemptTokenBodyConflict::RecordAdmission { .. } => {
2124 ClientDiscriminant::RecordAdmission
2125 }
2126 }),
2127 Self::ConnectionConversationCapacityExceeded(value) => match value {
2128 ConnectionConversationCapacityExceeded::SemanticRequest { request, .. } => {
2129 Some(request.originating_request())
2130 }
2131 ConnectionConversationCapacityExceeded::ObserverRecovery { .. } => None,
2132 },
2133 Self::ConnectionConversationBindingOccupied(value) => Some(match value {
2134 ConnectionConversationBindingOccupied::Enrollment { .. } => {
2135 ClientDiscriminant::EnrollmentRequest
2136 }
2137 ConnectionConversationBindingOccupied::CredentialAttach { .. } => {
2138 ClientDiscriminant::CredentialAttachRequest
2139 }
2140 }),
2141 Self::ConversationOrderExhausted(value) => Some(match value.request() {
2142 OrderAllocatingEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2143 OrderAllocatingEnvelope::CredentialAttach(_) => {
2144 ClientDiscriminant::CredentialAttachRequest
2145 }
2146 OrderAllocatingEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2147 }),
2148 Self::ParticipantUnknown(value) => Some(participant_reference_origin(&value.request)),
2149 Self::NoBinding(value) => Some(binding_required_origin(&value.request)),
2150 Self::StaleAuthority(value) => Some(stale_authority_origin(value)),
2151 Self::Retired(value) => Some(match value {
2152 Retired::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2153 Retired::Participant { request, .. } => participant_reference_origin(request),
2154 }),
2155 Self::MarkerClosureCapacityExceeded(value) => Some(match &value.request {
2156 ClosureCheckedEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2157 ClosureCheckedEnvelope::CredentialAttach(_) => {
2158 ClientDiscriminant::CredentialAttachRequest
2159 }
2160 ClosureCheckedEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
2161 ClosureCheckedEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2162 }),
2163 Self::EnrollBound(_)
2164 | Self::EnrollmentKnown(_)
2165 | Self::IdentityCapacityExceeded(_)
2166 | Self::EnrollmentSettlementBackpressure(_) => {
2167 Some(ClientDiscriminant::EnrollmentRequest)
2168 }
2169 Self::ReceiptExpired(value) => Some(match value {
2170 ReceiptExpired::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2171 ReceiptExpired::CredentialAttach { .. } => {
2172 ClientDiscriminant::CredentialAttachRequest
2173 }
2174 }),
2175 Self::ReceiptCapacityExceeded(value) => Some(match value {
2176 ReceiptCapacityExceeded::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2177 ReceiptCapacityExceeded::CredentialAttach { .. } => {
2178 ClientDiscriminant::CredentialAttachRequest
2179 }
2180 }),
2181 Self::ObserverBackpressure(value) => Some(match value {
2182 ObserverBackpressure::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2183 ObserverBackpressure::CredentialAttach { .. } => {
2184 ClientDiscriminant::CredentialAttachRequest
2185 }
2186 ObserverBackpressure::Detach { .. } => ClientDiscriminant::DetachRequest,
2187 ObserverBackpressure::Leave { .. } => ClientDiscriminant::LeaveRequest,
2188 ObserverBackpressure::RecordAdmission { .. } => ClientDiscriminant::RecordAdmission,
2189 }),
2190 Self::ConversationSequenceExhausted(value) => Some(match &value.request {
2191 SequenceAllocatingEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2192 SequenceAllocatingEnvelope::CredentialAttach(_) => {
2193 ClientDiscriminant::CredentialAttachRequest
2194 }
2195 SequenceAllocatingEnvelope::RecordAdmission(_) => {
2196 ClientDiscriminant::RecordAdmission
2197 }
2198 }),
2199 Self::AttachBound(_) | Self::StaleOrUnknownReceipt(_) => {
2200 Some(ClientDiscriminant::CredentialAttachRequest)
2201 }
2202 Self::MarkerNotDelivered(value) => Some(marker_proof_origin(&value.request)),
2203 Self::MarkerMismatch(value) => Some(marker_proof_origin(&value.request)),
2204 Self::Bound(value) | Self::UnboundReceipt(value) => Some(match value {
2205 ReceiptReplay::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2206 ReceiptReplay::CredentialAttach(_) => ClientDiscriminant::CredentialAttachRequest,
2207 }),
2208 Self::DetachCommitted(_) | Self::DetachInProgress(_) => {
2209 Some(ClientDiscriminant::DetachRequest)
2210 }
2211 Self::AckCommitted(_) | Self::AckGap(_) | Self::AckRegression(_) => {
2212 Some(ClientDiscriminant::ParticipantAck)
2213 }
2214 Self::AckNoOp(value) => Some(match value {
2215 AckNoOp::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2216 AckNoOp::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2217 }),
2218 Self::LeaveCommitted(_) => Some(ClientDiscriminant::LeaveRequest),
2219 Self::MarkerAckCommitted(_) => Some(ClientDiscriminant::MarkerAck),
2220 Self::RecordCommitted(_)
2221 | Self::RecordTooLarge(_)
2222 | Self::RecordAdmissionProtocolFault(_) => Some(ClientDiscriminant::RecordAdmission),
2223 Self::MarkerSettlementBackpressure(value) => Some(match value {
2224 MarkerSettlementBackpressure::CredentialAttach { .. } => {
2225 ClientDiscriminant::CredentialAttachRequest
2226 }
2227 MarkerSettlementBackpressure::Detach { .. } => ClientDiscriminant::DetachRequest,
2228 }),
2229 Self::SettlementAnswer(_) => Some(ClientDiscriminant::SettlementQuery),
2230 Self::WriteOutcomeUnknown(value) => Some(match value {
2231 WriteOutcomeUnknown::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2232 WriteOutcomeUnknown::CredentialAttach { .. } => {
2233 ClientDiscriminant::CredentialAttachRequest
2234 }
2235 WriteOutcomeUnknown::Detach { .. } => ClientDiscriminant::DetachRequest,
2236 WriteOutcomeUnknown::Leave { .. } => ClientDiscriminant::LeaveRequest,
2237 WriteOutcomeUnknown::RecordAdmission { .. } => ClientDiscriminant::RecordAdmission,
2238 }),
2239 }
2240 }
2241}
2242
2243const fn participant_reference_origin(
2244 request: &ParticipantReferenceEnvelope,
2245) -> ClientDiscriminant {
2246 match request {
2247 ParticipantReferenceEnvelope::CredentialAttach(_) => {
2248 ClientDiscriminant::CredentialAttachRequest
2249 }
2250 ParticipantReferenceEnvelope::Detach(_) => ClientDiscriminant::DetachRequest,
2251 ParticipantReferenceEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2252 ParticipantReferenceEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
2253 ParticipantReferenceEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2254 ParticipantReferenceEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2255 }
2256}
2257
2258const fn binding_required_origin(request: &BindingRequiredEnvelope) -> ClientDiscriminant {
2259 match request {
2260 BindingRequiredEnvelope::Detach(_) => ClientDiscriminant::DetachRequest,
2261 BindingRequiredEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2262 BindingRequiredEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
2263 BindingRequiredEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2264 BindingRequiredEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2265 }
2266}
2267
2268const fn stale_authority_origin(value: &StaleAuthority) -> ClientDiscriminant {
2269 match value {
2270 StaleAuthority::Live { request, .. } => match request {
2271 CommonStaleAuthorityEnvelope::CredentialAttach(_) => {
2272 ClientDiscriminant::CredentialAttachRequest
2273 }
2274 CommonStaleAuthorityEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2275 CommonStaleAuthorityEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2276 CommonStaleAuthorityEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2277 },
2278 StaleAuthority::Detach(_) => ClientDiscriminant::DetachRequest,
2279 StaleAuthority::Leave(_) => ClientDiscriminant::LeaveRequest,
2280 }
2281}
2282
2283const fn marker_proof_origin(request: &MarkerProofRequest) -> ClientDiscriminant {
2284 match request {
2285 MarkerProofRequest::CredentialAttach(_) => ClientDiscriminant::CredentialAttachRequest,
2286 MarkerProofRequest::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2287 }
2288}
2289
2290pub const PARTICIPANT_CAPABILITY: &str = "participant-v1";
2292
2293#[must_use]
2295pub const fn attempt_operation(value: &AttemptTokenBodyConflict) -> super::AttemptOperation {
2296 match value {
2297 AttemptTokenBodyConflict::CredentialAttach { .. } => {
2298 super::AttemptOperation::CredentialAttachRequest
2299 }
2300 AttemptTokenBodyConflict::Leave { .. } => super::AttemptOperation::LeaveRequest,
2301 AttemptTokenBodyConflict::RecordAdmission { .. } => {
2302 super::AttemptOperation::RecordAdmission
2303 }
2304 }
2305}
2306
2307#[must_use]
2309pub fn capability_string() -> String {
2310 String::from(PARTICIPANT_CAPABILITY)
2311}