1use crate::outcome::CandidatePhase;
2use crate::wire::{
3 BindingEpoch, CloseCause, ConversationId, DeliverySeq, DetachedCause, DiedCause, ParticipantId,
4 ParticipantIndex, TransactionOrder,
5};
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
14pub struct AdmissionOrder {
15 transaction_order: TransactionOrder,
16 candidate_phase: CandidatePhase,
17 participant_index: ParticipantIndex,
18}
19
20impl AdmissionOrder {
21 #[must_use]
23 pub const fn new(
24 transaction_order: TransactionOrder,
25 candidate_phase: CandidatePhase,
26 participant_index: ParticipantIndex,
27 ) -> Self {
28 Self {
29 transaction_order,
30 candidate_phase,
31 participant_index,
32 }
33 }
34
35 #[must_use]
37 pub const fn binding_terminal(
38 transaction_order: TransactionOrder,
39 participant_id: ParticipantId,
40 ) -> Self {
41 Self::new(
42 transaction_order,
43 CandidatePhase::BindingTerminal,
44 participant_id,
45 )
46 }
47
48 #[must_use]
50 pub const fn transaction_order(self) -> TransactionOrder {
51 self.transaction_order
52 }
53
54 #[must_use]
56 pub const fn candidate_phase(self) -> CandidatePhase {
57 self.candidate_phase
58 }
59
60 #[must_use]
62 pub const fn participant_index(self) -> ParticipantIndex {
63 self.participant_index
64 }
65}
66
67#[derive(Clone, Copy, Debug, PartialEq, Eq)]
69pub struct ActiveBinding {
70 pub participant_id: ParticipantId,
72 pub conversation_id: ConversationId,
74 pub binding_epoch: BindingEpoch,
76}
77
78#[derive(Clone, Copy, Debug, PartialEq, Eq)]
80pub struct CommittedBindingTerminalPosition {
81 transaction_order: TransactionOrder,
82 delivery_seq: DeliverySeq,
83}
84
85impl CommittedBindingTerminalPosition {
86 #[must_use]
88 pub const fn new(transaction_order: TransactionOrder, delivery_seq: DeliverySeq) -> Self {
89 Self {
90 transaction_order,
91 delivery_seq,
92 }
93 }
94
95 #[must_use]
97 pub const fn transaction_order(self) -> TransactionOrder {
98 self.transaction_order
99 }
100
101 #[must_use]
103 pub const fn delivery_seq(self) -> DeliverySeq {
104 self.delivery_seq
105 }
106}
107
108#[derive(Clone, Copy, Debug, PartialEq, Eq)]
110pub struct PendingBindingTerminalPosition {
111 transaction_order: TransactionOrder,
112}
113
114impl PendingBindingTerminalPosition {
115 #[must_use]
117 pub const fn new(transaction_order: TransactionOrder) -> Self {
118 Self { transaction_order }
119 }
120
121 #[must_use]
123 pub const fn transaction_order(self) -> TransactionOrder {
124 self.transaction_order
125 }
126}
127
128#[derive(Clone, Copy, Debug, PartialEq, Eq)]
130pub enum BindingTerminalDisposition {
131 Committed(CommittedBindingTerminalPosition),
133 Pending(PendingBindingTerminalPosition),
135}
136
137#[derive(Clone, Copy, Debug, PartialEq, Eq)]
138struct BindingTerminalIdentity {
139 participant_id: ParticipantId,
140 conversation_id: ConversationId,
141 binding_epoch: BindingEpoch,
142 admission_order: AdmissionOrder,
143}
144
145impl BindingTerminalIdentity {
146 const fn from_active(binding: ActiveBinding, transaction_order: TransactionOrder) -> Self {
147 Self {
148 participant_id: binding.participant_id,
149 conversation_id: binding.conversation_id,
150 binding_epoch: binding.binding_epoch,
151 admission_order: AdmissionOrder::binding_terminal(
152 transaction_order,
153 binding.participant_id,
154 ),
155 }
156 }
157}
158
159#[derive(Clone, Copy, Debug, PartialEq, Eq)]
161pub struct CommittedDetachedTerminal {
162 identity: BindingTerminalIdentity,
163 cause: DetachedCause,
164 delivery_seq: DeliverySeq,
165}
166
167impl CommittedDetachedTerminal {
168 #[must_use]
170 pub const fn participant_id(self) -> ParticipantId {
171 self.identity.participant_id
172 }
173
174 #[must_use]
176 pub const fn conversation_id(self) -> ConversationId {
177 self.identity.conversation_id
178 }
179
180 #[must_use]
182 pub const fn binding_epoch(self) -> BindingEpoch {
183 self.identity.binding_epoch
184 }
185
186 #[must_use]
188 pub const fn cause(self) -> DetachedCause {
189 self.cause
190 }
191
192 #[must_use]
194 pub const fn admission_order(self) -> AdmissionOrder {
195 self.identity.admission_order
196 }
197
198 #[must_use]
200 pub const fn delivery_seq(self) -> DeliverySeq {
201 self.delivery_seq
202 }
203}
204
205#[derive(Clone, Copy, Debug, PartialEq, Eq)]
207pub struct CommittedDiedTerminal {
208 identity: BindingTerminalIdentity,
209 cause: DiedCause,
210 delivery_seq: DeliverySeq,
211}
212
213impl CommittedDiedTerminal {
214 #[must_use]
216 pub const fn participant_id(self) -> ParticipantId {
217 self.identity.participant_id
218 }
219
220 #[must_use]
222 pub const fn conversation_id(self) -> ConversationId {
223 self.identity.conversation_id
224 }
225
226 #[must_use]
228 pub const fn binding_epoch(self) -> BindingEpoch {
229 self.identity.binding_epoch
230 }
231
232 #[must_use]
234 pub const fn cause(self) -> DiedCause {
235 self.cause
236 }
237
238 #[must_use]
240 pub const fn admission_order(self) -> AdmissionOrder {
241 self.identity.admission_order
242 }
243
244 #[must_use]
246 pub const fn delivery_seq(self) -> DeliverySeq {
247 self.delivery_seq
248 }
249}
250
251#[derive(Clone, Copy, Debug, PartialEq, Eq)]
256pub enum CommittedBindingTerminal {
257 Detached(CommittedDetachedTerminal),
259 Died(CommittedDiedTerminal),
261}
262
263impl CommittedBindingTerminal {
264 #[must_use]
266 pub const fn participant_id(self) -> ParticipantId {
267 match self {
268 Self::Detached(value) => value.participant_id(),
269 Self::Died(value) => value.participant_id(),
270 }
271 }
272
273 #[must_use]
275 pub const fn conversation_id(self) -> ConversationId {
276 match self {
277 Self::Detached(value) => value.conversation_id(),
278 Self::Died(value) => value.conversation_id(),
279 }
280 }
281
282 #[must_use]
284 pub const fn binding_epoch(self) -> BindingEpoch {
285 match self {
286 Self::Detached(value) => value.binding_epoch(),
287 Self::Died(value) => value.binding_epoch(),
288 }
289 }
290
291 #[must_use]
293 pub const fn admission_order(self) -> AdmissionOrder {
294 match self {
295 Self::Detached(value) => value.admission_order(),
296 Self::Died(value) => value.admission_order(),
297 }
298 }
299
300 #[must_use]
302 pub const fn delivery_seq(self) -> DeliverySeq {
303 match self {
304 Self::Detached(value) => value.delivery_seq(),
305 Self::Died(value) => value.delivery_seq(),
306 }
307 }
308
309 #[must_use]
311 pub const fn kind(self) -> BindingTerminalKind {
312 match self {
313 Self::Detached(_) => BindingTerminalKind::Detached,
314 Self::Died(_) => BindingTerminalKind::Died,
315 }
316 }
317
318 #[must_use]
320 pub const fn close_cause(self) -> CloseCause {
321 match self {
322 Self::Detached(value) => value.cause().close_cause(),
323 Self::Died(value) => value.cause().close_cause(),
324 }
325 }
326
327 #[must_use]
329 pub const fn detached_cause(self) -> Option<DetachedCause> {
330 match self {
331 Self::Detached(value) => Some(value.cause()),
332 Self::Died(_) => None,
333 }
334 }
335
336 #[must_use]
338 pub const fn died_cause(self) -> Option<DiedCause> {
339 match self {
340 Self::Detached(_) => None,
341 Self::Died(value) => Some(value.cause()),
342 }
343 }
344
345 #[must_use]
351 pub const fn storage_description(self) -> super::storage::CommittedBindingTerminalRestore {
352 super::storage::CommittedBindingTerminalRestore {
353 binding: ActiveBinding {
354 participant_id: self.participant_id(),
355 conversation_id: self.conversation_id(),
356 binding_epoch: self.binding_epoch(),
357 },
358 cause: self.close_cause(),
359 transaction_order: self.admission_order().transaction_order(),
360 delivery_seq: self.delivery_seq(),
361 }
362 }
363}
364
365impl From<CommittedDetachedTerminal> for CommittedBindingTerminal {
366 fn from(value: CommittedDetachedTerminal) -> Self {
367 Self::Detached(value)
368 }
369}
370
371impl From<CommittedDiedTerminal> for CommittedBindingTerminal {
372 fn from(value: CommittedDiedTerminal) -> Self {
373 Self::Died(value)
374 }
375}
376
377#[derive(Clone, Copy, Debug, PartialEq, Eq)]
379pub struct PendingDetachedFinalization {
380 identity: BindingTerminalIdentity,
381 cause: DetachedCause,
382}
383
384impl PendingDetachedFinalization {
385 #[must_use]
387 pub const fn participant_id(self) -> ParticipantId {
388 self.identity.participant_id
389 }
390
391 #[must_use]
393 pub const fn conversation_id(self) -> ConversationId {
394 self.identity.conversation_id
395 }
396
397 #[must_use]
399 pub const fn binding_epoch(self) -> BindingEpoch {
400 self.identity.binding_epoch
401 }
402
403 #[must_use]
405 pub const fn cause(self) -> DetachedCause {
406 self.cause
407 }
408
409 #[must_use]
411 pub const fn admission_order(self) -> AdmissionOrder {
412 self.identity.admission_order
413 }
414
415 #[must_use]
417 pub const fn commit(self, delivery_seq: DeliverySeq) -> CommittedDetachedTerminal {
418 CommittedDetachedTerminal {
419 identity: self.identity,
420 cause: self.cause,
421 delivery_seq,
422 }
423 }
424}
425
426#[derive(Clone, Copy, Debug, PartialEq, Eq)]
428pub struct PendingDiedFinalization {
429 identity: BindingTerminalIdentity,
430 cause: DiedCause,
431}
432
433impl PendingDiedFinalization {
434 #[must_use]
436 pub const fn participant_id(self) -> ParticipantId {
437 self.identity.participant_id
438 }
439
440 #[must_use]
442 pub const fn conversation_id(self) -> ConversationId {
443 self.identity.conversation_id
444 }
445
446 #[must_use]
448 pub const fn binding_epoch(self) -> BindingEpoch {
449 self.identity.binding_epoch
450 }
451
452 #[must_use]
454 pub const fn cause(self) -> DiedCause {
455 self.cause
456 }
457
458 #[must_use]
460 pub const fn admission_order(self) -> AdmissionOrder {
461 self.identity.admission_order
462 }
463
464 #[must_use]
466 pub const fn commit(self, delivery_seq: DeliverySeq) -> CommittedDiedTerminal {
467 CommittedDiedTerminal {
468 identity: self.identity,
469 cause: self.cause,
470 delivery_seq,
471 }
472 }
473}
474
475#[derive(Clone, Copy, Debug, PartialEq, Eq)]
477pub enum BindingTerminalKind {
478 Detached,
480 Died,
482}
483
484#[derive(Clone, Copy, Debug, PartialEq, Eq)]
491pub enum PendingFinalization {
492 Detached(PendingDetachedFinalization),
494 Died(PendingDiedFinalization),
496}
497
498impl PendingFinalization {
499 #[must_use]
501 pub const fn participant_id(self) -> ParticipantId {
502 match self {
503 Self::Detached(value) => value.participant_id(),
504 Self::Died(value) => value.participant_id(),
505 }
506 }
507
508 #[must_use]
510 pub const fn conversation_id(self) -> ConversationId {
511 match self {
512 Self::Detached(value) => value.conversation_id(),
513 Self::Died(value) => value.conversation_id(),
514 }
515 }
516
517 #[must_use]
519 pub const fn binding_epoch(self) -> BindingEpoch {
520 match self {
521 Self::Detached(value) => value.binding_epoch(),
522 Self::Died(value) => value.binding_epoch(),
523 }
524 }
525
526 #[must_use]
528 pub const fn admission_order(self) -> AdmissionOrder {
529 match self {
530 Self::Detached(value) => value.admission_order(),
531 Self::Died(value) => value.admission_order(),
532 }
533 }
534
535 #[must_use]
537 pub const fn kind(self) -> BindingTerminalKind {
538 match self {
539 Self::Detached(_) => BindingTerminalKind::Detached,
540 Self::Died(_) => BindingTerminalKind::Died,
541 }
542 }
543
544 #[must_use]
546 pub const fn close_cause(self) -> CloseCause {
547 match self {
548 Self::Detached(value) => value.cause().close_cause(),
549 Self::Died(value) => value.cause().close_cause(),
550 }
551 }
552
553 #[must_use]
555 pub const fn detached_cause(self) -> Option<DetachedCause> {
556 match self {
557 Self::Detached(value) => Some(value.cause()),
558 Self::Died(_) => None,
559 }
560 }
561
562 #[must_use]
564 pub const fn died_cause(self) -> Option<DiedCause> {
565 match self {
566 Self::Detached(_) => None,
567 Self::Died(value) => Some(value.cause()),
568 }
569 }
570
571 #[must_use]
573 pub const fn commit(self, delivery_seq: DeliverySeq) -> CommittedBindingTerminal {
574 match self {
575 Self::Detached(value) => CommittedBindingTerminal::Detached(value.commit(delivery_seq)),
576 Self::Died(value) => CommittedBindingTerminal::Died(value.commit(delivery_seq)),
577 }
578 }
579
580 #[must_use]
586 pub const fn storage_description(self) -> super::storage::PendingFinalizationRestore {
587 super::storage::PendingFinalizationRestore {
588 binding: ActiveBinding {
589 participant_id: self.participant_id(),
590 conversation_id: self.conversation_id(),
591 binding_epoch: self.binding_epoch(),
592 },
593 cause: self.close_cause(),
594 transaction_order: self.admission_order().transaction_order(),
595 }
596 }
597}
598
599impl From<PendingDetachedFinalization> for PendingFinalization {
600 fn from(value: PendingDetachedFinalization) -> Self {
601 Self::Detached(value)
602 }
603}
604
605impl From<PendingDiedFinalization> for PendingFinalization {
606 fn from(value: PendingDiedFinalization) -> Self {
607 Self::Died(value)
608 }
609}
610
611#[derive(Clone, Copy, Debug, PartialEq, Eq)]
613pub enum DetachedBindingTransition {
614 Committed(CommittedDetachedTerminal),
616 Pending(PendingDetachedFinalization),
618}
619
620impl DetachedBindingTransition {
621 #[must_use]
623 pub const fn observer_progress_projection(&self) -> Option<super::ObserverProgressProjection> {
624 let Self::Committed(terminal) = self else {
625 return None;
626 };
627 Some(super::ObserverProgressProjection::sourced(
628 terminal.conversation_id(),
629 terminal.delivery_seq(),
630 super::checkpoint_codec::ObserverProjectionSource::Terminal(
631 CommittedBindingTerminal::Detached(*terminal).storage_description(),
632 ),
633 ))
634 }
635
636 #[must_use]
638 pub const fn binding_state(self) -> BindingState {
639 match self {
640 Self::Committed(_) => BindingState::Detached,
641 Self::Pending(value) => {
642 BindingState::PendingFinalization(PendingFinalization::Detached(value))
643 }
644 }
645 }
646}
647
648#[derive(Clone, Copy, Debug, PartialEq, Eq)]
650pub enum DiedBindingTransition {
651 Committed(CommittedDiedTerminal),
653 Pending(PendingDiedFinalization),
655}
656
657impl DiedBindingTransition {
658 #[must_use]
660 pub const fn observer_progress_projection(&self) -> Option<super::ObserverProgressProjection> {
661 let Self::Committed(terminal) = self else {
662 return None;
663 };
664 Some(super::ObserverProgressProjection::sourced(
665 terminal.conversation_id(),
666 terminal.delivery_seq(),
667 super::checkpoint_codec::ObserverProjectionSource::Terminal(
668 CommittedBindingTerminal::Died(*terminal).storage_description(),
669 ),
670 ))
671 }
672
673 #[must_use]
675 pub const fn binding_state(self) -> BindingState {
676 match self {
677 Self::Committed(_) => BindingState::Detached,
678 Self::Pending(value) => {
679 BindingState::PendingFinalization(PendingFinalization::Died(value))
680 }
681 }
682 }
683}
684
685impl ActiveBinding {
686 const fn finish_detached(
687 self,
688 cause: DetachedCause,
689 disposition: BindingTerminalDisposition,
690 ) -> DetachedBindingTransition {
691 match disposition {
692 BindingTerminalDisposition::Committed(position) => {
693 DetachedBindingTransition::Committed(CommittedDetachedTerminal {
694 identity: BindingTerminalIdentity::from_active(
695 self,
696 position.transaction_order,
697 ),
698 cause,
699 delivery_seq: position.delivery_seq,
700 })
701 }
702 BindingTerminalDisposition::Pending(position) => {
703 DetachedBindingTransition::Pending(PendingDetachedFinalization {
704 identity: BindingTerminalIdentity::from_active(
705 self,
706 position.transaction_order,
707 ),
708 cause,
709 })
710 }
711 }
712 }
713
714 const fn finish_died(
715 self,
716 cause: DiedCause,
717 disposition: BindingTerminalDisposition,
718 ) -> DiedBindingTransition {
719 match disposition {
720 BindingTerminalDisposition::Committed(position) => {
721 DiedBindingTransition::Committed(CommittedDiedTerminal {
722 identity: BindingTerminalIdentity::from_active(
723 self,
724 position.transaction_order,
725 ),
726 cause,
727 delivery_seq: position.delivery_seq,
728 })
729 }
730 BindingTerminalDisposition::Pending(position) => {
731 DiedBindingTransition::Pending(PendingDiedFinalization {
732 identity: BindingTerminalIdentity::from_active(
733 self,
734 position.transaction_order,
735 ),
736 cause,
737 })
738 }
739 }
740 }
741
742 #[must_use]
744 pub const fn clean_deregister(
745 self,
746 disposition: BindingTerminalDisposition,
747 ) -> DetachedBindingTransition {
748 self.finish_detached(DetachedCause::CleanDeregister, disposition)
749 }
750
751 #[must_use]
753 pub const fn commit_clean_deregister(
754 self,
755 position: CommittedBindingTerminalPosition,
756 ) -> CommittedDetachedTerminal {
757 CommittedDetachedTerminal {
758 identity: BindingTerminalIdentity::from_active(self, position.transaction_order),
759 cause: DetachedCause::CleanDeregister,
760 delivery_seq: position.delivery_seq,
761 }
762 }
763
764 #[must_use]
766 pub const fn pending_clean_deregister(
767 self,
768 position: PendingBindingTerminalPosition,
769 ) -> PendingDetachedFinalization {
770 PendingDetachedFinalization {
771 identity: BindingTerminalIdentity::from_active(self, position.transaction_order),
772 cause: DetachedCause::CleanDeregister,
773 }
774 }
775
776 #[must_use]
778 pub const fn clean_disconnect(
779 self,
780 disposition: BindingTerminalDisposition,
781 ) -> DetachedBindingTransition {
782 self.clean_deregister(disposition)
783 }
784
785 #[must_use]
791 pub const fn superseded(
792 self,
793 position: CommittedBindingTerminalPosition,
794 ) -> CommittedDetachedTerminal {
795 CommittedDetachedTerminal {
796 identity: BindingTerminalIdentity::from_active(self, position.transaction_order),
797 cause: DetachedCause::Superseded,
798 delivery_seq: position.delivery_seq,
799 }
800 }
801
802 #[must_use]
804 pub const fn server_shutdown(
805 self,
806 disposition: BindingTerminalDisposition,
807 ) -> DetachedBindingTransition {
808 self.finish_detached(DetachedCause::ServerShutdown, disposition)
809 }
810
811 #[must_use]
813 pub const fn connection_lost(
814 self,
815 disposition: BindingTerminalDisposition,
816 ) -> DiedBindingTransition {
817 self.finish_died(DiedCause::ConnectionLost, disposition)
818 }
819
820 #[must_use]
822 pub const fn process_killed(
823 self,
824 disposition: BindingTerminalDisposition,
825 ) -> DiedBindingTransition {
826 self.finish_died(DiedCause::ProcessKilled, disposition)
827 }
828
829 #[must_use]
831 pub const fn protocol_error(
832 self,
833 disposition: BindingTerminalDisposition,
834 ) -> DiedBindingTransition {
835 self.finish_died(DiedCause::ProtocolError, disposition)
836 }
837
838 #[must_use]
843 pub const fn unclean_server_restart(
844 self,
845 disposition: BindingTerminalDisposition,
846 ) -> DiedBindingTransition {
847 self.finish_died(
848 DiedCause::UncleanServerRestart {
849 prior_server_incarnation: self
850 .binding_epoch
851 .connection_incarnation
852 .server_incarnation,
853 },
854 disposition,
855 )
856 }
857}
858
859#[derive(Clone, Copy, Debug, PartialEq, Eq)]
861pub enum BindingState {
862 Detached,
864 Bound(ActiveBinding),
866 PendingFinalization(PendingFinalization),
868}
869
870pub(super) const fn restore_pending_finalization(
871 binding: ActiveBinding,
872 cause: CloseCause,
873 transaction_order: TransactionOrder,
874) -> Option<PendingFinalization> {
875 let position =
876 BindingTerminalDisposition::Pending(PendingBindingTerminalPosition::new(transaction_order));
877 match cause {
878 CloseCause::CleanDeregister => match binding.clean_deregister(position) {
879 DetachedBindingTransition::Pending(value) => Some(PendingFinalization::Detached(value)),
880 DetachedBindingTransition::Committed(_) => None,
881 },
882 CloseCause::ServerShutdown => match binding.server_shutdown(position) {
883 DetachedBindingTransition::Pending(value) => Some(PendingFinalization::Detached(value)),
884 DetachedBindingTransition::Committed(_) => None,
885 },
886 CloseCause::Superseded => None,
888 CloseCause::ConnectionLost => match binding.connection_lost(position) {
889 DiedBindingTransition::Pending(value) => Some(PendingFinalization::Died(value)),
890 DiedBindingTransition::Committed(_) => None,
891 },
892 CloseCause::ProcessKilled => match binding.process_killed(position) {
893 DiedBindingTransition::Pending(value) => Some(PendingFinalization::Died(value)),
894 DiedBindingTransition::Committed(_) => None,
895 },
896 CloseCause::ProtocolError => match binding.protocol_error(position) {
897 DiedBindingTransition::Pending(value) => Some(PendingFinalization::Died(value)),
898 DiedBindingTransition::Committed(_) => None,
899 },
900 CloseCause::UncleanServerRestart {
901 prior_server_incarnation,
902 } => {
903 if binding
904 .binding_epoch
905 .connection_incarnation
906 .server_incarnation
907 != prior_server_incarnation
908 {
909 return None;
910 }
911 match binding.unclean_server_restart(position) {
912 DiedBindingTransition::Pending(value) => Some(PendingFinalization::Died(value)),
913 DiedBindingTransition::Committed(_) => None,
914 }
915 }
916 }
917}
918
919pub(super) const fn restore_committed_terminal(
920 binding: ActiveBinding,
921 cause: CloseCause,
922 transaction_order: TransactionOrder,
923 delivery_seq: DeliverySeq,
924) -> Option<CommittedBindingTerminal> {
925 let position = BindingTerminalDisposition::Committed(CommittedBindingTerminalPosition::new(
926 transaction_order,
927 delivery_seq,
928 ));
929 match cause {
930 CloseCause::CleanDeregister => match binding.clean_deregister(position) {
931 DetachedBindingTransition::Committed(value) => {
932 Some(CommittedBindingTerminal::Detached(value))
933 }
934 DetachedBindingTransition::Pending(_) => None,
935 },
936 CloseCause::Superseded => Some(CommittedBindingTerminal::Detached(binding.superseded(
937 CommittedBindingTerminalPosition::new(transaction_order, delivery_seq),
938 ))),
939 CloseCause::ServerShutdown => match binding.server_shutdown(position) {
940 DetachedBindingTransition::Committed(value) => {
941 Some(CommittedBindingTerminal::Detached(value))
942 }
943 DetachedBindingTransition::Pending(_) => None,
944 },
945 CloseCause::ConnectionLost => match binding.connection_lost(position) {
946 DiedBindingTransition::Committed(value) => Some(CommittedBindingTerminal::Died(value)),
947 DiedBindingTransition::Pending(_) => None,
948 },
949 CloseCause::ProcessKilled => match binding.process_killed(position) {
950 DiedBindingTransition::Committed(value) => Some(CommittedBindingTerminal::Died(value)),
951 DiedBindingTransition::Pending(_) => None,
952 },
953 CloseCause::ProtocolError => match binding.protocol_error(position) {
954 DiedBindingTransition::Committed(value) => Some(CommittedBindingTerminal::Died(value)),
955 DiedBindingTransition::Pending(_) => None,
956 },
957 CloseCause::UncleanServerRestart {
958 prior_server_incarnation,
959 } => {
960 if binding
961 .binding_epoch
962 .connection_incarnation
963 .server_incarnation
964 != prior_server_incarnation
965 {
966 return None;
967 }
968 match binding.unclean_server_restart(position) {
969 DiedBindingTransition::Committed(value) => {
970 Some(CommittedBindingTerminal::Died(value))
971 }
972 DiedBindingTransition::Pending(_) => None,
973 }
974 }
975 }
976}