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::new(
628 terminal.conversation_id(),
629 terminal.delivery_seq(),
630 ))
631 }
632
633 #[must_use]
635 pub const fn binding_state(self) -> BindingState {
636 match self {
637 Self::Committed(_) => BindingState::Detached,
638 Self::Pending(value) => {
639 BindingState::PendingFinalization(PendingFinalization::Detached(value))
640 }
641 }
642 }
643}
644
645#[derive(Clone, Copy, Debug, PartialEq, Eq)]
647pub enum DiedBindingTransition {
648 Committed(CommittedDiedTerminal),
650 Pending(PendingDiedFinalization),
652}
653
654impl DiedBindingTransition {
655 #[must_use]
657 pub const fn observer_progress_projection(&self) -> Option<super::ObserverProgressProjection> {
658 let Self::Committed(terminal) = self else {
659 return None;
660 };
661 Some(super::ObserverProgressProjection::new(
662 terminal.conversation_id(),
663 terminal.delivery_seq(),
664 ))
665 }
666
667 #[must_use]
669 pub const fn binding_state(self) -> BindingState {
670 match self {
671 Self::Committed(_) => BindingState::Detached,
672 Self::Pending(value) => {
673 BindingState::PendingFinalization(PendingFinalization::Died(value))
674 }
675 }
676 }
677}
678
679impl ActiveBinding {
680 const fn finish_detached(
681 self,
682 cause: DetachedCause,
683 disposition: BindingTerminalDisposition,
684 ) -> DetachedBindingTransition {
685 match disposition {
686 BindingTerminalDisposition::Committed(position) => {
687 DetachedBindingTransition::Committed(CommittedDetachedTerminal {
688 identity: BindingTerminalIdentity::from_active(
689 self,
690 position.transaction_order,
691 ),
692 cause,
693 delivery_seq: position.delivery_seq,
694 })
695 }
696 BindingTerminalDisposition::Pending(position) => {
697 DetachedBindingTransition::Pending(PendingDetachedFinalization {
698 identity: BindingTerminalIdentity::from_active(
699 self,
700 position.transaction_order,
701 ),
702 cause,
703 })
704 }
705 }
706 }
707
708 const fn finish_died(
709 self,
710 cause: DiedCause,
711 disposition: BindingTerminalDisposition,
712 ) -> DiedBindingTransition {
713 match disposition {
714 BindingTerminalDisposition::Committed(position) => {
715 DiedBindingTransition::Committed(CommittedDiedTerminal {
716 identity: BindingTerminalIdentity::from_active(
717 self,
718 position.transaction_order,
719 ),
720 cause,
721 delivery_seq: position.delivery_seq,
722 })
723 }
724 BindingTerminalDisposition::Pending(position) => {
725 DiedBindingTransition::Pending(PendingDiedFinalization {
726 identity: BindingTerminalIdentity::from_active(
727 self,
728 position.transaction_order,
729 ),
730 cause,
731 })
732 }
733 }
734 }
735
736 #[must_use]
738 pub const fn clean_deregister(
739 self,
740 disposition: BindingTerminalDisposition,
741 ) -> DetachedBindingTransition {
742 self.finish_detached(DetachedCause::CleanDeregister, disposition)
743 }
744
745 #[must_use]
747 pub const fn commit_clean_deregister(
748 self,
749 position: CommittedBindingTerminalPosition,
750 ) -> CommittedDetachedTerminal {
751 CommittedDetachedTerminal {
752 identity: BindingTerminalIdentity::from_active(self, position.transaction_order),
753 cause: DetachedCause::CleanDeregister,
754 delivery_seq: position.delivery_seq,
755 }
756 }
757
758 #[must_use]
760 pub const fn pending_clean_deregister(
761 self,
762 position: PendingBindingTerminalPosition,
763 ) -> PendingDetachedFinalization {
764 PendingDetachedFinalization {
765 identity: BindingTerminalIdentity::from_active(self, position.transaction_order),
766 cause: DetachedCause::CleanDeregister,
767 }
768 }
769
770 #[must_use]
772 pub const fn clean_disconnect(
773 self,
774 disposition: BindingTerminalDisposition,
775 ) -> DetachedBindingTransition {
776 self.clean_deregister(disposition)
777 }
778
779 #[must_use]
785 pub const fn superseded(
786 self,
787 position: CommittedBindingTerminalPosition,
788 ) -> CommittedDetachedTerminal {
789 CommittedDetachedTerminal {
790 identity: BindingTerminalIdentity::from_active(self, position.transaction_order),
791 cause: DetachedCause::Superseded,
792 delivery_seq: position.delivery_seq,
793 }
794 }
795
796 #[must_use]
798 pub const fn server_shutdown(
799 self,
800 disposition: BindingTerminalDisposition,
801 ) -> DetachedBindingTransition {
802 self.finish_detached(DetachedCause::ServerShutdown, disposition)
803 }
804
805 #[must_use]
807 pub const fn connection_lost(
808 self,
809 disposition: BindingTerminalDisposition,
810 ) -> DiedBindingTransition {
811 self.finish_died(DiedCause::ConnectionLost, disposition)
812 }
813
814 #[must_use]
816 pub const fn process_killed(
817 self,
818 disposition: BindingTerminalDisposition,
819 ) -> DiedBindingTransition {
820 self.finish_died(DiedCause::ProcessKilled, disposition)
821 }
822
823 #[must_use]
825 pub const fn protocol_error(
826 self,
827 disposition: BindingTerminalDisposition,
828 ) -> DiedBindingTransition {
829 self.finish_died(DiedCause::ProtocolError, disposition)
830 }
831
832 #[must_use]
837 pub const fn unclean_server_restart(
838 self,
839 disposition: BindingTerminalDisposition,
840 ) -> DiedBindingTransition {
841 self.finish_died(
842 DiedCause::UncleanServerRestart {
843 prior_server_incarnation: self
844 .binding_epoch
845 .connection_incarnation
846 .server_incarnation,
847 },
848 disposition,
849 )
850 }
851}
852
853#[derive(Clone, Copy, Debug, PartialEq, Eq)]
855pub enum BindingState {
856 Detached,
858 Bound(ActiveBinding),
860 PendingFinalization(PendingFinalization),
862}
863
864pub(super) const fn restore_pending_finalization(
865 binding: ActiveBinding,
866 cause: CloseCause,
867 transaction_order: TransactionOrder,
868) -> Option<PendingFinalization> {
869 let position =
870 BindingTerminalDisposition::Pending(PendingBindingTerminalPosition::new(transaction_order));
871 match cause {
872 CloseCause::CleanDeregister => match binding.clean_deregister(position) {
873 DetachedBindingTransition::Pending(value) => Some(PendingFinalization::Detached(value)),
874 DetachedBindingTransition::Committed(_) => None,
875 },
876 CloseCause::ServerShutdown => match binding.server_shutdown(position) {
877 DetachedBindingTransition::Pending(value) => Some(PendingFinalization::Detached(value)),
878 DetachedBindingTransition::Committed(_) => None,
879 },
880 CloseCause::Superseded => None,
882 CloseCause::ConnectionLost => match binding.connection_lost(position) {
883 DiedBindingTransition::Pending(value) => Some(PendingFinalization::Died(value)),
884 DiedBindingTransition::Committed(_) => None,
885 },
886 CloseCause::ProcessKilled => match binding.process_killed(position) {
887 DiedBindingTransition::Pending(value) => Some(PendingFinalization::Died(value)),
888 DiedBindingTransition::Committed(_) => None,
889 },
890 CloseCause::ProtocolError => match binding.protocol_error(position) {
891 DiedBindingTransition::Pending(value) => Some(PendingFinalization::Died(value)),
892 DiedBindingTransition::Committed(_) => None,
893 },
894 CloseCause::UncleanServerRestart {
895 prior_server_incarnation,
896 } => {
897 if binding
898 .binding_epoch
899 .connection_incarnation
900 .server_incarnation
901 != prior_server_incarnation
902 {
903 return None;
904 }
905 match binding.unclean_server_restart(position) {
906 DiedBindingTransition::Pending(value) => Some(PendingFinalization::Died(value)),
907 DiedBindingTransition::Committed(_) => None,
908 }
909 }
910 }
911}
912
913pub(super) const fn restore_committed_terminal(
914 binding: ActiveBinding,
915 cause: CloseCause,
916 transaction_order: TransactionOrder,
917 delivery_seq: DeliverySeq,
918) -> Option<CommittedBindingTerminal> {
919 let position = BindingTerminalDisposition::Committed(CommittedBindingTerminalPosition::new(
920 transaction_order,
921 delivery_seq,
922 ));
923 match cause {
924 CloseCause::CleanDeregister => match binding.clean_deregister(position) {
925 DetachedBindingTransition::Committed(value) => {
926 Some(CommittedBindingTerminal::Detached(value))
927 }
928 DetachedBindingTransition::Pending(_) => None,
929 },
930 CloseCause::Superseded => Some(CommittedBindingTerminal::Detached(binding.superseded(
931 CommittedBindingTerminalPosition::new(transaction_order, delivery_seq),
932 ))),
933 CloseCause::ServerShutdown => match binding.server_shutdown(position) {
934 DetachedBindingTransition::Committed(value) => {
935 Some(CommittedBindingTerminal::Detached(value))
936 }
937 DetachedBindingTransition::Pending(_) => None,
938 },
939 CloseCause::ConnectionLost => match binding.connection_lost(position) {
940 DiedBindingTransition::Committed(value) => Some(CommittedBindingTerminal::Died(value)),
941 DiedBindingTransition::Pending(_) => None,
942 },
943 CloseCause::ProcessKilled => match binding.process_killed(position) {
944 DiedBindingTransition::Committed(value) => Some(CommittedBindingTerminal::Died(value)),
945 DiedBindingTransition::Pending(_) => None,
946 },
947 CloseCause::ProtocolError => match binding.protocol_error(position) {
948 DiedBindingTransition::Committed(value) => Some(CommittedBindingTerminal::Died(value)),
949 DiedBindingTransition::Pending(_) => None,
950 },
951 CloseCause::UncleanServerRestart {
952 prior_server_incarnation,
953 } => {
954 if binding
955 .binding_epoch
956 .connection_incarnation
957 .server_incarnation
958 != prior_server_incarnation
959 {
960 return None;
961 }
962 match binding.unclean_server_restart(position) {
963 DiedBindingTransition::Committed(value) => {
964 Some(CommittedBindingTerminal::Died(value))
965 }
966 DiedBindingTransition::Pending(_) => None,
967 }
968 }
969 }
970}