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 AccessRefused {
70 refusal: String,
72 },
73}
74
75#[derive(Clone, Debug, PartialEq, Eq)]
80pub enum AttemptTokenBodyConflict {
81 CredentialAttach {
83 token: AttachAttemptToken,
85 conversation_id: ConversationId,
87 presented_participant_id: ParticipantId,
89 presented_generation: Generation,
91 presented_marker_delivery_seq: Option<DeliverySeq>,
93 conflict: AttemptConflict,
95 },
96 Leave {
98 token: LeaveAttemptToken,
100 conversation_id: ConversationId,
102 presented_participant_id: ParticipantId,
104 presented_generation: Generation,
106 },
107 RecordAdmission {
117 token: RecordAdmissionAttemptToken,
119 conversation_id: ConversationId,
121 presented_participant_id: ParticipantId,
123 presented_generation: Generation,
125 },
126}
127
128#[derive(Clone, Debug, PartialEq, Eq)]
135pub enum ConnectionConversationCapacityExceeded {
136 SemanticRequest {
138 request: ResponseEnvelope,
140 limit: u64,
142 },
143 ObserverRecovery {
145 conversation_id: ConversationId,
147 limit: u64,
149 },
150}
151
152#[derive(Clone, Debug, PartialEq, Eq)]
154pub enum ConnectionConversationBindingOccupied {
155 Enrollment {
157 conversation_id: ConversationId,
159 enrollment_token: EnrollmentToken,
161 },
162 CredentialAttach {
164 conversation_id: ConversationId,
166 participant_id: ParticipantId,
168 capability_generation: Generation,
170 attach_attempt_token: AttachAttemptToken,
172 accept_marker_delivery_seq: Option<DeliverySeq>,
174 },
175}
176
177#[derive(Clone, Debug, PartialEq, Eq)]
179pub enum OrderAllocatingEnvelope {
180 Enrollment(EnrollmentEnvelope),
182 CredentialAttach(AttachEnvelope),
184 RecordAdmission(RecordAdmissionEnvelope),
186}
187
188#[derive(Clone, Debug, PartialEq, Eq)]
190pub struct ConversationOrderExhausted {
191 request: OrderAllocatingEnvelope,
193 high: u64,
195 order_remaining: u128,
197 reserved_claims: u128,
199 resulting_order_remaining: u128,
201 resulting_reserved_claims: u128,
203}
204
205impl ConversationOrderExhausted {
206 pub const REQUIRED_MAJORS: u64 = 1;
208
209 #[must_use]
215 pub const fn new(
216 request: OrderAllocatingEnvelope,
217 high: u64,
218 order_remaining: u128,
219 reserved_claims: u128,
220 resulting_order_remaining: u128,
221 resulting_reserved_claims: u128,
222 ) -> Self {
223 Self {
224 request,
225 high,
226 order_remaining,
227 reserved_claims,
228 resulting_order_remaining,
229 resulting_reserved_claims,
230 }
231 }
232
233 #[must_use]
235 pub const fn request(&self) -> &OrderAllocatingEnvelope {
236 &self.request
237 }
238
239 #[must_use]
241 pub const fn counter(&self) -> Counter {
242 let _ = self;
243 Counter::TransactionOrder
244 }
245
246 #[must_use]
248 pub const fn high(&self) -> u64 {
249 self.high
250 }
251
252 #[must_use]
254 pub const fn next_value(&self) -> Option<u64> {
255 self.high.checked_add(1)
256 }
257
258 #[must_use]
260 pub const fn order_remaining(&self) -> u128 {
261 self.order_remaining
262 }
263
264 #[must_use]
266 pub const fn reserved_claims(&self) -> u128 {
267 self.reserved_claims
268 }
269
270 #[must_use]
272 pub const fn resulting_order_remaining(&self) -> u128 {
273 self.resulting_order_remaining
274 }
275
276 #[must_use]
278 pub const fn resulting_reserved_claims(&self) -> u128 {
279 self.resulting_reserved_claims
280 }
281}
282
283#[derive(Clone, Debug, PartialEq, Eq)]
285pub enum ParticipantReferenceEnvelope {
286 CredentialAttach(AttachEnvelope),
288 Detach(DetachEnvelope),
290 ParticipantAck(ParticipantAckEnvelope),
292 Leave(LeaveEnvelope),
294 MarkerAck(MarkerAckEnvelope),
296 RecordAdmission(RecordAdmissionEnvelope),
298}
299
300#[derive(Clone, Debug, PartialEq, Eq)]
302pub enum BindingRequiredEnvelope {
303 Detach(DetachEnvelope),
305 ParticipantAck(ParticipantAckEnvelope),
307 Leave(LeaveEnvelope),
309 MarkerAck(MarkerAckEnvelope),
311 RecordAdmission(RecordAdmissionEnvelope),
313}
314
315#[derive(Clone, Debug, PartialEq, Eq)]
317pub struct ParticipantUnknown {
318 pub request: ParticipantReferenceEnvelope,
320}
321
322#[derive(Clone, Debug, PartialEq, Eq)]
324pub struct NoBinding {
325 pub request: BindingRequiredEnvelope,
327}
328
329#[derive(Clone, Copy, Debug, PartialEq, Eq)]
331pub enum BindingStateView {
332 Bound {
334 current_binding_epoch: BindingEpoch,
336 },
337 Detached,
339}
340
341impl BindingStateView {
342 #[must_use]
344 pub const fn tag(self) -> super::BindingStateTag {
345 match self {
346 Self::Bound { .. } => super::BindingStateTag::Bound,
347 Self::Detached => super::BindingStateTag::Detached,
348 }
349 }
350}
351
352#[derive(Clone, Debug, PartialEq, Eq)]
357pub struct TerminalizedDetachCell {
358 conversation_id: ConversationId,
359 participant_id: ParticipantId,
360 capability_generation: Generation,
361 detach_attempt_token: DetachAttemptToken,
362 current_generation: Generation,
363 committed_binding_epoch: BindingEpoch,
364 binding_state: BindingStateView,
365}
366
367impl TerminalizedDetachCell {
368 pub(crate) const fn from_terminalized_state<V>(
376 state: &crate::lifecycle::TerminalizedDetach<V>,
377 conversation_id: ConversationId,
378 current_generation: Generation,
379 binding_state: BindingStateView,
380 ) -> Self {
381 Self {
382 conversation_id,
383 participant_id: state.participant_id(),
384 capability_generation: state.request_generation(),
385 detach_attempt_token: state.token(),
386 current_generation,
387 committed_binding_epoch: state.committed_binding_epoch(),
388 binding_state,
389 }
390 }
391
392 #[allow(clippy::too_many_arguments)]
399 pub(super) const fn from_wire_decode(
400 _authority: super::server_codec::TerminalizedWireDecodeAuthority,
401 conversation_id: ConversationId,
402 participant_id: ParticipantId,
403 capability_generation: Generation,
404 detach_attempt_token: DetachAttemptToken,
405 current_generation: Generation,
406 committed_binding_epoch: BindingEpoch,
407 binding_state: BindingStateView,
408 ) -> Self {
409 Self {
410 conversation_id,
411 participant_id,
412 capability_generation,
413 detach_attempt_token,
414 current_generation,
415 committed_binding_epoch,
416 binding_state,
417 }
418 }
419
420 #[cfg(test)]
421 pub(crate) const fn for_client_test(
422 conversation_id: ConversationId,
423 participant_id: ParticipantId,
424 capability_generation: Generation,
425 detach_attempt_token: DetachAttemptToken,
426 current_generation: Generation,
427 committed_binding_epoch: BindingEpoch,
428 binding_state: BindingStateView,
429 ) -> Self {
430 Self {
431 conversation_id,
432 participant_id,
433 capability_generation,
434 detach_attempt_token,
435 current_generation,
436 committed_binding_epoch,
437 binding_state,
438 }
439 }
440
441 #[must_use]
443 pub const fn conversation_id(&self) -> ConversationId {
444 self.conversation_id
445 }
446
447 #[must_use]
449 pub const fn participant_id(&self) -> ParticipantId {
450 self.participant_id
451 }
452
453 #[must_use]
455 pub const fn capability_generation(&self) -> Generation {
456 self.capability_generation
457 }
458
459 #[must_use]
461 pub const fn detach_attempt_token(&self) -> DetachAttemptToken {
462 self.detach_attempt_token
463 }
464
465 #[must_use]
467 pub const fn current_generation(&self) -> Generation {
468 self.current_generation
469 }
470
471 #[must_use]
473 pub const fn committed_binding_epoch(&self) -> BindingEpoch {
474 self.committed_binding_epoch
475 }
476
477 #[must_use]
479 pub const fn binding_state(&self) -> BindingStateView {
480 self.binding_state
481 }
482}
483
484#[derive(Clone, Debug, PartialEq, Eq)]
486pub enum DetachStaleAuthority {
487 Live {
489 conversation_id: ConversationId,
491 participant_id: ParticipantId,
493 capability_generation: Generation,
495 detach_attempt_token: DetachAttemptToken,
497 current_generation: Generation,
499 },
500 TerminalizedDetachCell(TerminalizedDetachCell),
502}
503
504impl DetachStaleAuthority {
505 #[must_use]
507 pub const fn authority_state_tag(&self) -> DetachAuthorityStateTag {
508 match self {
509 Self::Live { .. } => DetachAuthorityStateTag::Live,
510 Self::TerminalizedDetachCell(_) => DetachAuthorityStateTag::TerminalizedDetachCell,
511 }
512 }
513}
514
515#[derive(Clone, Debug, PartialEq, Eq)]
517pub enum LeaveStaleAuthority {
518 Live {
520 conversation_id: ConversationId,
522 participant_id: ParticipantId,
524 presented_generation: Generation,
526 leave_attempt_token: LeaveAttemptToken,
528 current_generation: Generation,
530 },
531 CommittedLeaveTombstone {
533 conversation_id: ConversationId,
535 participant_id: ParticipantId,
537 presented_generation: Generation,
539 leave_attempt_token: LeaveAttemptToken,
541 retired_generation: Generation,
543 },
544}
545
546impl LeaveStaleAuthority {
547 #[must_use]
549 pub const fn authority_state_tag(&self) -> LeaveAuthorityStateTag {
550 match self {
551 Self::Live { .. } => LeaveAuthorityStateTag::Live,
552 Self::CommittedLeaveTombstone { .. } => LeaveAuthorityStateTag::CommittedLeaveTombstone,
553 }
554 }
555}
556
557#[derive(Clone, Debug, PartialEq, Eq)]
559pub enum CommonStaleAuthorityEnvelope {
560 CredentialAttach(AttachEnvelope),
562 ParticipantAck(ParticipantAckEnvelope),
564 MarkerAck(MarkerAckEnvelope),
566 RecordAdmission(RecordAdmissionEnvelope),
568}
569
570#[derive(Clone, Debug, PartialEq, Eq)]
572pub enum StaleAuthority {
573 Live {
575 request: CommonStaleAuthorityEnvelope,
577 current_generation: Generation,
579 },
580 Detach(DetachStaleAuthority),
582 Leave(LeaveStaleAuthority),
584}
585
586#[derive(Clone, Debug, PartialEq, Eq)]
588pub enum Retired {
589 Enrollment {
591 request: EnrollmentEnvelope,
593 participant_id: ParticipantId,
595 retired_generation: Generation,
597 },
598 Participant {
600 request: ParticipantReferenceEnvelope,
602 retired_generation: Generation,
604 },
605}
606
607#[derive(Clone, Debug, PartialEq, Eq)]
609pub struct EnrollBound {
610 conversation_id: ConversationId,
611 token: EnrollmentToken,
612 participant_id: ParticipantId,
613 attach_secret: AttachSecret,
614 origin_binding_epoch: BindingEpoch,
615 receipt_expires_at: u128,
616 provenance_expires_at: u128,
617}
618
619impl EnrollBound {
620 #[must_use]
627 pub const fn new(
628 conversation_id: ConversationId,
629 token: EnrollmentToken,
630 participant_id: ParticipantId,
631 attach_secret: AttachSecret,
632 origin_binding_epoch: BindingEpoch,
633 receipt_expires_at: u128,
634 provenance_expires_at: u128,
635 ) -> Option<Self> {
636 if origin_binding_epoch.capability_generation.get() == 1 {
637 Some(Self {
638 conversation_id,
639 token,
640 participant_id,
641 attach_secret,
642 origin_binding_epoch,
643 receipt_expires_at,
644 provenance_expires_at,
645 })
646 } else {
647 None
648 }
649 }
650
651 #[must_use]
653 pub const fn conversation_id(&self) -> ConversationId {
654 self.conversation_id
655 }
656
657 #[must_use]
659 pub const fn token(&self) -> EnrollmentToken {
660 self.token
661 }
662
663 #[must_use]
665 pub const fn participant_id(&self) -> ParticipantId {
666 self.participant_id
667 }
668
669 #[must_use]
671 pub const fn request_generation(&self) -> Option<Generation> {
672 None
673 }
674
675 #[must_use]
677 pub const fn capability_generation(&self) -> Generation {
678 self.origin_binding_epoch.capability_generation
679 }
680
681 #[must_use]
683 pub const fn attach_secret(&self) -> AttachSecret {
684 self.attach_secret
685 }
686
687 #[must_use]
689 pub const fn origin_binding_epoch(&self) -> BindingEpoch {
690 self.origin_binding_epoch
691 }
692
693 #[must_use]
695 pub const fn persisted_cursor(&self) -> DeliverySeq {
696 0
697 }
698
699 #[must_use]
701 pub const fn accepted_marker_delivery_seq(&self) -> Option<DeliverySeq> {
702 None
703 }
704
705 #[must_use]
707 pub const fn receipt_expires_at(&self) -> u128 {
708 self.receipt_expires_at
709 }
710
711 #[must_use]
713 pub const fn provenance_expires_at(&self) -> u128 {
714 self.provenance_expires_at
715 }
716}
717
718#[derive(Clone, Debug, PartialEq, Eq)]
720pub struct EnrollmentKnown {
721 pub conversation_id: ConversationId,
723 pub token: EnrollmentToken,
725 pub participant_id: ParticipantId,
727 pub current_generation: Generation,
729}
730
731#[derive(Clone, Debug, PartialEq, Eq)]
733pub enum ReceiptExpired {
734 Enrollment {
736 conversation_id: ConversationId,
738 token: EnrollmentToken,
740 participant_id: ParticipantId,
742 result_generation: Generation,
744 current_generation: Generation,
746 reason: ReceiptExpiryReason,
748 },
749 CredentialAttach {
751 conversation_id: ConversationId,
753 token: AttachAttemptToken,
755 participant_id: ParticipantId,
757 presented_generation: Generation,
759 presented_marker_delivery_seq: Option<DeliverySeq>,
761 result_generation: Generation,
763 current_generation: Generation,
765 reason: ReceiptExpiryReason,
767 },
768}
769
770#[derive(Clone, Copy, Debug, PartialEq, Eq)]
775pub enum EnrollmentReceiptCapacityScope {
776 LiveReceiptServer,
778 ProvenanceServer,
780 ProvenanceConversation,
782}
783
784impl EnrollmentReceiptCapacityScope {
785 #[must_use]
787 pub const fn wire_scope(self) -> ReceiptCapacityScope {
788 match self {
789 Self::LiveReceiptServer => ReceiptCapacityScope::LiveReceiptServer,
790 Self::ProvenanceServer => ReceiptCapacityScope::ProvenanceServer,
791 Self::ProvenanceConversation => ReceiptCapacityScope::ProvenanceConversation,
792 }
793 }
794}
795
796#[derive(Clone, Debug, PartialEq, Eq)]
798pub enum ReceiptCapacityExceeded {
799 Enrollment {
801 request: EnrollmentEnvelope,
803 scope: EnrollmentReceiptCapacityScope,
805 limit: u64,
807 occupied: u64,
809 },
810 CredentialAttach {
812 request: AttachEnvelope,
814 scope: ReceiptCapacityScope,
816 limit: u64,
818 occupied: u64,
820 },
821}
822
823impl ReceiptCapacityExceeded {
824 pub const REQUESTED: u64 = 1;
826}
827
828#[derive(Clone, Debug, PartialEq, Eq)]
830pub struct IdentityCapacityExceeded {
831 pub request: EnrollmentEnvelope,
833 pub scope: IdentityCapacityScope,
835 pub limit: u64,
837 pub occupied: u64,
839}
840
841impl IdentityCapacityExceeded {
842 pub const REQUESTED: u64 = 1;
844}
845
846#[derive(Clone, Copy, Debug, PartialEq, Eq)]
848pub struct ObserverBackpressureState {
849 backpressure_epoch: ObserverEpoch,
851 observer_progress: DeliverySeq,
853}
854
855impl ObserverBackpressureState {
856 #[must_use]
861 pub const fn initial(observer_progress: DeliverySeq) -> Self {
862 Self {
863 backpressure_epoch: observer_progress,
864 observer_progress,
865 }
866 }
867
868 #[must_use]
874 pub const fn replay(
875 backpressure_epoch: ObserverEpoch,
876 observer_progress: DeliverySeq,
877 ) -> Option<Self> {
878 if backpressure_epoch == observer_progress {
879 Some(Self {
880 backpressure_epoch,
881 observer_progress,
882 })
883 } else {
884 None
885 }
886 }
887
888 #[must_use]
890 pub const fn backpressure_epoch(self) -> ObserverEpoch {
891 self.backpressure_epoch
892 }
893
894 #[must_use]
896 pub const fn observer_progress(self) -> DeliverySeq {
897 self.observer_progress
898 }
899}
900
901#[derive(Clone, Debug, PartialEq, Eq)]
903pub enum ObserverBackpressure {
904 Enrollment {
906 request: EnrollmentEnvelope,
908 state: ObserverBackpressureState,
910 },
911 CredentialAttach {
913 request: AttachEnvelope,
915 state: ObserverBackpressureState,
917 },
918 Detach {
920 request: DetachEnvelope,
922 committed_binding_epoch: BindingEpoch,
924 state: ObserverBackpressureState,
926 },
927 Leave {
929 request: LeaveEnvelope,
931 state: ObserverBackpressureState,
933 prior_terminal_cell_exists: bool,
935 },
936 RecordAdmission {
938 request: RecordAdmissionEnvelope,
940 state: ObserverBackpressureState,
942 },
943}
944
945#[derive(Clone, Copy, Debug, PartialEq, Eq)]
959pub enum MarkerSettlementBackpressure {
960 CredentialAttach {
962 conversation_id: ConversationId,
964 refused_epoch: SettlementEpoch,
966 },
967 Detach {
969 conversation_id: ConversationId,
971 refused_epoch: SettlementEpoch,
973 },
974}
975
976#[derive(Clone, Copy, Debug, PartialEq, Eq)]
987pub struct EnrollmentSettlementBackpressure {
988 pub conversation_id: ConversationId,
990}
991
992#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1002pub enum RecordAdmissionFaultClass {
1003 Projection,
1005 Order,
1007 Sequence,
1009 RequiredCapacity,
1011 RefusalInvariant,
1013}
1014
1015impl RecordAdmissionFaultClass {
1016 #[must_use]
1018 pub const fn tag(self) -> RecordAdmissionFaultClassTag {
1019 match self {
1020 Self::Projection => RecordAdmissionFaultClassTag::Projection,
1021 Self::Order => RecordAdmissionFaultClassTag::Order,
1022 Self::Sequence => RecordAdmissionFaultClassTag::Sequence,
1023 Self::RequiredCapacity => RecordAdmissionFaultClassTag::RequiredCapacity,
1024 Self::RefusalInvariant => RecordAdmissionFaultClassTag::RefusalInvariant,
1025 }
1026 }
1027}
1028
1029impl From<RecordAdmissionFaultClassTag> for RecordAdmissionFaultClass {
1030 fn from(tag: RecordAdmissionFaultClassTag) -> Self {
1031 match tag {
1032 RecordAdmissionFaultClassTag::Projection => Self::Projection,
1033 RecordAdmissionFaultClassTag::Order => Self::Order,
1034 RecordAdmissionFaultClassTag::Sequence => Self::Sequence,
1035 RecordAdmissionFaultClassTag::RequiredCapacity => Self::RequiredCapacity,
1036 RecordAdmissionFaultClassTag::RefusalInvariant => Self::RefusalInvariant,
1037 }
1038 }
1039}
1040
1041#[derive(Clone, Debug, PartialEq, Eq)]
1060pub struct RecordAdmissionProtocolFault {
1061 pub request: RecordAdmissionEnvelope,
1063 pub class: RecordAdmissionFaultClass,
1065}
1066
1067#[derive(Clone, Debug, PartialEq, Eq)]
1083pub enum WriteOutcomeUnknown {
1084 Enrollment {
1086 request: EnrollmentEnvelope,
1088 },
1089 CredentialAttach {
1091 request: AttachEnvelope,
1093 },
1094 Detach {
1096 request: DetachEnvelope,
1098 },
1099 Leave {
1101 request: LeaveEnvelope,
1103 },
1104 RecordAdmission {
1106 request: RecordAdmissionEnvelope,
1108 },
1109}
1110
1111#[derive(Clone, Debug, PartialEq, Eq)]
1113pub enum SequenceAllocatingEnvelope {
1114 Enrollment(EnrollmentEnvelope),
1116 CredentialAttach(AttachEnvelope),
1118 RecordAdmission(RecordAdmissionEnvelope),
1120}
1121
1122#[derive(Clone, Debug, PartialEq, Eq)]
1124pub struct ConversationSequenceExhausted {
1125 pub request: SequenceAllocatingEnvelope,
1127 pub sequence_budget: SequenceBudget,
1129}
1130
1131#[derive(Clone, Debug, PartialEq, Eq)]
1133pub struct AttachBound {
1134 conversation_id: ConversationId,
1136 token: AttachAttemptToken,
1138 participant_id: ParticipantId,
1140 request_generation: Generation,
1142 attach_secret: AttachSecret,
1144 origin_binding_epoch: BindingEpoch,
1146 persisted_cursor: DeliverySeq,
1148 accepted_marker_delivery_seq: Option<DeliverySeq>,
1150 receipt_expires_at: u128,
1152 provenance_expires_at: u128,
1154}
1155
1156impl AttachBound {
1157 #[must_use]
1163 #[allow(clippy::too_many_arguments)]
1164 pub const fn ordinary(
1165 conversation_id: ConversationId,
1166 token: AttachAttemptToken,
1167 participant_id: ParticipantId,
1168 request_generation: Generation,
1169 attach_secret: AttachSecret,
1170 origin_binding_epoch: BindingEpoch,
1171 persisted_cursor: DeliverySeq,
1172 receipt_expires_at: u128,
1173 provenance_expires_at: u128,
1174 ) -> Option<Self> {
1175 if !is_successor_generation(
1176 request_generation,
1177 origin_binding_epoch.capability_generation,
1178 ) {
1179 return None;
1180 }
1181 Some(Self {
1182 conversation_id,
1183 token,
1184 participant_id,
1185 request_generation,
1186 attach_secret,
1187 origin_binding_epoch,
1188 persisted_cursor,
1189 accepted_marker_delivery_seq: None,
1190 receipt_expires_at,
1191 provenance_expires_at,
1192 })
1193 }
1194
1195 #[must_use]
1201 #[allow(clippy::too_many_arguments)]
1202 pub const fn fenced(
1203 conversation_id: ConversationId,
1204 token: AttachAttemptToken,
1205 participant_id: ParticipantId,
1206 request_generation: Generation,
1207 attach_secret: AttachSecret,
1208 origin_binding_epoch: BindingEpoch,
1209 accepted_marker_delivery_seq: DeliverySeq,
1210 receipt_expires_at: u128,
1211 provenance_expires_at: u128,
1212 ) -> Option<Self> {
1213 if !is_successor_generation(
1214 request_generation,
1215 origin_binding_epoch.capability_generation,
1216 ) {
1217 return None;
1218 }
1219 Some(Self {
1220 conversation_id,
1221 token,
1222 participant_id,
1223 request_generation,
1224 attach_secret,
1225 origin_binding_epoch,
1226 persisted_cursor: accepted_marker_delivery_seq,
1227 accepted_marker_delivery_seq: Some(accepted_marker_delivery_seq),
1228 receipt_expires_at,
1229 provenance_expires_at,
1230 })
1231 }
1232
1233 #[must_use]
1235 pub const fn conversation_id(&self) -> ConversationId {
1236 self.conversation_id
1237 }
1238
1239 #[must_use]
1241 pub const fn token(&self) -> AttachAttemptToken {
1242 self.token
1243 }
1244
1245 #[must_use]
1247 pub const fn participant_id(&self) -> ParticipantId {
1248 self.participant_id
1249 }
1250
1251 #[must_use]
1253 pub const fn request_generation(&self) -> Generation {
1254 self.request_generation
1255 }
1256
1257 #[must_use]
1259 pub const fn capability_generation(&self) -> Generation {
1260 self.origin_binding_epoch.capability_generation
1261 }
1262
1263 #[must_use]
1265 pub const fn attach_secret(&self) -> AttachSecret {
1266 self.attach_secret
1267 }
1268
1269 #[must_use]
1271 pub const fn origin_binding_epoch(&self) -> BindingEpoch {
1272 self.origin_binding_epoch
1273 }
1274
1275 #[must_use]
1277 pub const fn persisted_cursor(&self) -> DeliverySeq {
1278 self.persisted_cursor
1279 }
1280
1281 #[must_use]
1283 pub const fn accepted_marker_delivery_seq(&self) -> Option<DeliverySeq> {
1284 self.accepted_marker_delivery_seq
1285 }
1286
1287 #[must_use]
1289 pub const fn receipt_expires_at(&self) -> u128 {
1290 self.receipt_expires_at
1291 }
1292
1293 #[must_use]
1295 pub const fn provenance_expires_at(&self) -> u128 {
1296 self.provenance_expires_at
1297 }
1298}
1299
1300const fn is_successor_generation(previous: Generation, successor: Generation) -> bool {
1301 match previous.get().checked_add(1) {
1302 Some(expected) => successor.get() == expected,
1303 None => false,
1304 }
1305}
1306
1307#[derive(Clone, Debug, PartialEq, Eq)]
1309pub struct StaleOrUnknownReceipt {
1310 pub conversation_id: ConversationId,
1312 pub token: AttachAttemptToken,
1314 pub participant_id: ParticipantId,
1316 pub presented_generation: Generation,
1318 pub presented_marker_delivery_seq: Option<DeliverySeq>,
1320 pub current_generation: Generation,
1322}
1323
1324#[derive(Clone, Debug, PartialEq, Eq)]
1326pub struct AttachMarkerProof {
1327 pub conversation_id: ConversationId,
1329 pub token: AttachAttemptToken,
1331 pub participant_id: ParticipantId,
1333 pub capability_generation: Generation,
1335 pub requested_marker_delivery_seq: DeliverySeq,
1337}
1338
1339#[derive(Clone, Debug, PartialEq, Eq)]
1341pub struct MarkerAckProof {
1342 pub conversation_id: ConversationId,
1344 pub participant_id: ParticipantId,
1346 pub capability_generation: Generation,
1348 pub requested_marker_delivery_seq: DeliverySeq,
1350}
1351
1352#[derive(Clone, Debug, PartialEq, Eq)]
1354pub enum MarkerProofRequest {
1355 CredentialAttach(AttachMarkerProof),
1357 MarkerAck(MarkerAckProof),
1359}
1360
1361#[derive(Clone, Debug, PartialEq, Eq)]
1363pub struct MarkerNotDelivered {
1364 pub request: MarkerProofRequest,
1366 pub reason: MarkerNotDeliveredReason,
1368 pub expected_marker_delivery_seq: DeliverySeq,
1370}
1371
1372#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1374pub enum MarkerMismatchBody {
1375 BelowCursor {
1377 current_cursor: DeliverySeq,
1379 },
1380 NoMarkerExpected,
1382 ExpectedDifferentMarker {
1384 expected_marker_delivery_seq: DeliverySeq,
1386 },
1387}
1388
1389impl MarkerMismatchBody {
1390 #[must_use]
1392 pub const fn reason(self) -> MarkerMismatchReason {
1393 match self {
1394 Self::BelowCursor { .. } => MarkerMismatchReason::BelowCursor,
1395 Self::NoMarkerExpected => MarkerMismatchReason::NoMarkerExpected,
1396 Self::ExpectedDifferentMarker { .. } => MarkerMismatchReason::ExpectedDifferentMarker,
1397 }
1398 }
1399}
1400
1401#[derive(Clone, Debug, PartialEq, Eq)]
1403pub struct MarkerMismatch {
1404 pub request: MarkerProofRequest,
1406 pub mismatch: MarkerMismatchBody,
1408}
1409
1410#[derive(Clone, Debug, PartialEq, Eq)]
1412pub enum ReceiptReplay {
1413 Enrollment(EnrollBound),
1416 CredentialAttach(AttachBound),
1419}
1420
1421#[derive(Clone, Debug, PartialEq, Eq)]
1423pub struct DetachCommitted {
1424 conversation_id: ConversationId,
1426 participant_id: ParticipantId,
1428 detach_attempt_token: DetachAttemptToken,
1430 committed_binding_epoch: BindingEpoch,
1432 detached_delivery_seq: DeliverySeq,
1434}
1435
1436impl DetachCommitted {
1437 #[must_use]
1440 pub const fn new(
1441 conversation_id: ConversationId,
1442 participant_id: ParticipantId,
1443 detach_attempt_token: DetachAttemptToken,
1444 committed_binding_epoch: BindingEpoch,
1445 detached_delivery_seq: DeliverySeq,
1446 ) -> Self {
1447 Self {
1448 conversation_id,
1449 participant_id,
1450 detach_attempt_token,
1451 committed_binding_epoch,
1452 detached_delivery_seq,
1453 }
1454 }
1455
1456 #[must_use]
1458 pub const fn conversation_id(&self) -> ConversationId {
1459 self.conversation_id
1460 }
1461
1462 #[must_use]
1464 pub const fn participant_id(&self) -> ParticipantId {
1465 self.participant_id
1466 }
1467
1468 #[must_use]
1470 pub const fn capability_generation(&self) -> Generation {
1471 self.committed_binding_epoch.capability_generation
1472 }
1473
1474 #[must_use]
1476 pub const fn detach_attempt_token(&self) -> DetachAttemptToken {
1477 self.detach_attempt_token
1478 }
1479
1480 #[must_use]
1482 pub const fn committed_binding_epoch(&self) -> BindingEpoch {
1483 self.committed_binding_epoch
1484 }
1485
1486 #[must_use]
1488 pub const fn detached_delivery_seq(&self) -> DeliverySeq {
1489 self.detached_delivery_seq
1490 }
1491}
1492
1493#[derive(Clone, Debug, PartialEq, Eq)]
1495pub struct DetachInProgress {
1496 pub conversation_id: ConversationId,
1498 pub participant_id: ParticipantId,
1500 pub presented_token: DetachAttemptToken,
1502 pub presented_generation: Generation,
1504 pub committed_binding_epoch: BindingEpoch,
1506}
1507
1508#[derive(Clone, Debug, PartialEq, Eq)]
1510pub struct AckCommitted {
1511 request: ParticipantAckEnvelope,
1513}
1514
1515impl AckCommitted {
1516 #[must_use]
1519 pub const fn new(request: ParticipantAckEnvelope) -> Self {
1520 Self { request }
1521 }
1522
1523 #[must_use]
1525 pub const fn request(&self) -> &ParticipantAckEnvelope {
1526 &self.request
1527 }
1528
1529 #[must_use]
1531 pub const fn current_cursor(&self) -> DeliverySeq {
1532 self.request.through_seq
1533 }
1534}
1535
1536#[derive(Clone, Debug, PartialEq, Eq)]
1538pub enum AckNoOp {
1539 ParticipantAck(ParticipantAckEnvelope),
1541 MarkerAck(MarkerAckEnvelope),
1543}
1544
1545impl AckNoOp {
1546 #[must_use]
1549 pub const fn participant_ack(request: ParticipantAckEnvelope) -> Self {
1550 Self::ParticipantAck(request)
1551 }
1552
1553 #[must_use]
1556 pub const fn marker_ack(request: MarkerAckEnvelope) -> Self {
1557 Self::MarkerAck(request)
1558 }
1559
1560 #[must_use]
1562 pub const fn current_cursor(&self) -> DeliverySeq {
1563 match self {
1564 Self::ParticipantAck(request) => request.through_seq,
1565 Self::MarkerAck(request) => request.marker_delivery_seq,
1566 }
1567 }
1568}
1569
1570#[derive(Clone, Debug, PartialEq, Eq)]
1572pub struct AckGap {
1573 request: ParticipantAckEnvelope,
1575 current_cursor: DeliverySeq,
1577}
1578
1579impl AckGap {
1580 #[must_use]
1583 pub const fn new(request: ParticipantAckEnvelope, current_cursor: DeliverySeq) -> Option<Self> {
1584 if request.through_seq > current_cursor {
1585 Some(Self {
1586 request,
1587 current_cursor,
1588 })
1589 } else {
1590 None
1591 }
1592 }
1593
1594 #[must_use]
1596 pub const fn request(&self) -> &ParticipantAckEnvelope {
1597 &self.request
1598 }
1599
1600 #[must_use]
1602 pub const fn current_cursor(&self) -> DeliverySeq {
1603 self.current_cursor
1604 }
1605
1606 #[must_use]
1608 pub const fn reason(&self) -> AckGapReason {
1609 let _ = self;
1610 AckGapReason::NotContiguouslyAvailable
1611 }
1612}
1613
1614#[derive(Clone, Debug, PartialEq, Eq)]
1616pub struct AckRegression {
1617 request: ParticipantAckEnvelope,
1619 current_cursor: DeliverySeq,
1621}
1622
1623impl AckRegression {
1624 #[must_use]
1627 pub const fn new(request: ParticipantAckEnvelope, current_cursor: DeliverySeq) -> Option<Self> {
1628 if request.through_seq < current_cursor {
1629 Some(Self {
1630 request,
1631 current_cursor,
1632 })
1633 } else {
1634 None
1635 }
1636 }
1637
1638 #[must_use]
1640 pub const fn request(&self) -> &ParticipantAckEnvelope {
1641 &self.request
1642 }
1643
1644 #[must_use]
1646 pub const fn current_cursor(&self) -> DeliverySeq {
1647 self.current_cursor
1648 }
1649
1650 #[must_use]
1652 pub const fn reason(&self) -> AckRegressionReason {
1653 let _ = self;
1654 AckRegressionReason::BelowCursor
1655 }
1656}
1657
1658#[derive(Clone, Debug, PartialEq, Eq)]
1660pub struct LeaveCommitted {
1661 conversation_id: ConversationId,
1663 leave_attempt_token: LeaveAttemptToken,
1665 participant_id: ParticipantId,
1667 retired_generation: Generation,
1669 ended_binding_epoch: Option<BindingEpoch>,
1671 prior_terminal_delivery_seq: Option<DeliverySeq>,
1673 left_delivery_seq: DeliverySeq,
1675}
1676
1677impl LeaveCommitted {
1678 #[must_use]
1684 #[allow(clippy::too_many_arguments)]
1685 pub const fn new(
1686 conversation_id: ConversationId,
1687 leave_attempt_token: LeaveAttemptToken,
1688 participant_id: ParticipantId,
1689 retired_generation: Generation,
1690 ended_binding_epoch: Option<BindingEpoch>,
1691 prior_terminal_delivery_seq: Option<DeliverySeq>,
1692 left_delivery_seq: DeliverySeq,
1693 ) -> Option<Self> {
1694 if let Some(epoch) = ended_binding_epoch
1695 && epoch.capability_generation.get() != retired_generation.get()
1696 {
1697 return None;
1698 }
1699 if let Some(prior) = prior_terminal_delivery_seq
1700 && prior >= left_delivery_seq
1701 {
1702 return None;
1703 }
1704 Some(Self {
1705 conversation_id,
1706 leave_attempt_token,
1707 participant_id,
1708 retired_generation,
1709 ended_binding_epoch,
1710 prior_terminal_delivery_seq,
1711 left_delivery_seq,
1712 })
1713 }
1714
1715 #[must_use]
1717 pub const fn conversation_id(&self) -> ConversationId {
1718 self.conversation_id
1719 }
1720
1721 #[must_use]
1723 pub const fn leave_attempt_token(&self) -> LeaveAttemptToken {
1724 self.leave_attempt_token
1725 }
1726
1727 #[must_use]
1729 pub const fn participant_id(&self) -> ParticipantId {
1730 self.participant_id
1731 }
1732
1733 #[must_use]
1735 pub const fn presented_generation(&self) -> Generation {
1736 self.retired_generation
1737 }
1738
1739 #[must_use]
1741 pub const fn retired_generation(&self) -> Generation {
1742 self.retired_generation
1743 }
1744
1745 #[must_use]
1747 pub const fn ended_binding_epoch(&self) -> Option<BindingEpoch> {
1748 self.ended_binding_epoch
1749 }
1750
1751 #[must_use]
1753 pub const fn prior_terminal_delivery_seq(&self) -> Option<DeliverySeq> {
1754 self.prior_terminal_delivery_seq
1755 }
1756
1757 #[must_use]
1759 pub const fn left_delivery_seq(&self) -> DeliverySeq {
1760 self.left_delivery_seq
1761 }
1762}
1763
1764#[derive(Clone, Debug, PartialEq, Eq)]
1766pub struct MarkerAckCommitted {
1767 request: MarkerAckEnvelope,
1769}
1770
1771impl MarkerAckCommitted {
1772 #[must_use]
1775 pub const fn new(request: MarkerAckEnvelope) -> Self {
1776 Self { request }
1777 }
1778
1779 #[must_use]
1781 pub const fn request(&self) -> &MarkerAckEnvelope {
1782 &self.request
1783 }
1784
1785 #[must_use]
1787 pub const fn current_cursor(&self) -> DeliverySeq {
1788 self.request.marker_delivery_seq
1789 }
1790}
1791
1792#[derive(Clone, Debug, PartialEq, Eq)]
1794pub struct RecordCommitted {
1795 request: RecordAdmissionEnvelope,
1797 delivery_seq: DeliverySeq,
1799}
1800
1801impl RecordCommitted {
1802 #[must_use]
1805 pub const fn new(request: RecordAdmissionEnvelope, delivery_seq: DeliverySeq) -> Self {
1806 Self {
1807 request,
1808 delivery_seq,
1809 }
1810 }
1811
1812 #[must_use]
1814 pub const fn request(&self) -> &RecordAdmissionEnvelope {
1815 &self.request
1816 }
1817
1818 #[must_use]
1820 pub const fn sender_participant_id(&self) -> ParticipantId {
1821 self.request.participant_id
1822 }
1823
1824 #[must_use]
1826 pub const fn delivery_seq(&self) -> DeliverySeq {
1827 self.delivery_seq
1828 }
1829}
1830
1831#[derive(Clone, Debug, PartialEq, Eq)]
1833pub struct RecordTooLarge {
1834 pub request: RecordAdmissionEnvelope,
1836 pub dimension: ResourceDimension,
1838 pub encoded_record_charge: ResourceVector,
1840 pub max_ordinary_record_charge: ResourceVector,
1842}
1843
1844#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1846pub struct ObserverProgressStatus {
1847 pub conversation_id: ConversationId,
1849 pub refused_epoch: ObserverEpoch,
1851 pub current_observer_progress: DeliverySeq,
1853 pub armed: bool,
1855 pub progressed: bool,
1857}
1858
1859#[derive(Clone, Debug, PartialEq, Eq)]
1861pub struct ObserverRecoveryAccepted {
1862 pub statuses: Vec<ObserverProgressStatus>,
1864}
1865
1866#[derive(Clone, Debug, PartialEq, Eq)]
1868pub enum InvalidObserverEpoch {
1869 ConversationUnknown {
1871 conversation_id: ConversationId,
1873 presented_epoch: ObserverEpoch,
1875 },
1876 EpochAhead {
1878 conversation_id: ConversationId,
1880 presented_epoch: ObserverEpoch,
1882 current_observer_progress: DeliverySeq,
1884 },
1885}
1886
1887impl InvalidObserverEpoch {
1888 #[must_use]
1890 pub const fn reason(&self) -> InvalidObserverEpochReason {
1891 match self {
1892 Self::ConversationUnknown { .. } => InvalidObserverEpochReason::ConversationUnknown,
1893 Self::EpochAhead { .. } => InvalidObserverEpochReason::EpochAhead,
1894 }
1895 }
1896}
1897
1898#[derive(Clone, Debug, PartialEq, Eq)]
1900pub enum InvalidObserverEpochList {
1901 TooManyEntries {
1903 presented_entries: u64,
1905 max_entries: u64,
1907 },
1908 DuplicateConversation {
1910 conversation_id: ConversationId,
1912 first_index: u64,
1914 duplicate_index: u64,
1916 },
1917}
1918
1919impl InvalidObserverEpochList {
1920 #[must_use]
1922 pub const fn reason(&self) -> InvalidObserverEpochListReason {
1923 match self {
1924 Self::TooManyEntries { .. } => InvalidObserverEpochListReason::TooManyEntries,
1925 Self::DuplicateConversation { .. } => {
1926 InvalidObserverEpochListReason::DuplicateConversation
1927 }
1928 }
1929 }
1930}
1931
1932#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1934pub enum SettlementOutcome {
1935 Committed {
1937 delivery_seq: DeliverySeq,
1939 },
1940 Withdrawn,
1942 Expired,
1944 NotCommitted,
1946 Unknown,
1948}
1949
1950#[derive(Clone, Debug, PartialEq, Eq)]
1952pub struct SettlementAnswer {
1953 pub conversation_id: ConversationId,
1955 pub participant_id: ParticipantId,
1957 pub record_admission_attempt_token: RecordAdmissionAttemptToken,
1959 pub outcome: SettlementOutcome,
1961}
1962
1963#[derive(Clone, Debug, PartialEq, Eq)]
1965pub enum ServerValue {
1966 ParticipantTransportRejected(ParticipantTransportRejected),
1968 AttemptTokenBodyConflict(AttemptTokenBodyConflict),
1970 ConnectionConversationCapacityExceeded(ConnectionConversationCapacityExceeded),
1972 ConnectionConversationBindingOccupied(ConnectionConversationBindingOccupied),
1974 ConversationOrderExhausted(Box<ConversationOrderExhausted>),
1976 ParticipantUnknown(ParticipantUnknown),
1978 NoBinding(NoBinding),
1980 StaleAuthority(StaleAuthority),
1982 Retired(Retired),
1984 MarkerClosureCapacityExceeded(Box<MarkerClosureCapacityExceeded>),
1986 EnrollBound(EnrollBound),
1988 EnrollmentKnown(EnrollmentKnown),
1990 ReceiptExpired(ReceiptExpired),
1992 ReceiptCapacityExceeded(ReceiptCapacityExceeded),
1994 IdentityCapacityExceeded(IdentityCapacityExceeded),
1996 ObserverBackpressure(ObserverBackpressure),
1998 ConversationSequenceExhausted(Box<ConversationSequenceExhausted>),
2000 AttachBound(AttachBound),
2002 StaleOrUnknownReceipt(StaleOrUnknownReceipt),
2004 MarkerNotDelivered(MarkerNotDelivered),
2006 MarkerMismatch(MarkerMismatch),
2008 Bound(ReceiptReplay),
2010 UnboundReceipt(ReceiptReplay),
2012 DetachCommitted(DetachCommitted),
2014 DetachInProgress(DetachInProgress),
2016 AckCommitted(AckCommitted),
2018 AckNoOp(AckNoOp),
2020 AckGap(AckGap),
2022 AckRegression(AckRegression),
2024 LeaveCommitted(LeaveCommitted),
2026 MarkerAckCommitted(MarkerAckCommitted),
2028 RecordCommitted(RecordCommitted),
2030 RecordTooLarge(RecordTooLarge),
2032 ObserverRecoveryAccepted(ObserverRecoveryAccepted),
2034 InvalidObserverEpoch(InvalidObserverEpoch),
2036 InvalidObserverEpochList(InvalidObserverEpochList),
2038 MarkerSettlementBackpressure(MarkerSettlementBackpressure),
2040 EnrollmentSettlementBackpressure(EnrollmentSettlementBackpressure),
2042 RecordAdmissionProtocolFault(RecordAdmissionProtocolFault),
2044 WriteOutcomeUnknown(WriteOutcomeUnknown),
2046 SettlementAnswer(SettlementAnswer),
2048}
2049
2050impl ServerValue {
2051 #[must_use]
2053 pub const fn discriminant(&self) -> ServerDiscriminant {
2054 match self {
2055 Self::ParticipantTransportRejected(_) => {
2056 ServerDiscriminant::ParticipantTransportRejected
2057 }
2058 Self::AttemptTokenBodyConflict(_) => ServerDiscriminant::AttemptTokenBodyConflict,
2059 Self::ConnectionConversationCapacityExceeded(value) => match value {
2060 ConnectionConversationCapacityExceeded::SemanticRequest { .. } => {
2061 ServerDiscriminant::ConnectionConversationCapacityExceeded
2062 }
2063 ConnectionConversationCapacityExceeded::ObserverRecovery { .. } => {
2064 ServerDiscriminant::ObserverRecoveryConnectionCapacityExceeded
2065 }
2066 },
2067 Self::ConnectionConversationBindingOccupied(_) => {
2068 ServerDiscriminant::ConnectionConversationBindingOccupied
2069 }
2070 Self::ConversationOrderExhausted(_) => ServerDiscriminant::ConversationOrderExhausted,
2071 Self::ParticipantUnknown(_) => ServerDiscriminant::ParticipantUnknown,
2072 Self::NoBinding(_) => ServerDiscriminant::NoBinding,
2073 Self::StaleAuthority(_) => ServerDiscriminant::StaleAuthority,
2074 Self::Retired(_) => ServerDiscriminant::Retired,
2075 Self::MarkerClosureCapacityExceeded(_) => {
2076 ServerDiscriminant::MarkerClosureCapacityExceeded
2077 }
2078 Self::EnrollBound(_) => ServerDiscriminant::EnrollBound,
2079 Self::EnrollmentKnown(_) => ServerDiscriminant::EnrollmentKnown,
2080 Self::ReceiptExpired(_) => ServerDiscriminant::ReceiptExpired,
2081 Self::ReceiptCapacityExceeded(_) => ServerDiscriminant::ReceiptCapacityExceeded,
2082 Self::IdentityCapacityExceeded(_) => ServerDiscriminant::IdentityCapacityExceeded,
2083 Self::ObserverBackpressure(_) => ServerDiscriminant::ObserverBackpressure,
2084 Self::ConversationSequenceExhausted(_) => {
2085 ServerDiscriminant::ConversationSequenceExhausted
2086 }
2087 Self::AttachBound(_) => ServerDiscriminant::AttachBound,
2088 Self::StaleOrUnknownReceipt(_) => ServerDiscriminant::StaleOrUnknownReceipt,
2089 Self::MarkerNotDelivered(_) => ServerDiscriminant::MarkerNotDelivered,
2090 Self::MarkerMismatch(_) => ServerDiscriminant::MarkerMismatch,
2091 Self::Bound(_) => ServerDiscriminant::Bound,
2092 Self::UnboundReceipt(_) => ServerDiscriminant::UnboundReceipt,
2093 Self::DetachCommitted(_) => ServerDiscriminant::DetachCommitted,
2094 Self::DetachInProgress(_) => ServerDiscriminant::DetachInProgress,
2095 Self::AckCommitted(_) => ServerDiscriminant::AckCommitted,
2096 Self::AckNoOp(_) => ServerDiscriminant::AckNoOp,
2097 Self::AckGap(_) => ServerDiscriminant::AckGap,
2098 Self::AckRegression(_) => ServerDiscriminant::AckRegression,
2099 Self::LeaveCommitted(_) => ServerDiscriminant::LeaveCommitted,
2100 Self::MarkerAckCommitted(_) => ServerDiscriminant::MarkerAckCommitted,
2101 Self::RecordCommitted(_) => ServerDiscriminant::RecordCommitted,
2102 Self::RecordTooLarge(_) => ServerDiscriminant::RecordTooLarge,
2103 Self::ObserverRecoveryAccepted(_) => ServerDiscriminant::ObserverRecoveryAccepted,
2104 Self::InvalidObserverEpoch(_) => ServerDiscriminant::InvalidObserverEpoch,
2105 Self::InvalidObserverEpochList(_) => ServerDiscriminant::InvalidObserverEpochList,
2106 Self::MarkerSettlementBackpressure(_) => {
2107 ServerDiscriminant::MarkerSettlementBackpressure
2108 }
2109 Self::EnrollmentSettlementBackpressure(_) => {
2110 ServerDiscriminant::EnrollmentSettlementBackpressure
2111 }
2112 Self::RecordAdmissionProtocolFault(_) => {
2113 ServerDiscriminant::RecordAdmissionProtocolFault
2114 }
2115 Self::WriteOutcomeUnknown(_) => ServerDiscriminant::WriteOutcomeUnknown,
2116 Self::SettlementAnswer(_) => ServerDiscriminant::SettlementAnswer,
2117 }
2118 }
2119
2120 #[must_use]
2122 #[allow(clippy::too_many_lines)]
2123 pub const fn originating_request(&self) -> Option<ClientDiscriminant> {
2124 match self {
2125 Self::ParticipantTransportRejected(_)
2126 | Self::ObserverRecoveryAccepted(_)
2127 | Self::InvalidObserverEpoch(_)
2128 | Self::InvalidObserverEpochList(_) => None,
2129 Self::AttemptTokenBodyConflict(value) => Some(match value {
2130 AttemptTokenBodyConflict::CredentialAttach { .. } => {
2131 ClientDiscriminant::CredentialAttachRequest
2132 }
2133 AttemptTokenBodyConflict::Leave { .. } => ClientDiscriminant::LeaveRequest,
2134 AttemptTokenBodyConflict::RecordAdmission { .. } => {
2135 ClientDiscriminant::RecordAdmission
2136 }
2137 }),
2138 Self::ConnectionConversationCapacityExceeded(value) => match value {
2139 ConnectionConversationCapacityExceeded::SemanticRequest { request, .. } => {
2140 Some(request.originating_request())
2141 }
2142 ConnectionConversationCapacityExceeded::ObserverRecovery { .. } => None,
2143 },
2144 Self::ConnectionConversationBindingOccupied(value) => Some(match value {
2145 ConnectionConversationBindingOccupied::Enrollment { .. } => {
2146 ClientDiscriminant::EnrollmentRequest
2147 }
2148 ConnectionConversationBindingOccupied::CredentialAttach { .. } => {
2149 ClientDiscriminant::CredentialAttachRequest
2150 }
2151 }),
2152 Self::ConversationOrderExhausted(value) => Some(match value.request() {
2153 OrderAllocatingEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2154 OrderAllocatingEnvelope::CredentialAttach(_) => {
2155 ClientDiscriminant::CredentialAttachRequest
2156 }
2157 OrderAllocatingEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2158 }),
2159 Self::ParticipantUnknown(value) => Some(participant_reference_origin(&value.request)),
2160 Self::NoBinding(value) => Some(binding_required_origin(&value.request)),
2161 Self::StaleAuthority(value) => Some(stale_authority_origin(value)),
2162 Self::Retired(value) => Some(match value {
2163 Retired::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2164 Retired::Participant { request, .. } => participant_reference_origin(request),
2165 }),
2166 Self::MarkerClosureCapacityExceeded(value) => Some(match &value.request {
2167 ClosureCheckedEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2168 ClosureCheckedEnvelope::CredentialAttach(_) => {
2169 ClientDiscriminant::CredentialAttachRequest
2170 }
2171 ClosureCheckedEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
2172 ClosureCheckedEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2173 }),
2174 Self::EnrollBound(_)
2175 | Self::EnrollmentKnown(_)
2176 | Self::IdentityCapacityExceeded(_)
2177 | Self::EnrollmentSettlementBackpressure(_) => {
2178 Some(ClientDiscriminant::EnrollmentRequest)
2179 }
2180 Self::ReceiptExpired(value) => Some(match value {
2181 ReceiptExpired::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2182 ReceiptExpired::CredentialAttach { .. } => {
2183 ClientDiscriminant::CredentialAttachRequest
2184 }
2185 }),
2186 Self::ReceiptCapacityExceeded(value) => Some(match value {
2187 ReceiptCapacityExceeded::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2188 ReceiptCapacityExceeded::CredentialAttach { .. } => {
2189 ClientDiscriminant::CredentialAttachRequest
2190 }
2191 }),
2192 Self::ObserverBackpressure(value) => Some(match value {
2193 ObserverBackpressure::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2194 ObserverBackpressure::CredentialAttach { .. } => {
2195 ClientDiscriminant::CredentialAttachRequest
2196 }
2197 ObserverBackpressure::Detach { .. } => ClientDiscriminant::DetachRequest,
2198 ObserverBackpressure::Leave { .. } => ClientDiscriminant::LeaveRequest,
2199 ObserverBackpressure::RecordAdmission { .. } => ClientDiscriminant::RecordAdmission,
2200 }),
2201 Self::ConversationSequenceExhausted(value) => Some(match &value.request {
2202 SequenceAllocatingEnvelope::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2203 SequenceAllocatingEnvelope::CredentialAttach(_) => {
2204 ClientDiscriminant::CredentialAttachRequest
2205 }
2206 SequenceAllocatingEnvelope::RecordAdmission(_) => {
2207 ClientDiscriminant::RecordAdmission
2208 }
2209 }),
2210 Self::AttachBound(_) | Self::StaleOrUnknownReceipt(_) => {
2211 Some(ClientDiscriminant::CredentialAttachRequest)
2212 }
2213 Self::MarkerNotDelivered(value) => Some(marker_proof_origin(&value.request)),
2214 Self::MarkerMismatch(value) => Some(marker_proof_origin(&value.request)),
2215 Self::Bound(value) | Self::UnboundReceipt(value) => Some(match value {
2216 ReceiptReplay::Enrollment(_) => ClientDiscriminant::EnrollmentRequest,
2217 ReceiptReplay::CredentialAttach(_) => ClientDiscriminant::CredentialAttachRequest,
2218 }),
2219 Self::DetachCommitted(_) | Self::DetachInProgress(_) => {
2220 Some(ClientDiscriminant::DetachRequest)
2221 }
2222 Self::AckCommitted(_) | Self::AckGap(_) | Self::AckRegression(_) => {
2223 Some(ClientDiscriminant::ParticipantAck)
2224 }
2225 Self::AckNoOp(value) => Some(match value {
2226 AckNoOp::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2227 AckNoOp::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2228 }),
2229 Self::LeaveCommitted(_) => Some(ClientDiscriminant::LeaveRequest),
2230 Self::MarkerAckCommitted(_) => Some(ClientDiscriminant::MarkerAck),
2231 Self::RecordCommitted(_)
2232 | Self::RecordTooLarge(_)
2233 | Self::RecordAdmissionProtocolFault(_) => Some(ClientDiscriminant::RecordAdmission),
2234 Self::MarkerSettlementBackpressure(value) => Some(match value {
2235 MarkerSettlementBackpressure::CredentialAttach { .. } => {
2236 ClientDiscriminant::CredentialAttachRequest
2237 }
2238 MarkerSettlementBackpressure::Detach { .. } => ClientDiscriminant::DetachRequest,
2239 }),
2240 Self::SettlementAnswer(_) => Some(ClientDiscriminant::SettlementQuery),
2241 Self::WriteOutcomeUnknown(value) => Some(match value {
2242 WriteOutcomeUnknown::Enrollment { .. } => ClientDiscriminant::EnrollmentRequest,
2243 WriteOutcomeUnknown::CredentialAttach { .. } => {
2244 ClientDiscriminant::CredentialAttachRequest
2245 }
2246 WriteOutcomeUnknown::Detach { .. } => ClientDiscriminant::DetachRequest,
2247 WriteOutcomeUnknown::Leave { .. } => ClientDiscriminant::LeaveRequest,
2248 WriteOutcomeUnknown::RecordAdmission { .. } => ClientDiscriminant::RecordAdmission,
2249 }),
2250 }
2251 }
2252}
2253
2254const fn participant_reference_origin(
2255 request: &ParticipantReferenceEnvelope,
2256) -> ClientDiscriminant {
2257 match request {
2258 ParticipantReferenceEnvelope::CredentialAttach(_) => {
2259 ClientDiscriminant::CredentialAttachRequest
2260 }
2261 ParticipantReferenceEnvelope::Detach(_) => ClientDiscriminant::DetachRequest,
2262 ParticipantReferenceEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2263 ParticipantReferenceEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
2264 ParticipantReferenceEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2265 ParticipantReferenceEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2266 }
2267}
2268
2269const fn binding_required_origin(request: &BindingRequiredEnvelope) -> ClientDiscriminant {
2270 match request {
2271 BindingRequiredEnvelope::Detach(_) => ClientDiscriminant::DetachRequest,
2272 BindingRequiredEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2273 BindingRequiredEnvelope::Leave(_) => ClientDiscriminant::LeaveRequest,
2274 BindingRequiredEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2275 BindingRequiredEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2276 }
2277}
2278
2279const fn stale_authority_origin(value: &StaleAuthority) -> ClientDiscriminant {
2280 match value {
2281 StaleAuthority::Live { request, .. } => match request {
2282 CommonStaleAuthorityEnvelope::CredentialAttach(_) => {
2283 ClientDiscriminant::CredentialAttachRequest
2284 }
2285 CommonStaleAuthorityEnvelope::ParticipantAck(_) => ClientDiscriminant::ParticipantAck,
2286 CommonStaleAuthorityEnvelope::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2287 CommonStaleAuthorityEnvelope::RecordAdmission(_) => ClientDiscriminant::RecordAdmission,
2288 },
2289 StaleAuthority::Detach(_) => ClientDiscriminant::DetachRequest,
2290 StaleAuthority::Leave(_) => ClientDiscriminant::LeaveRequest,
2291 }
2292}
2293
2294const fn marker_proof_origin(request: &MarkerProofRequest) -> ClientDiscriminant {
2295 match request {
2296 MarkerProofRequest::CredentialAttach(_) => ClientDiscriminant::CredentialAttachRequest,
2297 MarkerProofRequest::MarkerAck(_) => ClientDiscriminant::MarkerAck,
2298 }
2299}
2300
2301pub const PARTICIPANT_CAPABILITY: &str = "participant-v1";
2303
2304#[must_use]
2306pub const fn attempt_operation(value: &AttemptTokenBodyConflict) -> super::AttemptOperation {
2307 match value {
2308 AttemptTokenBodyConflict::CredentialAttach { .. } => {
2309 super::AttemptOperation::CredentialAttachRequest
2310 }
2311 AttemptTokenBodyConflict::Leave { .. } => super::AttemptOperation::LeaveRequest,
2312 AttemptTokenBodyConflict::RecordAdmission { .. } => {
2313 super::AttemptOperation::RecordAdmission
2314 }
2315 }
2316}
2317
2318#[must_use]
2320pub fn capability_string() -> String {
2321 String::from(PARTICIPANT_CAPABILITY)
2322}