Skip to main content

behavior_actors/atomic/pool/
customer.rs

1//! Customer outcome delivery with exact rejected-submission custody.
2
3use behavior::{
4    ActionItem, Delivery, EndpointAddress, EstablishedDelivery, ExactDeliveryReason,
5    InterpretationProgress, InterpreterRequest, ItemSettlement, LogicalDeliveryReason,
6    NoReturnToEmitter, Protocol, finish_item, prepare_item,
7};
8
9use crate::{ReplyDelivery, ReplyRoute};
10
11/// One customer outcome and every capability required if delivery rejects.
12///
13/// Ordinary accepted and terminal outcomes consume their sole customer route
14/// as the delivery target. A synchronously rejected keyed submission instead
15/// uses a cloned target and retains the original customer route in this action.
16/// A rejecting interpreter therefore returns both capabilities together.
17#[must_use = "customer delivery must be interpreted or retained"]
18pub enum CustomerDelivery<P>
19where
20    P: Protocol,
21    P::Addr: EndpointAddress,
22{
23    /// One outcome targeting a logical customer.
24    Logical {
25        /// Concrete logical delivery.
26        delivery: Delivery<P>,
27    },
28    /// One outcome targeting an exact customer.
29    Established {
30        /// Concrete exact delivery.
31        delivery: EstablishedDelivery<P>,
32    },
33    /// One rejected submission targeting a clone of a logical customer.
34    RejectedLogical {
35        /// Concrete delivery using the cloned target.
36        delivery: Delivery<P>,
37        /// Original unchanged customer route.
38        customer: ReplyRoute<P>,
39    },
40    /// One rejected submission targeting a clone of an exact customer.
41    RejectedEstablished {
42        /// Concrete delivery using the cloned target.
43        delivery: EstablishedDelivery<P>,
44        /// Original unchanged customer route.
45        customer: ReplyRoute<P>,
46    },
47}
48
49impl<P> CustomerDelivery<P>
50where
51    P: Protocol,
52    P::Addr: EndpointAddress,
53{
54    pub(in crate::atomic) fn outcome(route: ReplyRoute<P>, outcome: P::Msg) -> Self {
55        match route {
56            ReplyRoute::Logical(to) => Self::Logical {
57                delivery: Delivery::new(to, outcome),
58            },
59            ReplyRoute::Established(to) => Self::Established {
60                delivery: EstablishedDelivery::new(to, outcome),
61            },
62        }
63    }
64
65    pub(in crate::atomic) fn rejected(route: ReplyRoute<P>, outcome: P::Msg) -> Self {
66        match route.clone() {
67            ReplyRoute::Logical(to) => Self::RejectedLogical {
68                delivery: Delivery::new(to, outcome),
69                customer: route,
70            },
71            ReplyRoute::Established(to) => Self::RejectedEstablished {
72                delivery: EstablishedDelivery::new(to, outcome),
73                customer: route,
74            },
75        }
76    }
77}
78
79impl<P> InterpreterRequest for CustomerDelivery<P>
80where
81    P: Protocol,
82    P::Addr: EndpointAddress,
83{
84    type ReturnToEmitter = NoReturnToEmitter;
85    type LogicalProtocols = behavior::BirthProtocol<P, behavior::NoBirthProtocols>;
86}
87
88impl<P> ActionItem for CustomerDelivery<P>
89where
90    P: Protocol,
91    P::Addr: EndpointAddress + Send,
92    P::Msg: Send,
93    <P::Addr as EndpointAddress>::Established<P>: Send,
94{
95    type Custody = (Option<Self>, Option<Self::Reply>);
96    type Input<'a>
97        = &'a mut Option<Self>
98    where
99        Self: 'a;
100    type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
101
102    fn prepare_interpretation(
103        progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
104    ) {
105        prepare_item::<Self>(progress);
106    }
107
108    fn interpretation_input<'a>(
109        custody: &'a mut Self::Custody,
110    ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
111    where
112        Self: 'a,
113    {
114        match custody {
115            (input @ Some(_), received @ None) => Some((input, received)),
116            _ => None,
117        }
118    }
119
120    fn finish_interpretation(
121        progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
122    ) {
123        finish_item::<Self>(progress);
124    }
125
126    type Accepted = ();
127    type Rejection = ReplyDelivery<LogicalDeliveryReason, ExactDeliveryReason>;
128    type Prerequisite = behavior::Never;
129}